//********************************************************
//
// 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=