#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// Constants
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define MA_TAX_RATE 0.05
#define NH_TAX_RATE 0.0
#define VT_TAX_RATE 0.06
#define CA_TAX_RATE 0.07
#define DEFAULT_STATE_TAX_RATE 0.08
#define TAX_STATE_SIZE 3
#define FED_TAX_RATE 0.25
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10
// Macros
#define CALC_OT_HOURS(h) ((h) > STD_HOURS ? (h) - STD_HOURS : 0)
#define CALC_STATE_TAX(p,r) ((p) * (r))
#define CALC_FED_TAX(p) ((p) * FED_TAX_RATE)
#define CALC_NET_PAY(p,st,ft) ((p) - ((st) + (ft)))
#define CALC_NORMAL_PAY(w,h,oh) ((w) * ((h) - (oh)))
#define CALC_OT_PAY(w,oh) ((oh) * (OT_RATE * (w)))
#define CALC_MIN(v,c) ((v) < (c) ? (v) : (c))
#define CALC_MAX(v,c) ((v) > (c) ? (v) : (c))
// Structure declarations
typedef struct {
char firstName[ FIRST_NAME_SIZE] ;
char lastName[ LAST_NAME_SIZE] ;
} Name;
typedef struct employee {
Name empName;
char taxState[ TAX_STATE_SIZE] ;
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 {
float min_wageRate, min_hours, min_overtimeHrs, min_grossPay;
float min_stateTax, min_fedTax, min_netPay;
float max_wageRate, max_hours, max_overtimeHrs, max_grossPay;
float max_stateTax, max_fedTax, max_netPay;
} MinMax;
// Function prototypes
Employee * getEmployees( ) ;
int countEmployees( Employee * head) ;
void calculateOvertime( Employee * head) ;
void calculateGrossPay( Employee * head) ;
void calculateStateTax( Employee * head) ;
void calculateFederalTax( Employee * head) ;
void calculateNetPay( Employee * head) ;
void calculateTotals( Employee * head, Totals * totals) ;
void calculateMinMax( Employee * head, MinMax * mm) ;
void printHeader( ) ;
void printEmployee( Employee * head) ;
void printStatistics( Totals * totals, MinMax * mm, int count) ;
void freeEmployees( Employee * head) ;
int main( ) {
Employee * head = NULL;
Totals totals = { 0 } ;
MinMax minmax = { 0 } ;
int employeeCount = 0 ;
head = getEmployees( ) ;
employeeCount = countEmployees( head) ;
if ( employeeCount <= 0 ) {
printf ( "\n No employees to process\n " ) ; return 0 ;
}
calculateOvertime( head) ;
calculateGrossPay( head) ;
calculateStateTax( head) ;
calculateFederalTax( head) ;
calculateNetPay( head) ;
calculateTotals( head, & totals) ;
calculateMinMax( head, & minmax) ;
printHeader( ) ;
printEmployee( head) ;
printStatistics( & totals, & minmax, employeeCount) ;
freeEmployees( head) ;
printf ( "\n Program completed successfully\n " ) ; return 0 ;
}
//Input Functions with Error Checking for ideone compatibility
Employee * getEmployees( ) {
Employee * head = NULL, * current = NULL, * prev = NULL;
char choice[ 4 ] ;
int first = 1 ;
while ( 1 ) {
Employee
* newEmp
= ( Employee
* ) malloc ( sizeof ( Employee
) ) ; if ( ! newEmp) {
printf ( "Memory allocation failed!\n " ) ; }
// Input validation for all fields
printf ( "\n Enter first name: " ) ; if ( scanf ( "%9s" , newEmp
-> empName.
firstName ) != 1 ) { }
if ( scanf ( "%9s" , newEmp
-> empName.
lastName ) != 1 ) { }
printf ( "Enter tax state (2 chars): " ) ; if ( scanf ( "%2s" , newEmp
-> taxState
) != 1 ) { }
printf ( "Enter clock number: " ) ; if ( scanf ( "%ld" , & newEmp
-> clockNumber
) != 1 ) { }
printf ( "Enter hourly wage: " ) ; if ( scanf ( "%f" , & newEmp
-> wageRate
) != 1 ) { }
printf ( "Enter hours worked: " ) ; if ( scanf ( "%f" , & newEmp
-> hours
) != 1 ) { }
// Initialize pointers
newEmp-> next = NULL;
if ( first) {
head = current = newEmp;
first = 0 ;
} else {
prev-> next = newEmp;
current = newEmp;
}
prev = current;
// Add another employee?
printf ( "\n Add another employee? (yes/no): " ) ; if ( scanf ( "%3s" , choice
) != 1 ) { freeEmployees( head) ;
}
if ( toupper ( choice
[ 0 ] ) != 'Y' ) break ; }
return head;
}
void calculateOvertime( Employee * head) {
while ( head) {
head-> overtimeHrs = CALC_OT_HOURS( head-> hours) ;
head = head-> next;
}
}
void calculateGrossPay( Employee * head) {
while ( head) {
float normal = CALC_NORMAL_PAY( head-> wageRate, head-> hours, head-> overtimeHrs) ;
float overtime = CALC_OT_PAY( head-> wageRate, head-> overtimeHrs) ;
head-> grossPay = normal + overtime;
head = head-> next;
}
}
void calculateStateTax( Employee * head) {
while ( head) {
// Convert state code to uppercase
for ( int i = 0 ; i < 2 ; i++ ) {
head
-> taxState
[ i
] = toupper ( head
-> taxState
[ i
] ) ; }
float rate;
if ( strcmp ( head
-> taxState
, "MA" ) == 0 ) rate
= MA_TAX_RATE
; else if ( strcmp ( head
-> taxState
, "VT" ) == 0 ) rate
= VT_TAX_RATE
; else if ( strcmp ( head
-> taxState
, "NH" ) == 0 ) rate
= NH_TAX_RATE
; else if ( strcmp ( head
-> taxState
, "CA" ) == 0 ) rate
= CA_TAX_RATE
; else rate = DEFAULT_STATE_TAX_RATE;
head-> stateTax = CALC_STATE_TAX( head-> grossPay, rate) ;
head = head-> next;
}
}
void calculateFederalTax( Employee * head) {
while ( head) {
head-> fedTax = CALC_FED_TAX( head-> grossPay) ;
head = head-> next;
}
}
void calculateNetPay( Employee * head) {
while ( head) {
head-> netPay = CALC_NET_PAY( head-> grossPay, head-> stateTax, head-> fedTax) ;
head = head-> next;
}
}
//Calculations
void calculateTotals( Employee * head, Totals * t) {
while ( head) {
t-> total_wageRate += head-> wageRate;
t-> total_hours += head-> hours;
t-> total_overtimeHrs += head-> overtimeHrs;
t-> total_grossPay += head-> grossPay;
t-> total_stateTax += head-> stateTax;
t-> total_fedTax += head-> fedTax;
t-> total_netPay += head-> netPay;
head = head-> next;
}
}
void calculateMinMax( Employee * head, MinMax * mm) {
if ( ! head) return ;
// Initialize with first employee
mm-> min_wageRate = mm-> max_wageRate = head-> wageRate;
mm-> min_hours = mm-> max_hours = head-> hours;
mm-> min_overtimeHrs = mm-> max_overtimeHrs = head-> overtimeHrs;
mm-> min_grossPay = mm-> max_grossPay = head-> grossPay;
mm-> min_stateTax = mm-> max_stateTax = head-> stateTax;
mm-> min_fedTax = mm-> max_fedTax = head-> fedTax;
mm-> min_netPay = mm-> max_netPay = head-> netPay;
// Process remaining employees
while ( ( head = head-> next) ) {
mm-> min_wageRate = CALC_MIN( head-> wageRate, mm-> min_wageRate) ;
mm-> max_wageRate = CALC_MAX( head-> wageRate, mm-> max_wageRate) ;
mm-> min_hours = CALC_MIN( head-> hours, mm-> min_hours) ;
mm-> max_hours = CALC_MAX( head-> hours, mm-> max_hours) ;
mm-> min_overtimeHrs = CALC_MIN( head-> overtimeHrs, mm-> min_overtimeHrs) ;
mm-> max_overtimeHrs = CALC_MAX( head-> overtimeHrs, mm-> max_overtimeHrs) ;
mm-> min_grossPay = CALC_MIN( head-> grossPay, mm-> min_grossPay) ;
mm-> max_grossPay = CALC_MAX( head-> grossPay, mm-> max_grossPay) ;
mm-> min_stateTax = CALC_MIN( head-> stateTax, mm-> min_stateTax) ;
mm-> max_stateTax = CALC_MAX( head-> stateTax, mm-> max_stateTax) ;
mm-> min_fedTax = CALC_MIN( head-> fedTax, mm-> min_fedTax) ;
mm-> max_fedTax = CALC_MAX( head-> fedTax, mm-> max_fedTax) ;
mm-> min_netPay = CALC_MIN( head-> netPay, mm-> min_netPay) ;
mm-> max_netPay = CALC_MAX( head-> netPay, mm-> max_netPay) ;
}
}
// Output Functions
void printHeader( ) {
printf ( "\n \n *** Pay Calculator ***\n " ) ; printf ( "--------------------------------------------------------------\n " ) ; printf ( "%-20s %-6s %-10s %-6s %-5s %-8s %-8s %-8s\n " , "Name" , "State" , "Clock#" , "Wage" , "Hours" , "Gross" , "State Tax" ,
"Fed Tax" , "Net Pay" ) ;
printf ( "--------------------------------------------------------------\n " ) ; }
void printEmployee( Employee * head) {
while ( head) {
char fullName[ FIRST_NAME_SIZE + LAST_NAME_SIZE + 2 ] ;
snprintf ( fullName
, sizeof ( fullName
) , "%s %s" , head-> empName.firstName , head-> empName.lastName ) ;
printf ( "%-20s %-6s %-10ld %-6.2f %-5.1f %-8.2f %-8.2f %-8.2f %-8.2f\n " , fullName,
head-> taxState,
head-> clockNumber,
head-> wageRate,
head-> hours,
head-> grossPay,
head-> stateTax,
head-> fedTax,
head-> netPay) ;
head = head-> next;
}
}
void printStatistics( Totals * t, MinMax * mm, int count) {
printf ( "\n --- Payroll Statistics ---\n " ) ; printf ( " Wages: $%.2f Hours: %.1f OT: %.1f\n " , t-> total_wageRate, t-> total_hours, t-> total_overtimeHrs) ;
printf ( " Gross: $%.2f State Tax: $%.2f Federal Tax: $%.2f Net: $%.2f\n " , t-> total_grossPay, t-> total_stateTax, t-> total_fedTax, t-> total_netPay) ;
printf ( "\n Averages (%d employees):\n " , count
) ; printf ( " Wage: $%.2f/hr Hours: %.1f OT: %.1f\n " , t-> total_wageRate/ count, t-> total_hours/ count, t-> total_overtimeHrs/ count) ;
printf ( " Gross: $%.2f Net: $%.2f\n " , t-> total_grossPay/ count, t-> total_netPay/ count) ;
printf ( " Wage: $%.2f Hours: %.1f Gross: $%.2f Net: $%.2f\n " , mm-> min_wageRate, mm-> min_hours, mm-> min_grossPay, mm-> min_netPay) ;
printf ( " Wage: $%.2f Hours: %.1f Gross: $%.2f Net: $%.2f\n " , mm-> max_wageRate, mm-> max_hours, mm-> max_grossPay, mm-> max_netPay) ;
}
/********************************************************
* Utility Functions
********************************************************/
int countEmployees( Employee * head) {
int count = 0 ;
while ( head) {
count++;
head = head-> next;
}
return count;
}
void freeEmployees( Employee * head) {
while ( head) {
Employee * temp = head;
head = head-> next;
}
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCi8vIENvbnN0YW50cwojZGVmaW5lIFNURF9IT1VSUyA0MC4wCiNkZWZpbmUgT1RfUkFURSAxLjUKI2RlZmluZSBNQV9UQVhfUkFURSAwLjA1CiNkZWZpbmUgTkhfVEFYX1JBVEUgMC4wCiNkZWZpbmUgVlRfVEFYX1JBVEUgMC4wNgojZGVmaW5lIENBX1RBWF9SQVRFIDAuMDcKI2RlZmluZSBERUZBVUxUX1NUQVRFX1RBWF9SQVRFIDAuMDgKI2RlZmluZSBUQVhfU1RBVEVfU0laRSAzCiNkZWZpbmUgRkVEX1RBWF9SQVRFIDAuMjUKI2RlZmluZSBGSVJTVF9OQU1FX1NJWkUgMTAKI2RlZmluZSBMQVNUX05BTUVfU0laRSAxMAoKLy8gTWFjcm9zCiNkZWZpbmUgQ0FMQ19PVF9IT1VSUyhoKSAoKGgpID4gU1REX0hPVVJTID8gKGgpIC0gU1REX0hPVVJTIDogMCkKI2RlZmluZSBDQUxDX1NUQVRFX1RBWChwLHIpICgocCkgKiAocikpCiNkZWZpbmUgQ0FMQ19GRURfVEFYKHApICgocCkgKiBGRURfVEFYX1JBVEUpCiNkZWZpbmUgQ0FMQ19ORVRfUEFZKHAsc3QsZnQpICgocCkgLSAoKHN0KSArIChmdCkpKQojZGVmaW5lIENBTENfTk9STUFMX1BBWSh3LGgsb2gpICgodykgKiAoKGgpIC0gKG9oKSkpCiNkZWZpbmUgQ0FMQ19PVF9QQVkodyxvaCkgKChvaCkgKiAoT1RfUkFURSAqICh3KSkpCiNkZWZpbmUgQ0FMQ19NSU4odixjKSAoKHYpIDwgKGMpID8gKHYpIDogKGMpKQojZGVmaW5lIENBTENfTUFYKHYsYykgKCh2KSA+IChjKSA/ICh2KSA6IChjKSkKCi8vIFN0cnVjdHVyZSBkZWNsYXJhdGlvbnMKdHlwZWRlZiBzdHJ1Y3QgewogICAgY2hhciBmaXJzdE5hbWVbRklSU1RfTkFNRV9TSVpFXTsKICAgIGNoYXIgbGFzdE5hbWVbTEFTVF9OQU1FX1NJWkVdOwp9IE5hbWU7Cgp0eXBlZGVmIHN0cnVjdCBlbXBsb3llZSB7CiAgICBOYW1lIGVtcE5hbWU7CiAgICBjaGFyIHRheFN0YXRlW1RBWF9TVEFURV9TSVpFXTsKICAgIGxvbmcgY2xvY2tOdW1iZXI7CiAgICBmbG9hdCB3YWdlUmF0ZTsKICAgIGZsb2F0IGhvdXJzOwogICAgZmxvYXQgb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBncm9zc1BheTsKICAgIGZsb2F0IHN0YXRlVGF4OwogICAgZmxvYXQgZmVkVGF4OwogICAgZmxvYXQgbmV0UGF5OwogICAgc3RydWN0IGVtcGxveWVlICpuZXh0Owp9IEVtcGxveWVlOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgZmxvYXQgdG90YWxfd2FnZVJhdGU7CiAgICBmbG9hdCB0b3RhbF9ob3VyczsKICAgIGZsb2F0IHRvdGFsX292ZXJ0aW1lSHJzOwogICAgZmxvYXQgdG90YWxfZ3Jvc3NQYXk7CiAgICBmbG9hdCB0b3RhbF9zdGF0ZVRheDsKICAgIGZsb2F0IHRvdGFsX2ZlZFRheDsKICAgIGZsb2F0IHRvdGFsX25ldFBheTsKfSBUb3RhbHM7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBmbG9hdCBtaW5fd2FnZVJhdGUsIG1pbl9ob3VycywgbWluX292ZXJ0aW1lSHJzLCBtaW5fZ3Jvc3NQYXk7CiAgICBmbG9hdCBtaW5fc3RhdGVUYXgsIG1pbl9mZWRUYXgsIG1pbl9uZXRQYXk7CiAgICBmbG9hdCBtYXhfd2FnZVJhdGUsIG1heF9ob3VycywgbWF4X292ZXJ0aW1lSHJzLCBtYXhfZ3Jvc3NQYXk7CiAgICBmbG9hdCBtYXhfc3RhdGVUYXgsIG1heF9mZWRUYXgsIG1heF9uZXRQYXk7Cn0gTWluTWF4OwoKLy8gRnVuY3Rpb24gcHJvdG90eXBlcwpFbXBsb3llZSAqZ2V0RW1wbG95ZWVzKCk7CmludCBjb3VudEVtcGxveWVlcyhFbXBsb3llZSAqaGVhZCk7CnZvaWQgY2FsY3VsYXRlT3ZlcnRpbWUoRW1wbG95ZWUgKmhlYWQpOwp2b2lkIGNhbGN1bGF0ZUdyb3NzUGF5KEVtcGxveWVlICpoZWFkKTsKdm9pZCBjYWxjdWxhdGVTdGF0ZVRheChFbXBsb3llZSAqaGVhZCk7CnZvaWQgY2FsY3VsYXRlRmVkZXJhbFRheChFbXBsb3llZSAqaGVhZCk7CnZvaWQgY2FsY3VsYXRlTmV0UGF5KEVtcGxveWVlICpoZWFkKTsKdm9pZCBjYWxjdWxhdGVUb3RhbHMoRW1wbG95ZWUgKmhlYWQsIFRvdGFscyAqdG90YWxzKTsKdm9pZCBjYWxjdWxhdGVNaW5NYXgoRW1wbG95ZWUgKmhlYWQsIE1pbk1heCAqbW0pOwp2b2lkIHByaW50SGVhZGVyKCk7CnZvaWQgcHJpbnRFbXBsb3llZShFbXBsb3llZSAqaGVhZCk7CnZvaWQgcHJpbnRTdGF0aXN0aWNzKFRvdGFscyAqdG90YWxzLCBNaW5NYXggKm1tLCBpbnQgY291bnQpOwp2b2lkIGZyZWVFbXBsb3llZXMoRW1wbG95ZWUgKmhlYWQpOwoKaW50IG1haW4oKSB7CiAgICBFbXBsb3llZSAqaGVhZCA9IE5VTEw7CiAgICBUb3RhbHMgdG90YWxzID0gezB9OwogICAgTWluTWF4IG1pbm1heCA9IHswfTsKICAgIGludCBlbXBsb3llZUNvdW50ID0gMDsKCiAgICBoZWFkID0gZ2V0RW1wbG95ZWVzKCk7CiAgICBlbXBsb3llZUNvdW50ID0gY291bnRFbXBsb3llZXMoaGVhZCk7CgogICAgaWYgKGVtcGxveWVlQ291bnQgPD0gMCkgewogICAgICAgIHByaW50ZigiXG5ObyBlbXBsb3llZXMgdG8gcHJvY2Vzc1xuIik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgY2FsY3VsYXRlT3ZlcnRpbWUoaGVhZCk7CiAgICBjYWxjdWxhdGVHcm9zc1BheShoZWFkKTsKICAgIGNhbGN1bGF0ZVN0YXRlVGF4KGhlYWQpOwogICAgY2FsY3VsYXRlRmVkZXJhbFRheChoZWFkKTsKICAgIGNhbGN1bGF0ZU5ldFBheShoZWFkKTsKICAgIGNhbGN1bGF0ZVRvdGFscyhoZWFkLCAmdG90YWxzKTsKICAgIGNhbGN1bGF0ZU1pbk1heChoZWFkLCAmbWlubWF4KTsKCiAgICBwcmludEhlYWRlcigpOwogICAgcHJpbnRFbXBsb3llZShoZWFkKTsKICAgIHByaW50U3RhdGlzdGljcygmdG90YWxzLCAmbWlubWF4LCBlbXBsb3llZUNvdW50KTsKCiAgICBmcmVlRW1wbG95ZWVzKGhlYWQpOwogICAgcHJpbnRmKCJcblByb2dyYW0gY29tcGxldGVkIHN1Y2Nlc3NmdWxseVxuIik7CiAgICByZXR1cm4gMDsKfQoKCi8vSW5wdXQgRnVuY3Rpb25zIHdpdGggRXJyb3IgQ2hlY2tpbmcgZm9yIGlkZW9uZSBjb21wYXRpYmlsaXR5IAoKRW1wbG95ZWUgKmdldEVtcGxveWVlcygpIHsKICAgIEVtcGxveWVlICpoZWFkID0gTlVMTCwgKmN1cnJlbnQgPSBOVUxMLCAqcHJldiA9IE5VTEw7CiAgICBjaGFyIGNob2ljZVs0XTsKICAgIGludCBmaXJzdCA9IDE7CgogICAgd2hpbGUoMSkgewogICAgICAgIEVtcGxveWVlICpuZXdFbXAgPSAoRW1wbG95ZWUgKiltYWxsb2Moc2l6ZW9mKEVtcGxveWVlKSk7CiAgICAgICAgaWYoIW5ld0VtcCkgewogICAgICAgICAgICBwcmludGYoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCFcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgLy8gSW5wdXQgdmFsaWRhdGlvbiBmb3IgYWxsIGZpZWxkcwogICAgICAgIHByaW50ZigiXG5FbnRlciBmaXJzdCBuYW1lOiAiKTsKICAgICAgICBpZihzY2FuZigiJTlzIiwgbmV3RW1wLT5lbXBOYW1lLmZpcnN0TmFtZSkgIT0gMSkgewogICAgICAgICAgICBwcmludGYoIkludmFsaWQgaW5wdXQhXG4iKTsKICAgICAgICAgICAgZnJlZShuZXdFbXApOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgcHJpbnRmKCJFbnRlciBsYXN0IG5hbWU6ICIpOwogICAgICAgIGlmKHNjYW5mKCIlOXMiLCBuZXdFbXAtPmVtcE5hbWUubGFzdE5hbWUpICE9IDEpIHsKICAgICAgICAgICAgcHJpbnRmKCJJbnZhbGlkIGlucHV0IVxuIik7CiAgICAgICAgICAgIGZyZWUobmV3RW1wKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIHByaW50ZigiRW50ZXIgdGF4IHN0YXRlICgyIGNoYXJzKTogIik7CiAgICAgICAgaWYoc2NhbmYoIiUycyIsIG5ld0VtcC0+dGF4U3RhdGUpICE9IDEpIHsKICAgICAgICAgICAgcHJpbnRmKCJJbnZhbGlkIGlucHV0IVxuIik7CiAgICAgICAgICAgIGZyZWUobmV3RW1wKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIHByaW50ZigiRW50ZXIgY2xvY2sgbnVtYmVyOiAiKTsKICAgICAgICBpZihzY2FuZigiJWxkIiwgJm5ld0VtcC0+Y2xvY2tOdW1iZXIpICE9IDEpIHsKICAgICAgICAgICAgcHJpbnRmKCJJbnZhbGlkIGlucHV0IVxuIik7CiAgICAgICAgICAgIGZyZWUobmV3RW1wKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIHByaW50ZigiRW50ZXIgaG91cmx5IHdhZ2U6ICIpOwogICAgICAgIGlmKHNjYW5mKCIlZiIsICZuZXdFbXAtPndhZ2VSYXRlKSAhPSAxKSB7CiAgICAgICAgICAgIHByaW50ZigiSW52YWxpZCBpbnB1dCFcbiIpOwogICAgICAgICAgICBmcmVlKG5ld0VtcCk7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICBwcmludGYoIkVudGVyIGhvdXJzIHdvcmtlZDogIik7CiAgICAgICAgaWYoc2NhbmYoIiVmIiwgJm5ld0VtcC0+aG91cnMpICE9IDEpIHsKICAgICAgICAgICAgcHJpbnRmKCJJbnZhbGlkIGlucHV0IVxuIik7CiAgICAgICAgICAgIGZyZWUobmV3RW1wKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIC8vIEluaXRpYWxpemUgcG9pbnRlcnMKICAgICAgICBuZXdFbXAtPm5leHQgPSBOVUxMOwogICAgICAgIGlmKGZpcnN0KSB7CiAgICAgICAgICAgIGhlYWQgPSBjdXJyZW50ID0gbmV3RW1wOwogICAgICAgICAgICBmaXJzdCA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJldi0+bmV4dCA9IG5ld0VtcDsKICAgICAgICAgICAgY3VycmVudCA9IG5ld0VtcDsKICAgICAgICB9CiAgICAgICAgcHJldiA9IGN1cnJlbnQ7CgogICAgICAgIC8vIEFkZCBhbm90aGVyIGVtcGxveWVlPwogICAgICAgIHByaW50ZigiXG5BZGQgYW5vdGhlciBlbXBsb3llZT8gKHllcy9ubyk6ICIpOwogICAgICAgIGlmKHNjYW5mKCIlM3MiLCBjaG9pY2UpICE9IDEpIHsKICAgICAgICAgICAgcHJpbnRmKCJJbnZhbGlkIGlucHV0IVxuIik7CiAgICAgICAgICAgIGZyZWVFbXBsb3llZXMoaGVhZCk7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQogICAgICAgIGlmKHRvdXBwZXIoY2hvaWNlWzBdKSAhPSAnWScpIGJyZWFrOwogICAgfQogICAgcmV0dXJuIGhlYWQ7Cn0KCnZvaWQgY2FsY3VsYXRlT3ZlcnRpbWUoRW1wbG95ZWUgKmhlYWQpIHsKICAgIHdoaWxlKGhlYWQpIHsKICAgICAgICBoZWFkLT5vdmVydGltZUhycyA9IENBTENfT1RfSE9VUlMoaGVhZC0+aG91cnMpOwogICAgICAgIGhlYWQgPSBoZWFkLT5uZXh0OwogICAgfQp9Cgp2b2lkIGNhbGN1bGF0ZUdyb3NzUGF5KEVtcGxveWVlICpoZWFkKSB7CiAgICB3aGlsZShoZWFkKSB7CiAgICAgICAgZmxvYXQgbm9ybWFsID0gQ0FMQ19OT1JNQUxfUEFZKGhlYWQtPndhZ2VSYXRlLCBoZWFkLT5ob3VycywgaGVhZC0+b3ZlcnRpbWVIcnMpOwogICAgICAgIGZsb2F0IG92ZXJ0aW1lID0gQ0FMQ19PVF9QQVkoaGVhZC0+d2FnZVJhdGUsIGhlYWQtPm92ZXJ0aW1lSHJzKTsKICAgICAgICBoZWFkLT5ncm9zc1BheSA9IG5vcm1hbCArIG92ZXJ0aW1lOwogICAgICAgIGhlYWQgPSBoZWFkLT5uZXh0OwogICAgfQp9Cgp2b2lkIGNhbGN1bGF0ZVN0YXRlVGF4KEVtcGxveWVlICpoZWFkKSB7CiAgICB3aGlsZShoZWFkKSB7CiAgICAgICAgLy8gQ29udmVydCBzdGF0ZSBjb2RlIHRvIHVwcGVyY2FzZQogICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICAgICAgICAgaGVhZC0+dGF4U3RhdGVbaV0gPSB0b3VwcGVyKGhlYWQtPnRheFN0YXRlW2ldKTsKICAgICAgICB9CgogICAgICAgIGZsb2F0IHJhdGU7CiAgICAgICAgaWYoc3RyY21wKGhlYWQtPnRheFN0YXRlLCAiTUEiKSA9PSAwKSByYXRlID0gTUFfVEFYX1JBVEU7CiAgICAgICAgZWxzZSBpZihzdHJjbXAoaGVhZC0+dGF4U3RhdGUsICJWVCIpID09IDApIHJhdGUgPSBWVF9UQVhfUkFURTsKICAgICAgICBlbHNlIGlmKHN0cmNtcChoZWFkLT50YXhTdGF0ZSwgIk5IIikgPT0gMCkgcmF0ZSA9IE5IX1RBWF9SQVRFOwogICAgICAgIGVsc2UgaWYoc3RyY21wKGhlYWQtPnRheFN0YXRlLCAiQ0EiKSA9PSAwKSByYXRlID0gQ0FfVEFYX1JBVEU7CiAgICAgICAgZWxzZSByYXRlID0gREVGQVVMVF9TVEFURV9UQVhfUkFURTsKCiAgICAgICAgaGVhZC0+c3RhdGVUYXggPSBDQUxDX1NUQVRFX1RBWChoZWFkLT5ncm9zc1BheSwgcmF0ZSk7CiAgICAgICAgaGVhZCA9IGhlYWQtPm5leHQ7CiAgICB9Cn0KCnZvaWQgY2FsY3VsYXRlRmVkZXJhbFRheChFbXBsb3llZSAqaGVhZCkgewogICAgd2hpbGUoaGVhZCkgewogICAgICAgIGhlYWQtPmZlZFRheCA9IENBTENfRkVEX1RBWChoZWFkLT5ncm9zc1BheSk7CiAgICAgICAgaGVhZCA9IGhlYWQtPm5leHQ7CiAgICB9Cn0KCnZvaWQgY2FsY3VsYXRlTmV0UGF5KEVtcGxveWVlICpoZWFkKSB7CiAgICB3aGlsZShoZWFkKSB7CiAgICAgICAgaGVhZC0+bmV0UGF5ID0gQ0FMQ19ORVRfUEFZKGhlYWQtPmdyb3NzUGF5LCBoZWFkLT5zdGF0ZVRheCwgaGVhZC0+ZmVkVGF4KTsKICAgICAgICBoZWFkID0gaGVhZC0+bmV4dDsKICAgIH0KfQoKLy9DYWxjdWxhdGlvbnMKCnZvaWQgY2FsY3VsYXRlVG90YWxzKEVtcGxveWVlICpoZWFkLCBUb3RhbHMgKnQpIHsKICAgIHdoaWxlKGhlYWQpIHsKICAgICAgICB0LT50b3RhbF93YWdlUmF0ZSArPSBoZWFkLT53YWdlUmF0ZTsKICAgICAgICB0LT50b3RhbF9ob3VycyArPSBoZWFkLT5ob3VyczsKICAgICAgICB0LT50b3RhbF9vdmVydGltZUhycyArPSBoZWFkLT5vdmVydGltZUhyczsKICAgICAgICB0LT50b3RhbF9ncm9zc1BheSArPSBoZWFkLT5ncm9zc1BheTsKICAgICAgICB0LT50b3RhbF9zdGF0ZVRheCArPSBoZWFkLT5zdGF0ZVRheDsKICAgICAgICB0LT50b3RhbF9mZWRUYXggKz0gaGVhZC0+ZmVkVGF4OwogICAgICAgIHQtPnRvdGFsX25ldFBheSArPSBoZWFkLT5uZXRQYXk7CiAgICAgICAgaGVhZCA9IGhlYWQtPm5leHQ7CiAgICB9Cn0KCnZvaWQgY2FsY3VsYXRlTWluTWF4KEVtcGxveWVlICpoZWFkLCBNaW5NYXggKm1tKSB7CiAgICBpZighaGVhZCkgcmV0dXJuOwoKICAgIC8vIEluaXRpYWxpemUgd2l0aCBmaXJzdCBlbXBsb3llZQogICAgbW0tPm1pbl93YWdlUmF0ZSA9IG1tLT5tYXhfd2FnZVJhdGUgPSBoZWFkLT53YWdlUmF0ZTsKICAgIG1tLT5taW5faG91cnMgPSBtbS0+bWF4X2hvdXJzID0gaGVhZC0+aG91cnM7CiAgICBtbS0+bWluX292ZXJ0aW1lSHJzID0gbW0tPm1heF9vdmVydGltZUhycyA9IGhlYWQtPm92ZXJ0aW1lSHJzOwogICAgbW0tPm1pbl9ncm9zc1BheSA9IG1tLT5tYXhfZ3Jvc3NQYXkgPSBoZWFkLT5ncm9zc1BheTsKICAgIG1tLT5taW5fc3RhdGVUYXggPSBtbS0+bWF4X3N0YXRlVGF4ID0gaGVhZC0+c3RhdGVUYXg7CiAgICBtbS0+bWluX2ZlZFRheCA9IG1tLT5tYXhfZmVkVGF4ID0gaGVhZC0+ZmVkVGF4OwogICAgbW0tPm1pbl9uZXRQYXkgPSBtbS0+bWF4X25ldFBheSA9IGhlYWQtPm5ldFBheTsKCiAgICAvLyBQcm9jZXNzIHJlbWFpbmluZyBlbXBsb3llZXMKICAgIHdoaWxlKChoZWFkID0gaGVhZC0+bmV4dCkpIHsKICAgICAgICBtbS0+bWluX3dhZ2VSYXRlID0gQ0FMQ19NSU4oaGVhZC0+d2FnZVJhdGUsIG1tLT5taW5fd2FnZVJhdGUpOwogICAgICAgIG1tLT5tYXhfd2FnZVJhdGUgPSBDQUxDX01BWChoZWFkLT53YWdlUmF0ZSwgbW0tPm1heF93YWdlUmF0ZSk7CiAgICAgICAgCiAgICAgICAgbW0tPm1pbl9ob3VycyA9IENBTENfTUlOKGhlYWQtPmhvdXJzLCBtbS0+bWluX2hvdXJzKTsKICAgICAgICBtbS0+bWF4X2hvdXJzID0gQ0FMQ19NQVgoaGVhZC0+aG91cnMsIG1tLT5tYXhfaG91cnMpOwogICAgICAgIAogICAgICAgIG1tLT5taW5fb3ZlcnRpbWVIcnMgPSBDQUxDX01JTihoZWFkLT5vdmVydGltZUhycywgbW0tPm1pbl9vdmVydGltZUhycyk7CiAgICAgICAgbW0tPm1heF9vdmVydGltZUhycyA9IENBTENfTUFYKGhlYWQtPm92ZXJ0aW1lSHJzLCBtbS0+bWF4X292ZXJ0aW1lSHJzKTsKICAgICAgICAKICAgICAgICBtbS0+bWluX2dyb3NzUGF5ID0gQ0FMQ19NSU4oaGVhZC0+Z3Jvc3NQYXksIG1tLT5taW5fZ3Jvc3NQYXkpOwogICAgICAgIG1tLT5tYXhfZ3Jvc3NQYXkgPSBDQUxDX01BWChoZWFkLT5ncm9zc1BheSwgbW0tPm1heF9ncm9zc1BheSk7CiAgICAgICAgCiAgICAgICAgbW0tPm1pbl9zdGF0ZVRheCA9IENBTENfTUlOKGhlYWQtPnN0YXRlVGF4LCBtbS0+bWluX3N0YXRlVGF4KTsKICAgICAgICBtbS0+bWF4X3N0YXRlVGF4ID0gQ0FMQ19NQVgoaGVhZC0+c3RhdGVUYXgsIG1tLT5tYXhfc3RhdGVUYXgpOwogICAgICAgIAogICAgICAgIG1tLT5taW5fZmVkVGF4ID0gQ0FMQ19NSU4oaGVhZC0+ZmVkVGF4LCBtbS0+bWluX2ZlZFRheCk7CiAgICAgICAgbW0tPm1heF9mZWRUYXggPSBDQUxDX01BWChoZWFkLT5mZWRUYXgsIG1tLT5tYXhfZmVkVGF4KTsKICAgICAgICAKICAgICAgICBtbS0+bWluX25ldFBheSA9IENBTENfTUlOKGhlYWQtPm5ldFBheSwgbW0tPm1pbl9uZXRQYXkpOwogICAgICAgIG1tLT5tYXhfbmV0UGF5ID0gQ0FMQ19NQVgoaGVhZC0+bmV0UGF5LCBtbS0+bWF4X25ldFBheSk7CiAgICB9Cn0KCgovLyBPdXRwdXQgRnVuY3Rpb25zCgp2b2lkIHByaW50SGVhZGVyKCkgewogICAgcHJpbnRmKCJcblxuKioqIFBheSBDYWxjdWxhdG9yICoqKlxuIik7CiAgICBwcmludGYoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKICAgIHByaW50ZigiJS0yMHMgJS02cyAlLTEwcyAlLTZzICUtNXMgJS04cyAlLThzICUtOHNcbiIsIAogICAgICAgICAgICJOYW1lIiwgIlN0YXRlIiwgIkNsb2NrIyIsICJXYWdlIiwgIkhvdXJzIiwgIkdyb3NzIiwgIlN0YXRlIFRheCIsIAogICAgICAgICAgICJGZWQgVGF4IiwgIk5ldCBQYXkiKTsKICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwp9Cgp2b2lkIHByaW50RW1wbG95ZWUoRW1wbG95ZWUgKmhlYWQpIHsKICAgIHdoaWxlKGhlYWQpIHsKICAgICAgICBjaGFyIGZ1bGxOYW1lW0ZJUlNUX05BTUVfU0laRSArIExBU1RfTkFNRV9TSVpFICsgMl07CiAgICAgICAgc25wcmludGYoZnVsbE5hbWUsIHNpemVvZihmdWxsTmFtZSksICIlcyAlcyIsIAogICAgICAgICAgICAgICAgaGVhZC0+ZW1wTmFtZS5maXJzdE5hbWUsIGhlYWQtPmVtcE5hbWUubGFzdE5hbWUpOwogICAgICAgIAogICAgICAgIHByaW50ZigiJS0yMHMgJS02cyAlLTEwbGQgJS02LjJmICUtNS4xZiAlLTguMmYgJS04LjJmICUtOC4yZiAlLTguMmZcbiIsCiAgICAgICAgICAgICAgIGZ1bGxOYW1lLAogICAgICAgICAgICAgICBoZWFkLT50YXhTdGF0ZSwKICAgICAgICAgICAgICAgaGVhZC0+Y2xvY2tOdW1iZXIsCiAgICAgICAgICAgICAgIGhlYWQtPndhZ2VSYXRlLAogICAgICAgICAgICAgICBoZWFkLT5ob3VycywKICAgICAgICAgICAgICAgaGVhZC0+Z3Jvc3NQYXksCiAgICAgICAgICAgICAgIGhlYWQtPnN0YXRlVGF4LAogICAgICAgICAgICAgICBoZWFkLT5mZWRUYXgsCiAgICAgICAgICAgICAgIGhlYWQtPm5ldFBheSk7CiAgICAgICAgCiAgICAgICAgaGVhZCA9IGhlYWQtPm5leHQ7CiAgICB9Cn0KCnZvaWQgcHJpbnRTdGF0aXN0aWNzKFRvdGFscyAqdCwgTWluTWF4ICptbSwgaW50IGNvdW50KSB7CiAgICBwcmludGYoIlxuLS0tIFBheXJvbGwgU3RhdGlzdGljcyAtLS1cbiIpOwogICAgcHJpbnRmKCJUb3RhbHM6XG4iKTsKICAgIHByaW50ZigiIFdhZ2VzOiAkJS4yZiAgSG91cnM6ICUuMWYgIE9UOiAlLjFmXG4iLCAKICAgICAgICAgICB0LT50b3RhbF93YWdlUmF0ZSwgdC0+dG90YWxfaG91cnMsIHQtPnRvdGFsX292ZXJ0aW1lSHJzKTsKICAgIHByaW50ZigiIEdyb3NzOiAkJS4yZiAgU3RhdGUgVGF4OiAkJS4yZiAgRmVkZXJhbCBUYXg6ICQlLjJmICBOZXQ6ICQlLjJmXG4iLAogICAgICAgICAgIHQtPnRvdGFsX2dyb3NzUGF5LCB0LT50b3RhbF9zdGF0ZVRheCwgdC0+dG90YWxfZmVkVGF4LCB0LT50b3RhbF9uZXRQYXkpOwoKICAgIHByaW50ZigiXG5BdmVyYWdlcyAoJWQgZW1wbG95ZWVzKTpcbiIsIGNvdW50KTsKICAgIHByaW50ZigiIFdhZ2U6ICQlLjJmL2hyICBIb3VyczogJS4xZiAgT1Q6ICUuMWZcbiIsCiAgICAgICAgICAgdC0+dG90YWxfd2FnZVJhdGUvY291bnQsIHQtPnRvdGFsX2hvdXJzL2NvdW50LCB0LT50b3RhbF9vdmVydGltZUhycy9jb3VudCk7CiAgICBwcmludGYoIiBHcm9zczogJCUuMmYgIE5ldDogJCUuMmZcbiIsCiAgICAgICAgICAgdC0+dG90YWxfZ3Jvc3NQYXkvY291bnQsIHQtPnRvdGFsX25ldFBheS9jb3VudCk7CgogICAgcHJpbnRmKCJcbk1pbmltdW1zOlxuIik7CiAgICBwcmludGYoIiBXYWdlOiAkJS4yZiAgSG91cnM6ICUuMWYgIEdyb3NzOiAkJS4yZiAgTmV0OiAkJS4yZlxuIiwKICAgICAgICAgICBtbS0+bWluX3dhZ2VSYXRlLCBtbS0+bWluX2hvdXJzLCBtbS0+bWluX2dyb3NzUGF5LCBtbS0+bWluX25ldFBheSk7CiAgICAKICAgIHByaW50ZigiXG5NYXhpbXVtczpcbiIpOwogICAgcHJpbnRmKCIgV2FnZTogJCUuMmYgIEhvdXJzOiAlLjFmICBHcm9zczogJCUuMmYgIE5ldDogJCUuMmZcbiIsCiAgICAgICAgICAgbW0tPm1heF93YWdlUmF0ZSwgbW0tPm1heF9ob3VycywgbW0tPm1heF9ncm9zc1BheSwgbW0tPm1heF9uZXRQYXkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBVdGlsaXR5IEZ1bmN0aW9ucwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW50IGNvdW50RW1wbG95ZWVzKEVtcGxveWVlICpoZWFkKSB7CiAgICBpbnQgY291bnQgPSAwOwogICAgd2hpbGUoaGVhZCkgewogICAgICAgIGNvdW50Kys7CiAgICAgICAgaGVhZCA9IGhlYWQtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gY291bnQ7Cn0KCnZvaWQgZnJlZUVtcGxveWVlcyhFbXBsb3llZSAqaGVhZCkgewogICAgd2hpbGUoaGVhZCkgewogICAgICAgIEVtcGxveWVlICp0ZW1wID0gaGVhZDsKICAgICAgICBoZWFkID0gaGVhZC0+bmV4dDsKICAgICAgICBmcmVlKHRlbXApOwogICAgfQp9