//******************************************************** 
// 
// Assignment 10 - Linked Lists, Typedef, and Macros 
// 
// Name: <Kyle Merrihew> 
// 
// Class: C Programming, <Spring 2025> 
// 
// Date: <April 14,2025> 
// 
// Description: Program which determines overtime and  
// gross pay for a set of employees with outputs sent  
// to standard output (the screen). 
// 
// This assignment also adds the employee name, their tax state, 
// and calculates the state tax, federal tax, and net pay.   It 
// also calculates totals, averages, minimum, and maximum values. 
// 
// Array and Structure references have all been replaced with 
// pointer references to speed up the processing of this code. 
// A linked list has been created and deployed to dynamically 
// allocate and process employees as needed. 
// 
// It will also take advantage of the C Preprocessor features, 
// in particular with using macros, and will replace all  
// struct type references in the code with a typedef alias 
// reference. 
// 
// Call by Reference design (using pointers) 
// 
//******************************************************** 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
 
// Constants 
#define MA_TAX_RATE 0.06 
#define VT_TAX_RATE 0.04 
#define NH_TAX_RATE 0.00 
#define CA_TAX_RATE 0.08 
#define DEFAULT_STATE_TAX_RATE 0.05 
#define FED_TAX_RATE 0.10 
 
#define FIRST_NAME_SIZE 20 
#define LAST_NAME_SIZE 30 
 
// Macros 
#define CALC_OT_HOURS(hours) ((hours) > 40 ? (hours) - 40 : 0) 
#define CALC_NORMAL_PAY(rate, hours, overtime) ((hours) - (overtime)) * (rate) 
#define CALC_OT_PAY(rate, overtime) ((overtime) * (rate) * 1.5) 
#define CALC_STATE_TAX(grossPay, rate) ((grossPay) * (rate)) 
#define CALC_FED_TAX(grossPay) ((grossPay) * FED_TAX_RATE) 
#define CALC_NET_PAY(grossPay, stateTax, fedTax) ((grossPay) - (stateTax) - (fedTax)) 
#define CALC_MIN(a, b) ((a) < (b) ? (a) : (b)) 
#define CALC_MAX(a, b) ((a) > (b) ? (a) : (b)) 
 
// Struct Definitions 
typedef  struct  { 
    char  firstName[ FIRST_NAME_SIZE] ; 
    char  lastName[ LAST_NAME_SIZE] ; 
}  Name; 
 
typedef  struct  employee { 
    Name empName; 
    char  taxState[ 3 ] ;       // State code (2 characters) 
    long  clockNumber; 
    float  wageRate; 
    float  hours; 
    float  overtimeHrs; 
    float  grossPay; 
    float  stateTax; 
    float  fedTax; 
    float  netPay; 
    struct  employee * next; 
}  EMPLOYEE; 
 
typedef  struct  { 
    float  total_wageRate; 
    float  total_hours; 
    float  total_overtimeHrs; 
    float  total_grossPay; 
    float  total_stateTax; 
    float  total_fedTax; 
    float  total_netPay; 
}  TOTALS; 
 
typedef  struct  min_max { 
    float  min_wageRate; 
    float  max_wageRate; 
    float  min_hours; 
    float  max_hours; 
    float  min_overtimeHrs; 
    float  max_overtimeHrs; 
    float  min_grossPay; 
    float  max_grossPay; 
    float  min_stateTax; 
    float  max_stateTax; 
    float  min_fedTax; 
    float  max_fedTax; 
    float  min_netPay; 
    float  max_netPay; 
}  MIN_MAX; 
 
// Function Prototypes 
void  initializeEmployee( EMPLOYEE * emp) ; 
void  printEmployee( EMPLOYEE * emp) ; 
void  calculateEmployeePay( EMPLOYEE * emp) ; 
void  calculateTotals( EMPLOYEE * emp,  TOTALS * totals) ; 
void  printTotals( TOTALS * totals) ; 
void  calculateMinMax( EMPLOYEE * emp,  MIN_MAX * minMax) ; 
void  printMinMax( MIN_MAX * minMax) ; 
float  getTaxRate( char  * state) ; 
 
// Main function 
int  main( )  { 
    EMPLOYEE * head =  NULL; 
    EMPLOYEE * current =  NULL; 
    TOTALS totals =  { 0 } ; 
    MIN_MAX minMax =  { 0 } ; 
 
    char  choice; 
 
    do  { 
        EMPLOYEE 
* newEmployee 
=  ( EMPLOYEE 
* ) malloc ( sizeof ( EMPLOYEE
) ) ;         if  ( ! newEmployee)  { 
            printf ( "Memory allocation failed.\n " ) ;              return  1 ; 
        } 
 
        initializeEmployee( newEmployee) ; 
 
        calculateEmployeePay( newEmployee) ; 
        calculateTotals( newEmployee,  & totals) ; 
        calculateMinMax( newEmployee,  & minMax) ; 
 
        // Add employee to linked list 
        if  ( head ==  NULL)  { 
            head =  newEmployee; 
        }  else  { 
            current-> next =  newEmployee; 
        } 
        current =  newEmployee; 
 
        printf ( "Do you want to enter another employee? (Y/N): " ) ;          getchar ( ) ;   // To consume the newline character after input   
    }  while  ( choice ==  'Y' ) ; 
 
    // Print all employees 
    current =  head; 
    while  ( current !=  NULL)  { 
        printEmployee( current) ; 
        current =  current-> next; 
    } 
 
    // Print totals and min/max 
    printTotals( & totals) ; 
    printMinMax( & minMax) ; 
 
    return  0 ; 
} 
 
// Function Definitions 
 
void  initializeEmployee( EMPLOYEE * emp)  { 
    printf ( "Enter employee first name: " ) ;      fgets ( emp
-> empName.
firstName ,  FIRST_NAME_SIZE
,  stdin
) ;      emp
-> empName.
firstName [ strcspn ( emp
-> empName.
firstName ,  "\n " ) ]  =  '\0 ' ;   // Remove newline  
    printf ( "Enter employee last name: " ) ;      fgets ( emp
-> empName.
lastName ,  LAST_NAME_SIZE
,  stdin
) ;      emp
-> empName.
lastName [ strcspn ( emp
-> empName.
lastName ,  "\n " ) ]  =  '\0 ' ;   // Remove newline  
    printf ( "Enter employee clock number: " ) ;      scanf ( "%ld" ,  & emp
-> clockNumber
) ;   
    printf ( "Enter employee wage rate: " ) ;      scanf ( "%f" ,  & emp
-> wageRate
) ;   
    printf ( "Enter employee hours worked: " ) ;      scanf ( "%f" ,  & emp
-> hours
) ;   
    emp-> overtimeHrs =  CALC_OT_HOURS( emp-> hours) ; 
} 
 
void  printEmployee( EMPLOYEE * emp)  { 
    printf ( "\n Employee Name: %s %s\n " ,  emp
-> empName.
firstName ,  emp
-> empName.
lastName ) ;      printf ( "Clock Number: %ld\n " ,  emp
-> clockNumber
) ;      printf ( "Wage Rate: %.2f\n " ,  emp
-> wageRate
) ;      printf ( "Hours Worked: %.2f\n " ,  emp
-> hours
) ;      printf ( "Overtime Hours: %.2f\n " ,  emp
-> overtimeHrs
) ;      printf ( "Gross Pay: %.2f\n " ,  emp
-> grossPay
) ;      printf ( "State Tax: %.2f\n " ,  emp
-> stateTax
) ;      printf ( "Federal Tax: %.2f\n " ,  emp
-> fedTax
) ;      printf ( "Net Pay: %.2f\n \n " ,  emp
-> netPay
) ;  } 
 
void  calculateEmployeePay( EMPLOYEE * emp)  { 
    float  overtime =  emp-> overtimeHrs; 
    emp-> grossPay =  CALC_NORMAL_PAY( emp-> wageRate,  emp-> hours,  overtime)  +  CALC_OT_PAY( emp-> wageRate,  overtime) ; 
    emp-> stateTax =  CALC_STATE_TAX( emp-> grossPay,  getTaxRate( emp-> taxState) ) ; 
    emp-> fedTax =  CALC_FED_TAX( emp-> grossPay) ; 
    emp-> netPay =  CALC_NET_PAY( emp-> grossPay,  emp-> stateTax,  emp-> fedTax) ; 
} 
 
void  calculateTotals( EMPLOYEE * emp,  TOTALS * totals)  { 
    totals-> total_wageRate +=  emp-> wageRate; 
    totals-> total_hours +=  emp-> hours; 
    totals-> total_overtimeHrs +=  emp-> overtimeHrs; 
    totals-> total_grossPay +=  emp-> grossPay; 
    totals-> total_stateTax +=  emp-> stateTax; 
    totals-> total_fedTax +=  emp-> fedTax; 
    totals-> total_netPay +=  emp-> netPay; 
} 
 
void  printTotals( TOTALS * totals)  { 
    printf ( "\n Total Wage Rate: %.2f\n " ,  totals
-> total_wageRate
) ;      printf ( "Total Hours Worked: %.2f\n " ,  totals
-> total_hours
) ;      printf ( "Total Overtime Hours: %.2f\n " ,  totals
-> total_overtimeHrs
) ;      printf ( "Total Gross Pay: %.2f\n " ,  totals
-> total_grossPay
) ;      printf ( "Total State Tax: %.2f\n " ,  totals
-> total_stateTax
) ;      printf ( "Total Federal Tax: %.2f\n " ,  totals
-> total_fedTax
) ;      printf ( "Total Net Pay: %.2f\n \n " ,  totals
-> total_netPay
) ;  } 
 
void  calculateMinMax( EMPLOYEE * emp,  MIN_MAX * minMax)  { 
    minMax-> min_wageRate =  ( minMax-> min_wageRate ==  0 )  ?  emp-> wageRate :  CALC_MIN( minMax-> min_wageRate,  emp-> wageRate) ; 
    minMax-> max_wageRate =  ( minMax-> max_wageRate ==  0 )  ?  emp-> wageRate :  CALC_MAX( minMax-> max_wageRate,  emp-> wageRate) ; 
    minMax-> min_hours =  ( minMax-> min_hours ==  0 )  ?  emp-> hours :  CALC_MIN( minMax-> min_hours,  emp-> hours) ; 
    minMax-> max_hours =  ( minMax-> max_hours ==  0 )  ?  emp-> hours :  CALC_MAX( minMax-> max_hours,  emp-> hours) ; 
    minMax-> min_overtimeHrs =  ( minMax-> min_overtimeHrs ==  0 )  ?  emp-> overtimeHrs :  CALC_MIN( minMax-> min_overtimeHrs,  emp-> overtimeHrs) ; 
    minMax-> max_overtimeHrs =  ( minMax-> max_overtimeHrs ==  0 )  ?  emp-> overtimeHrs :  CALC_MAX( minMax-> max_overtimeHrs,  emp-> overtimeHrs) ; 
    minMax-> min_grossPay =  ( minMax-> min_grossPay ==  0 )  ?  emp-> grossPay :  CALC_MIN( minMax-> min_grossPay,  emp-> grossPay) ; 
    minMax-> max_grossPay =  ( minMax-> max_grossPay ==  0 )  ?  emp-> grossPay :  CALC_MAX( minMax-> max_grossPay,  emp-> grossPay) ; 
    minMax-> min_stateTax =  ( minMax-> min_stateTax ==  0 )  ?  emp-> stateTax :  CALC_MIN( minMax-> min_stateTax,  emp-> stateTax) ; 
    minMax-> max_stateTax =  ( minMax-> max_stateTax ==  0 )  ?  emp-> stateTax :  CALC_MAX( minMax-> max_stateTax,  emp-> stateTax) ; 
    minMax-> min_fedTax =  ( minMax-> min_fedTax ==  0 )  ?  emp-> fedTax :  CALC_MIN( minMax-> min_fedTax,  emp-> fedTax) ; 
    minMax-> max_fedTax =  ( minMax-> max_fedTax ==  0 )  ?  emp-> fedTax :  CALC_MAX( minMax-> max_fedTax,  emp-> fedTax) ; 
    minMax-> min_netPay =  ( minMax-> min_netPay ==  0 )  ?  emp-> netPay :  CALC_MIN( minMax-> min_netPay,  emp-> netPay) ; 
    minMax-> max_netPay =  ( minMax-> max_netPay ==  0 )  ?  emp-> netPay :  CALC_MAX( minMax-> max_netPay,  emp-> netPay) ; 
} 
 
void  printMinMax( MIN_MAX * minMax)  { 
    printf ( "\n Min Wage Rate: %.2f | Max Wage Rate: %.2f\n " ,  minMax
-> min_wageRate
,  minMax
-> max_wageRate
) ;      printf ( "Min Hours: %.2f | Max Hours: %.2f\n " ,  minMax
-> min_hours
,  minMax
-> max_hours
) ;      printf ( "Min Overtime Hours: %.2f | Max Overtime Hours: %.2f\n " ,  minMax
-> min_overtimeHrs
,  minMax
-> max_overtimeHrs
) ;      printf ( "Min Gross Pay: %.2f | Max Gross Pay: %.2f\n " ,  minMax
-> min_grossPay
,  minMax
-> max_grossPay
) ;      printf ( "Min State Tax: %.2f | Max State Tax: %.2f\n " ,  minMax
-> min_stateTax
,  minMax
-> max_stateTax
) ;      printf ( "Min Federal Tax: %.2f | Max Federal Tax: %.2f\n " ,  minMax
-> min_fedTax
,  minMax
-> max_fedTax
) ;      printf ( "Min Net Pay: %.2f | Max Net Pay: %.2f\n " ,  minMax
-> min_netPay
,  minMax
-> max_netPay
) ;  } 
 
float  getTaxRate( char  * state)  { 
    if  ( strcmp ( state
,  "MA" )  ==  0 )  {          return  MA_TAX_RATE; 
    }  else  if  ( strcmp ( state
,  "VT" )  ==  0 )  {          return  VT_TAX_RATE; 
    }  else  if  ( strcmp ( state
,  "NH" )  ==  0 )  {          return  NH_TAX_RATE; 
    }  else  if  ( strcmp ( state
,  "CA" )  ==  0 )  {          return  CA_TAX_RATE; 
    }  else  { 
        return  DEFAULT_STATE_TAX_RATE; 
    } 
} 
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDEwIC0gTGlua2VkIExpc3RzLCBUeXBlZGVmLCBhbmQgTWFjcm9zCi8vCi8vIE5hbWU6IDxLeWxlIE1lcnJpaGV3PgovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgPFNwcmluZyAyMDI1PgovLwovLyBEYXRlOiA8QXByaWwgMTQsMjAyNT4KLy8KLy8gRGVzY3JpcHRpb246IFByb2dyYW0gd2hpY2ggZGV0ZXJtaW5lcyBvdmVydGltZSBhbmQgCi8vIGdyb3NzIHBheSBmb3IgYSBzZXQgb2YgZW1wbG95ZWVzIHdpdGggb3V0cHV0cyBzZW50IAovLyB0byBzdGFuZGFyZCBvdXRwdXQgKHRoZSBzY3JlZW4pLgovLwovLyBUaGlzIGFzc2lnbm1lbnQgYWxzbyBhZGRzIHRoZSBlbXBsb3llZSBuYW1lLCB0aGVpciB0YXggc3RhdGUsCi8vIGFuZCBjYWxjdWxhdGVzIHRoZSBzdGF0ZSB0YXgsIGZlZGVyYWwgdGF4LCBhbmQgbmV0IHBheS4gICBJdAovLyBhbHNvIGNhbGN1bGF0ZXMgdG90YWxzLCBhdmVyYWdlcywgbWluaW11bSwgYW5kIG1heGltdW0gdmFsdWVzLgovLwovLyBBcnJheSBhbmQgU3RydWN0dXJlIHJlZmVyZW5jZXMgaGF2ZSBhbGwgYmVlbiByZXBsYWNlZCB3aXRoCi8vIHBvaW50ZXIgcmVmZXJlbmNlcyB0byBzcGVlZCB1cCB0aGUgcHJvY2Vzc2luZyBvZiB0aGlzIGNvZGUuCi8vIEEgbGlua2VkIGxpc3QgaGFzIGJlZW4gY3JlYXRlZCBhbmQgZGVwbG95ZWQgdG8gZHluYW1pY2FsbHkKLy8gYWxsb2NhdGUgYW5kIHByb2Nlc3MgZW1wbG95ZWVzIGFzIG5lZWRlZC4KLy8KLy8gSXQgd2lsbCBhbHNvIHRha2UgYWR2YW50YWdlIG9mIHRoZSBDIFByZXByb2Nlc3NvciBmZWF0dXJlcywKLy8gaW4gcGFydGljdWxhciB3aXRoIHVzaW5nIG1hY3JvcywgYW5kIHdpbGwgcmVwbGFjZSBhbGwgCi8vIHN0cnVjdCB0eXBlIHJlZmVyZW5jZXMgaW4gdGhlIGNvZGUgd2l0aCBhIHR5cGVkZWYgYWxpYXMKLy8gcmVmZXJlbmNlLgovLwovLyBDYWxsIGJ5IFJlZmVyZW5jZSBkZXNpZ24gKHVzaW5nIHBvaW50ZXJzKQovLwovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgoKLy8gQ29uc3RhbnRzCiNkZWZpbmUgTUFfVEFYX1JBVEUgMC4wNgojZGVmaW5lIFZUX1RBWF9SQVRFIDAuMDQKI2RlZmluZSBOSF9UQVhfUkFURSAwLjAwCiNkZWZpbmUgQ0FfVEFYX1JBVEUgMC4wOAojZGVmaW5lIERFRkFVTFRfU1RBVEVfVEFYX1JBVEUgMC4wNQojZGVmaW5lIEZFRF9UQVhfUkFURSAwLjEwCgojZGVmaW5lIEZJUlNUX05BTUVfU0laRSAyMAojZGVmaW5lIExBU1RfTkFNRV9TSVpFIDMwCgovLyBNYWNyb3MKI2RlZmluZSBDQUxDX09UX0hPVVJTKGhvdXJzKSAoKGhvdXJzKSA+IDQwID8gKGhvdXJzKSAtIDQwIDogMCkKI2RlZmluZSBDQUxDX05PUk1BTF9QQVkocmF0ZSwgaG91cnMsIG92ZXJ0aW1lKSAoKGhvdXJzKSAtIChvdmVydGltZSkpICogKHJhdGUpCiNkZWZpbmUgQ0FMQ19PVF9QQVkocmF0ZSwgb3ZlcnRpbWUpICgob3ZlcnRpbWUpICogKHJhdGUpICogMS41KQojZGVmaW5lIENBTENfU1RBVEVfVEFYKGdyb3NzUGF5LCByYXRlKSAoKGdyb3NzUGF5KSAqIChyYXRlKSkKI2RlZmluZSBDQUxDX0ZFRF9UQVgoZ3Jvc3NQYXkpICgoZ3Jvc3NQYXkpICogRkVEX1RBWF9SQVRFKQojZGVmaW5lIENBTENfTkVUX1BBWShncm9zc1BheSwgc3RhdGVUYXgsIGZlZFRheCkgKChncm9zc1BheSkgLSAoc3RhdGVUYXgpIC0gKGZlZFRheCkpCiNkZWZpbmUgQ0FMQ19NSU4oYSwgYikgKChhKSA8IChiKSA/IChhKSA6IChiKSkKI2RlZmluZSBDQUxDX01BWChhLCBiKSAoKGEpID4gKGIpID8gKGEpIDogKGIpKQoKLy8gU3RydWN0IERlZmluaXRpb25zCnR5cGVkZWYgc3RydWN0IHsKICAgIGNoYXIgZmlyc3ROYW1lW0ZJUlNUX05BTUVfU0laRV07CiAgICBjaGFyIGxhc3ROYW1lW0xBU1RfTkFNRV9TSVpFXTsKfSBOYW1lOwoKdHlwZWRlZiBzdHJ1Y3QgZW1wbG95ZWUgewogICAgTmFtZSBlbXBOYW1lOwogICAgY2hhciB0YXhTdGF0ZVszXTsgICAgICAvLyBTdGF0ZSBjb2RlICgyIGNoYXJhY3RlcnMpCiAgICBsb25nIGNsb2NrTnVtYmVyOwogICAgZmxvYXQgd2FnZVJhdGU7CiAgICBmbG9hdCBob3VyczsKICAgIGZsb2F0IG92ZXJ0aW1lSHJzOwogICAgZmxvYXQgZ3Jvc3NQYXk7CiAgICBmbG9hdCBzdGF0ZVRheDsKICAgIGZsb2F0IGZlZFRheDsKICAgIGZsb2F0IG5ldFBheTsKICAgIHN0cnVjdCBlbXBsb3llZSAqbmV4dDsKfSBFTVBMT1lFRTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIGZsb2F0IHRvdGFsX3dhZ2VSYXRlOwogICAgZmxvYXQgdG90YWxfaG91cnM7CiAgICBmbG9hdCB0b3RhbF9vdmVydGltZUhyczsKICAgIGZsb2F0IHRvdGFsX2dyb3NzUGF5OwogICAgZmxvYXQgdG90YWxfc3RhdGVUYXg7CiAgICBmbG9hdCB0b3RhbF9mZWRUYXg7CiAgICBmbG9hdCB0b3RhbF9uZXRQYXk7Cn0gVE9UQUxTOwoKdHlwZWRlZiBzdHJ1Y3QgbWluX21heCB7CiAgICBmbG9hdCBtaW5fd2FnZVJhdGU7CiAgICBmbG9hdCBtYXhfd2FnZVJhdGU7CiAgICBmbG9hdCBtaW5faG91cnM7CiAgICBmbG9hdCBtYXhfaG91cnM7CiAgICBmbG9hdCBtaW5fb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtYXhfb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtaW5fZ3Jvc3NQYXk7CiAgICBmbG9hdCBtYXhfZ3Jvc3NQYXk7CiAgICBmbG9hdCBtaW5fc3RhdGVUYXg7CiAgICBmbG9hdCBtYXhfc3RhdGVUYXg7CiAgICBmbG9hdCBtaW5fZmVkVGF4OwogICAgZmxvYXQgbWF4X2ZlZFRheDsKICAgIGZsb2F0IG1pbl9uZXRQYXk7CiAgICBmbG9hdCBtYXhfbmV0UGF5Owp9IE1JTl9NQVg7CgovLyBGdW5jdGlvbiBQcm90b3R5cGVzCnZvaWQgaW5pdGlhbGl6ZUVtcGxveWVlKEVNUExPWUVFICplbXApOwp2b2lkIHByaW50RW1wbG95ZWUoRU1QTE9ZRUUgKmVtcCk7CnZvaWQgY2FsY3VsYXRlRW1wbG95ZWVQYXkoRU1QTE9ZRUUgKmVtcCk7CnZvaWQgY2FsY3VsYXRlVG90YWxzKEVNUExPWUVFICplbXAsIFRPVEFMUyAqdG90YWxzKTsKdm9pZCBwcmludFRvdGFscyhUT1RBTFMgKnRvdGFscyk7CnZvaWQgY2FsY3VsYXRlTWluTWF4KEVNUExPWUVFICplbXAsIE1JTl9NQVggKm1pbk1heCk7CnZvaWQgcHJpbnRNaW5NYXgoTUlOX01BWCAqbWluTWF4KTsKZmxvYXQgZ2V0VGF4UmF0ZShjaGFyICpzdGF0ZSk7CgovLyBNYWluIGZ1bmN0aW9uCmludCBtYWluKCkgewogICAgRU1QTE9ZRUUgKmhlYWQgPSBOVUxMOwogICAgRU1QTE9ZRUUgKmN1cnJlbnQgPSBOVUxMOwogICAgVE9UQUxTIHRvdGFscyA9IHswfTsKICAgIE1JTl9NQVggbWluTWF4ID0gezB9OwoKICAgIGNoYXIgY2hvaWNlOwoKICAgIGRvIHsKICAgICAgICBFTVBMT1lFRSAqbmV3RW1wbG95ZWUgPSAoRU1QTE9ZRUUgKiltYWxsb2Moc2l6ZW9mKEVNUExPWUVFKSk7CiAgICAgICAgaWYgKCFuZXdFbXBsb3llZSkgewogICAgICAgICAgICBwcmludGYoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZC5cbiIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGluaXRpYWxpemVFbXBsb3llZShuZXdFbXBsb3llZSk7CgogICAgICAgIGNhbGN1bGF0ZUVtcGxveWVlUGF5KG5ld0VtcGxveWVlKTsKICAgICAgICBjYWxjdWxhdGVUb3RhbHMobmV3RW1wbG95ZWUsICZ0b3RhbHMpOwogICAgICAgIGNhbGN1bGF0ZU1pbk1heChuZXdFbXBsb3llZSwgJm1pbk1heCk7CgogICAgICAgIC8vIEFkZCBlbXBsb3llZSB0byBsaW5rZWQgbGlzdAogICAgICAgIGlmIChoZWFkID09IE5VTEwpIHsKICAgICAgICAgICAgaGVhZCA9IG5ld0VtcGxveWVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSBuZXdFbXBsb3llZTsKICAgICAgICB9CiAgICAgICAgY3VycmVudCA9IG5ld0VtcGxveWVlOwoKICAgICAgICBwcmludGYoIkRvIHlvdSB3YW50IHRvIGVudGVyIGFub3RoZXIgZW1wbG95ZWU/IChZL04pOiAiKTsKICAgICAgICBjaG9pY2UgPSB0b3VwcGVyKGdldGNoYXIoKSk7CiAgICAgICAgZ2V0Y2hhcigpOyAgLy8gVG8gY29uc3VtZSB0aGUgbmV3bGluZSBjaGFyYWN0ZXIgYWZ0ZXIgaW5wdXQKCiAgICB9IHdoaWxlIChjaG9pY2UgPT0gJ1knKTsKCiAgICAvLyBQcmludCBhbGwgZW1wbG95ZWVzCiAgICBjdXJyZW50ID0gaGVhZDsKICAgIHdoaWxlIChjdXJyZW50ICE9IE5VTEwpIHsKICAgICAgICBwcmludEVtcGxveWVlKGN1cnJlbnQpOwogICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LT5uZXh0OwogICAgfQoKICAgIC8vIFByaW50IHRvdGFscyBhbmQgbWluL21heAogICAgcHJpbnRUb3RhbHMoJnRvdGFscyk7CiAgICBwcmludE1pbk1heCgmbWluTWF4KTsKCiAgICByZXR1cm4gMDsKfQoKLy8gRnVuY3Rpb24gRGVmaW5pdGlvbnMKCnZvaWQgaW5pdGlhbGl6ZUVtcGxveWVlKEVNUExPWUVFICplbXApIHsKICAgIHByaW50ZigiRW50ZXIgZW1wbG95ZWUgZmlyc3QgbmFtZTogIik7CiAgICBmZ2V0cyhlbXAtPmVtcE5hbWUuZmlyc3ROYW1lLCBGSVJTVF9OQU1FX1NJWkUsIHN0ZGluKTsKICAgIGVtcC0+ZW1wTmFtZS5maXJzdE5hbWVbc3RyY3NwbihlbXAtPmVtcE5hbWUuZmlyc3ROYW1lLCAiXG4iKV0gPSAnXDAnOyAgLy8gUmVtb3ZlIG5ld2xpbmUKCiAgICBwcmludGYoIkVudGVyIGVtcGxveWVlIGxhc3QgbmFtZTogIik7CiAgICBmZ2V0cyhlbXAtPmVtcE5hbWUubGFzdE5hbWUsIExBU1RfTkFNRV9TSVpFLCBzdGRpbik7CiAgICBlbXAtPmVtcE5hbWUubGFzdE5hbWVbc3RyY3NwbihlbXAtPmVtcE5hbWUubGFzdE5hbWUsICJcbiIpXSA9ICdcMCc7ICAvLyBSZW1vdmUgbmV3bGluZQoKICAgIHByaW50ZigiRW50ZXIgZW1wbG95ZWUgY2xvY2sgbnVtYmVyOiAiKTsKICAgIHNjYW5mKCIlbGQiLCAmZW1wLT5jbG9ja051bWJlcik7CgogICAgcHJpbnRmKCJFbnRlciBlbXBsb3llZSB3YWdlIHJhdGU6ICIpOwogICAgc2NhbmYoIiVmIiwgJmVtcC0+d2FnZVJhdGUpOwoKICAgIHByaW50ZigiRW50ZXIgZW1wbG95ZWUgaG91cnMgd29ya2VkOiAiKTsKICAgIHNjYW5mKCIlZiIsICZlbXAtPmhvdXJzKTsKCiAgICBlbXAtPm92ZXJ0aW1lSHJzID0gQ0FMQ19PVF9IT1VSUyhlbXAtPmhvdXJzKTsKfQoKdm9pZCBwcmludEVtcGxveWVlKEVNUExPWUVFICplbXApIHsKICAgIHByaW50ZigiXG5FbXBsb3llZSBOYW1lOiAlcyAlc1xuIiwgZW1wLT5lbXBOYW1lLmZpcnN0TmFtZSwgZW1wLT5lbXBOYW1lLmxhc3ROYW1lKTsKICAgIHByaW50ZigiQ2xvY2sgTnVtYmVyOiAlbGRcbiIsIGVtcC0+Y2xvY2tOdW1iZXIpOwogICAgcHJpbnRmKCJXYWdlIFJhdGU6ICUuMmZcbiIsIGVtcC0+d2FnZVJhdGUpOwogICAgcHJpbnRmKCJIb3VycyBXb3JrZWQ6ICUuMmZcbiIsIGVtcC0+aG91cnMpOwogICAgcHJpbnRmKCJPdmVydGltZSBIb3VyczogJS4yZlxuIiwgZW1wLT5vdmVydGltZUhycyk7CiAgICBwcmludGYoIkdyb3NzIFBheTogJS4yZlxuIiwgZW1wLT5ncm9zc1BheSk7CiAgICBwcmludGYoIlN0YXRlIFRheDogJS4yZlxuIiwgZW1wLT5zdGF0ZVRheCk7CiAgICBwcmludGYoIkZlZGVyYWwgVGF4OiAlLjJmXG4iLCBlbXAtPmZlZFRheCk7CiAgICBwcmludGYoIk5ldCBQYXk6ICUuMmZcblxuIiwgZW1wLT5uZXRQYXkpOwp9Cgp2b2lkIGNhbGN1bGF0ZUVtcGxveWVlUGF5KEVNUExPWUVFICplbXApIHsKICAgIGZsb2F0IG92ZXJ0aW1lID0gZW1wLT5vdmVydGltZUhyczsKICAgIGVtcC0+Z3Jvc3NQYXkgPSBDQUxDX05PUk1BTF9QQVkoZW1wLT53YWdlUmF0ZSwgZW1wLT5ob3Vycywgb3ZlcnRpbWUpICsgQ0FMQ19PVF9QQVkoZW1wLT53YWdlUmF0ZSwgb3ZlcnRpbWUpOwogICAgZW1wLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGVtcC0+Z3Jvc3NQYXksIGdldFRheFJhdGUoZW1wLT50YXhTdGF0ZSkpOwogICAgZW1wLT5mZWRUYXggPSBDQUxDX0ZFRF9UQVgoZW1wLT5ncm9zc1BheSk7CiAgICBlbXAtPm5ldFBheSA9IENBTENfTkVUX1BBWShlbXAtPmdyb3NzUGF5LCBlbXAtPnN0YXRlVGF4LCBlbXAtPmZlZFRheCk7Cn0KCnZvaWQgY2FsY3VsYXRlVG90YWxzKEVNUExPWUVFICplbXAsIFRPVEFMUyAqdG90YWxzKSB7CiAgICB0b3RhbHMtPnRvdGFsX3dhZ2VSYXRlICs9IGVtcC0+d2FnZVJhdGU7CiAgICB0b3RhbHMtPnRvdGFsX2hvdXJzICs9IGVtcC0+aG91cnM7CiAgICB0b3RhbHMtPnRvdGFsX292ZXJ0aW1lSHJzICs9IGVtcC0+b3ZlcnRpbWVIcnM7CiAgICB0b3RhbHMtPnRvdGFsX2dyb3NzUGF5ICs9IGVtcC0+Z3Jvc3NQYXk7CiAgICB0b3RhbHMtPnRvdGFsX3N0YXRlVGF4ICs9IGVtcC0+c3RhdGVUYXg7CiAgICB0b3RhbHMtPnRvdGFsX2ZlZFRheCArPSBlbXAtPmZlZFRheDsKICAgIHRvdGFscy0+dG90YWxfbmV0UGF5ICs9IGVtcC0+bmV0UGF5Owp9Cgp2b2lkIHByaW50VG90YWxzKFRPVEFMUyAqdG90YWxzKSB7CiAgICBwcmludGYoIlxuVG90YWwgV2FnZSBSYXRlOiAlLjJmXG4iLCB0b3RhbHMtPnRvdGFsX3dhZ2VSYXRlKTsKICAgIHByaW50ZigiVG90YWwgSG91cnMgV29ya2VkOiAlLjJmXG4iLCB0b3RhbHMtPnRvdGFsX2hvdXJzKTsKICAgIHByaW50ZigiVG90YWwgT3ZlcnRpbWUgSG91cnM6ICUuMmZcbiIsIHRvdGFscy0+dG90YWxfb3ZlcnRpbWVIcnMpOwogICAgcHJpbnRmKCJUb3RhbCBHcm9zcyBQYXk6ICUuMmZcbiIsIHRvdGFscy0+dG90YWxfZ3Jvc3NQYXkpOwogICAgcHJpbnRmKCJUb3RhbCBTdGF0ZSBUYXg6ICUuMmZcbiIsIHRvdGFscy0+dG90YWxfc3RhdGVUYXgpOwogICAgcHJpbnRmKCJUb3RhbCBGZWRlcmFsIFRheDogJS4yZlxuIiwgdG90YWxzLT50b3RhbF9mZWRUYXgpOwogICAgcHJpbnRmKCJUb3RhbCBOZXQgUGF5OiAlLjJmXG5cbiIsIHRvdGFscy0+dG90YWxfbmV0UGF5KTsKfQoKdm9pZCBjYWxjdWxhdGVNaW5NYXgoRU1QTE9ZRUUgKmVtcCwgTUlOX01BWCAqbWluTWF4KSB7CiAgICBtaW5NYXgtPm1pbl93YWdlUmF0ZSA9IChtaW5NYXgtPm1pbl93YWdlUmF0ZSA9PSAwKSA/IGVtcC0+d2FnZVJhdGUgOiBDQUxDX01JTihtaW5NYXgtPm1pbl93YWdlUmF0ZSwgZW1wLT53YWdlUmF0ZSk7CiAgICBtaW5NYXgtPm1heF93YWdlUmF0ZSA9IChtaW5NYXgtPm1heF93YWdlUmF0ZSA9PSAwKSA/IGVtcC0+d2FnZVJhdGUgOiBDQUxDX01BWChtaW5NYXgtPm1heF93YWdlUmF0ZSwgZW1wLT53YWdlUmF0ZSk7CiAgICBtaW5NYXgtPm1pbl9ob3VycyA9IChtaW5NYXgtPm1pbl9ob3VycyA9PSAwKSA/IGVtcC0+aG91cnMgOiBDQUxDX01JTihtaW5NYXgtPm1pbl9ob3VycywgZW1wLT5ob3Vycyk7CiAgICBtaW5NYXgtPm1heF9ob3VycyA9IChtaW5NYXgtPm1heF9ob3VycyA9PSAwKSA/IGVtcC0+aG91cnMgOiBDQUxDX01BWChtaW5NYXgtPm1heF9ob3VycywgZW1wLT5ob3Vycyk7CiAgICBtaW5NYXgtPm1pbl9vdmVydGltZUhycyA9IChtaW5NYXgtPm1pbl9vdmVydGltZUhycyA9PSAwKSA/IGVtcC0+b3ZlcnRpbWVIcnMgOiBDQUxDX01JTihtaW5NYXgtPm1pbl9vdmVydGltZUhycywgZW1wLT5vdmVydGltZUhycyk7CiAgICBtaW5NYXgtPm1heF9vdmVydGltZUhycyA9IChtaW5NYXgtPm1heF9vdmVydGltZUhycyA9PSAwKSA/IGVtcC0+b3ZlcnRpbWVIcnMgOiBDQUxDX01BWChtaW5NYXgtPm1heF9vdmVydGltZUhycywgZW1wLT5vdmVydGltZUhycyk7CiAgICBtaW5NYXgtPm1pbl9ncm9zc1BheSA9IChtaW5NYXgtPm1pbl9ncm9zc1BheSA9PSAwKSA/IGVtcC0+Z3Jvc3NQYXkgOiBDQUxDX01JTihtaW5NYXgtPm1pbl9ncm9zc1BheSwgZW1wLT5ncm9zc1BheSk7CiAgICBtaW5NYXgtPm1heF9ncm9zc1BheSA9IChtaW5NYXgtPm1heF9ncm9zc1BheSA9PSAwKSA/IGVtcC0+Z3Jvc3NQYXkgOiBDQUxDX01BWChtaW5NYXgtPm1heF9ncm9zc1BheSwgZW1wLT5ncm9zc1BheSk7CiAgICBtaW5NYXgtPm1pbl9zdGF0ZVRheCA9IChtaW5NYXgtPm1pbl9zdGF0ZVRheCA9PSAwKSA/IGVtcC0+c3RhdGVUYXggOiBDQUxDX01JTihtaW5NYXgtPm1pbl9zdGF0ZVRheCwgZW1wLT5zdGF0ZVRheCk7CiAgICBtaW5NYXgtPm1heF9zdGF0ZVRheCA9IChtaW5NYXgtPm1heF9zdGF0ZVRheCA9PSAwKSA/IGVtcC0+c3RhdGVUYXggOiBDQUxDX01BWChtaW5NYXgtPm1heF9zdGF0ZVRheCwgZW1wLT5zdGF0ZVRheCk7CiAgICBtaW5NYXgtPm1pbl9mZWRUYXggPSAobWluTWF4LT5taW5fZmVkVGF4ID09IDApID8gZW1wLT5mZWRUYXggOiBDQUxDX01JTihtaW5NYXgtPm1pbl9mZWRUYXgsIGVtcC0+ZmVkVGF4KTsKICAgIG1pbk1heC0+bWF4X2ZlZFRheCA9IChtaW5NYXgtPm1heF9mZWRUYXggPT0gMCkgPyBlbXAtPmZlZFRheCA6IENBTENfTUFYKG1pbk1heC0+bWF4X2ZlZFRheCwgZW1wLT5mZWRUYXgpOwogICAgbWluTWF4LT5taW5fbmV0UGF5ID0gKG1pbk1heC0+bWluX25ldFBheSA9PSAwKSA/IGVtcC0+bmV0UGF5IDogQ0FMQ19NSU4obWluTWF4LT5taW5fbmV0UGF5LCBlbXAtPm5ldFBheSk7CiAgICBtaW5NYXgtPm1heF9uZXRQYXkgPSAobWluTWF4LT5tYXhfbmV0UGF5ID09IDApID8gZW1wLT5uZXRQYXkgOiBDQUxDX01BWChtaW5NYXgtPm1heF9uZXRQYXksIGVtcC0+bmV0UGF5KTsKfQoKdm9pZCBwcmludE1pbk1heChNSU5fTUFYICptaW5NYXgpIHsKICAgIHByaW50ZigiXG5NaW4gV2FnZSBSYXRlOiAlLjJmIHwgTWF4IFdhZ2UgUmF0ZTogJS4yZlxuIiwgbWluTWF4LT5taW5fd2FnZVJhdGUsIG1pbk1heC0+bWF4X3dhZ2VSYXRlKTsKICAgIHByaW50ZigiTWluIEhvdXJzOiAlLjJmIHwgTWF4IEhvdXJzOiAlLjJmXG4iLCBtaW5NYXgtPm1pbl9ob3VycywgbWluTWF4LT5tYXhfaG91cnMpOwogICAgcHJpbnRmKCJNaW4gT3ZlcnRpbWUgSG91cnM6ICUuMmYgfCBNYXggT3ZlcnRpbWUgSG91cnM6ICUuMmZcbiIsIG1pbk1heC0+bWluX292ZXJ0aW1lSHJzLCBtaW5NYXgtPm1heF9vdmVydGltZUhycyk7CiAgICBwcmludGYoIk1pbiBHcm9zcyBQYXk6ICUuMmYgfCBNYXggR3Jvc3MgUGF5OiAlLjJmXG4iLCBtaW5NYXgtPm1pbl9ncm9zc1BheSwgbWluTWF4LT5tYXhfZ3Jvc3NQYXkpOwogICAgcHJpbnRmKCJNaW4gU3RhdGUgVGF4OiAlLjJmIHwgTWF4IFN0YXRlIFRheDogJS4yZlxuIiwgbWluTWF4LT5taW5fc3RhdGVUYXgsIG1pbk1heC0+bWF4X3N0YXRlVGF4KTsKICAgIHByaW50ZigiTWluIEZlZGVyYWwgVGF4OiAlLjJmIHwgTWF4IEZlZGVyYWwgVGF4OiAlLjJmXG4iLCBtaW5NYXgtPm1pbl9mZWRUYXgsIG1pbk1heC0+bWF4X2ZlZFRheCk7CiAgICBwcmludGYoIk1pbiBOZXQgUGF5OiAlLjJmIHwgTWF4IE5ldCBQYXk6ICUuMmZcbiIsIG1pbk1heC0+bWluX25ldFBheSwgbWluTWF4LT5tYXhfbmV0UGF5KTsKfQoKZmxvYXQgZ2V0VGF4UmF0ZShjaGFyICpzdGF0ZSkgewogICAgaWYgKHN0cmNtcChzdGF0ZSwgIk1BIikgPT0gMCkgewogICAgICAgIHJldHVybiBNQV9UQVhfUkFURTsKICAgIH0gZWxzZSBpZiAoc3RyY21wKHN0YXRlLCAiVlQiKSA9PSAwKSB7CiAgICAgICAgcmV0dXJuIFZUX1RBWF9SQVRFOwogICAgfSBlbHNlIGlmIChzdHJjbXAoc3RhdGUsICJOSCIpID09IDApIHsKICAgICAgICByZXR1cm4gTkhfVEFYX1JBVEU7CiAgICB9IGVsc2UgaWYgKHN0cmNtcChzdGF0ZSwgIkNBIikgPT0gMCkgewogICAgICAgIHJldHVybiBDQV9UQVhfUkFURTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfU1RBVEVfVEFYX1JBVEU7CiAgICB9Cn0=