//********************************************************
//
// Assignment 10 - Linked Lists, Typedef, and Macros
//
// Name: <Kyle Merrihew>
//
// Class: C Programming, <Spring 2025>
//
// Date: <April 17,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)
//
//********************************************************
// necessary header files
#include <stdio.h>
#include <string.h>
#include <ctype.h> // for char functions
#include <stdlib.h> // for malloc
// define 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 NAME_SIZE 20
#define TAX_STATE_SIZE 3
#define FED_TAX_RATE 0.25
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10
// define macros
#define CALC_OT_HOURS(theHours) ((theHours > STD_HOURS) ? theHours - STD_HOURS : 0)
#define CALC_STATE_TAX(thePay,theStateTaxRate) (thePay * theStateTaxRate)
// ✅ CALC_FED_TAX macro
#define CALC_FED_TAX(thePay) (thePay * FED_TAX_RATE)
// ✅ Net Pay, Regular Pay, Overtime Pay
#define CALC_NET_PAY(thePay,theStateTax,theFedTax) (thePay - (theStateTax + theFedTax))
#define CALC_NORMAL_PAY(theWageRate,theHours,theOvertimeHrs) \
(theWageRate * (theHours - theOvertimeHrs))
#define CALC_OT_PAY(theWageRate,theOvertimeHrs) (theOvertimeHrs * (OT_RATE * theWageRate))
// ✅ Min and Max macros
#define CALC_MIN(theValue, currentMin) ((theValue < currentMin) ? theValue : currentMin)
#define CALC_MAX(theValue, currentMax) ((theValue > currentMax) ? theValue : currentMax)
// Define a global structure type to store an employee name
struct name
{
char firstName[ FIRST_NAME_SIZE] ;
char lastName [ LAST_NAME_SIZE] ;
} ;
// Define a global structure type to pass employee data between functions
typedef struct employee
{
struct name empName;
char taxState [ TAX_STATE_SIZE] ;
long int clockNumber;
float wageRate;
float hours;
float overtimeHrs;
float grossPay;
float stateTax;
float fedTax;
float netPay;
struct employee * next;
} EMPLOYEE;
// Define totals structure
typedef struct totals
{
float total_wageRate;
float total_hours;
float total_overtimeHrs;
float total_grossPay;
float total_stateTax;
float total_fedTax;
float total_netPay;
} TOTALS;
// ✅ Define MIN_MAX alias for min and max tracking
typedef struct min_max
{
float min_wageRate;
float min_hours;
float min_overtimeHrs;
float min_grossPay;
float min_stateTax;
float min_fedTax;
float min_netPay;
float max_wageRate;
float max_hours;
float max_overtimeHrs;
float max_grossPay;
float max_stateTax;
float max_fedTax;
float max_netPay;
} MIN_MAX;
// Function Prototypes
void printHeader( void ) ;
EMPLOYEE
* createEmployee
( char first
[ ] , char last
[ ] , char state
[ ] , long int clock , float wage
, float hours
) ; void printEmployeeData( EMPLOYEE * emp) ;
void computePayroll( EMPLOYEE * emp, TOTALS * totals, MIN_MAX * minmax) ;
void printTotals( TOTALS totals, int count) ;
void printMinMax( MIN_MAX minmax) ;
int main( void )
{
EMPLOYEE * head = NULL;
EMPLOYEE * current = NULL;
// Initialize totals
TOTALS totals = { 0 } ;
MIN_MAX minmax = {
.min_wageRate = 999999.0 , .min_hours = 999999.0 , .min_overtimeHrs = 999999.0 ,
.min_grossPay = 999999.0 , .min_stateTax = 999999.0 , .min_fedTax = 999999.0 , .min_netPay = 999999.0 ,
.max_wageRate = 0.0 , .max_hours = 0.0 , .max_overtimeHrs = 0.0 ,
.max_grossPay = 0.0 , .max_stateTax = 0.0 , .max_fedTax = 0.0 , .max_netPay = 0.0
} ;
// Create employee linked list
head = createEmployee( "John" , "Doe" , "MA" , 98401 , 10.60 , 51.0 ) ;
head-> next = createEmployee( "Jane" , "Smith" , "NH" , 526488 , 9.75 , 42.5 ) ;
head-> next-> next = createEmployee( "Alice" , "Johnson" , "VT" , 765349 , 10.50 , 37.0 ) ;
head-> next-> next-> next = createEmployee( "Bob" , "Lee" , "CA" , 34645 , 12.25 , 45.0 ) ;
head-> next-> next-> next-> next = createEmployee( "Emma" , "Davis" , "TX" , 127615 , 8.35 , 0.0 ) ;
printHeader( ) ;
current = head;
int count = 0 ;
while ( current != NULL)
{
computePayroll( current, & totals, & minmax) ;
printEmployeeData( current) ;
current = current-> next;
count++;
}
printTotals( totals, count) ;
printMinMax( minmax) ;
return 0 ;
}
// Dummy implementations below for illustration — add full logic as needed
EMPLOYEE
* createEmployee
( char first
[ ] , char last
[ ] , char state
[ ] , long int clock , float wage
, float hours
) {
EMPLOYEE
* emp
= ( EMPLOYEE
* ) malloc ( sizeof ( EMPLOYEE
) ) ;
strcpy ( emp
-> empName.
firstName , first
) ; strcpy ( emp
-> empName.
lastName , last
) ; emp
-> clockNumber
= clock ; emp-> wageRate = wage;
emp-> hours = hours;
emp-> next = NULL;
return emp;
}
void computePayroll( EMPLOYEE * emp, TOTALS * totals, MIN_MAX * minmax)
{
emp-> overtimeHrs = CALC_OT_HOURS( emp-> hours) ;
float regularPay = CALC_NORMAL_PAY( emp-> wageRate, emp-> hours, emp-> overtimeHrs) ;
float overtimePay = CALC_OT_PAY( emp-> wageRate, emp-> overtimeHrs) ;
emp-> grossPay = regularPay + overtimePay;
float stateTaxRate;
if ( strcmp ( emp
-> taxState
, "MA" ) == 0 ) stateTaxRate = MA_TAX_RATE;
else if ( strcmp ( emp
-> taxState
, "NH" ) == 0 ) stateTaxRate = NH_TAX_RATE;
else if ( strcmp ( emp
-> taxState
, "VT" ) == 0 ) stateTaxRate = VT_TAX_RATE;
else if ( strcmp ( emp
-> taxState
, "CA" ) == 0 ) stateTaxRate = CA_TAX_RATE;
else
stateTaxRate = DEFAULT_STATE_TAX_RATE;
emp-> stateTax = CALC_STATE_TAX( emp-> grossPay, stateTaxRate) ;
emp-> fedTax = CALC_FED_TAX( emp-> grossPay) ;
emp-> netPay = CALC_NET_PAY( emp-> grossPay, emp-> stateTax, emp-> fedTax) ;
// Update 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;
// Update min values
minmax-> min_wageRate = CALC_MIN( emp-> wageRate, minmax-> min_wageRate) ;
minmax-> min_hours = CALC_MIN( emp-> hours, minmax-> min_hours) ;
minmax-> min_overtimeHrs = CALC_MIN( emp-> overtimeHrs, minmax-> min_overtimeHrs) ;
minmax-> min_grossPay = CALC_MIN( emp-> grossPay, minmax-> min_grossPay) ;
minmax-> min_stateTax = CALC_MIN( emp-> stateTax, minmax-> min_stateTax) ;
minmax-> min_fedTax = CALC_MIN( emp-> fedTax, minmax-> min_fedTax) ;
minmax-> min_netPay = CALC_MIN( emp-> netPay, minmax-> min_netPay) ;
// Update max values
minmax-> max_wageRate = CALC_MAX( emp-> wageRate, minmax-> max_wageRate) ;
minmax-> max_hours = CALC_MAX( emp-> hours, minmax-> max_hours) ;
minmax-> max_overtimeHrs = CALC_MAX( emp-> overtimeHrs, minmax-> max_overtimeHrs) ;
minmax-> max_grossPay = CALC_MAX( emp-> grossPay, minmax-> max_grossPay) ;
minmax-> max_stateTax = CALC_MAX( emp-> stateTax, minmax-> max_stateTax) ;
minmax-> max_fedTax = CALC_MAX( emp-> fedTax, minmax-> max_fedTax) ;
minmax-> max_netPay = CALC_MAX( emp-> netPay, minmax-> max_netPay) ;
}
void printHeader( void )
{
printf ( "-----------------------------------------------------------------------\n " ) ; printf ( "Name Clock# Wage Hours OT Gross State Fed Net\n " ) ; printf ( " Hours Pay Tax Tax Pay\n " ) ; printf ( "-----------------------------------------------------------------------\n " ) ; }
void printEmployeeData( EMPLOYEE * emp)
{
printf ( "%-10s %-10s %06li %5.2f %5.1f %5.1f %7.2f %6.2f %6.2f %7.2f\n " , emp-> empName.firstName ,
emp-> empName.lastName ,
emp-> clockNumber,
emp-> wageRate,
emp-> hours,
emp-> overtimeHrs,
emp-> grossPay,
emp-> stateTax,
emp-> fedTax,
emp-> netPay) ;
}
void printTotals( TOTALS totals, int count)
{
printf ( " %5.2f %5.1f %5.1f %7.2f %6.2f %6.2f %7.2f\n " , totals.total_wageRate / count,
totals.total_hours / count,
totals.total_overtimeHrs / count,
totals.total_grossPay / count,
totals.total_stateTax / count,
totals.total_fedTax / count,
totals.total_netPay / count) ;
}
void printMinMax( MIN_MAX minmax)
{
printf ( " %5.2f %5.1f %5.1f %7.2f %6.2f %6.2f %7.2f\n " , minmax.min_wageRate ,
minmax.min_hours ,
minmax.min_overtimeHrs ,
minmax.min_grossPay ,
minmax.min_stateTax ,
minmax.min_fedTax ,
minmax.min_netPay ) ;
printf ( " %5.2f %5.1f %5.1f %7.2f %6.2f %6.2f %7.2f\n " , minmax.max_wageRate ,
minmax.max_hours ,
minmax.max_overtimeHrs ,
minmax.max_grossPay ,
minmax.max_stateTax ,
minmax.max_fedTax ,
minmax.max_netPay ) ;
}
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDEwIC0gTGlua2VkIExpc3RzLCBUeXBlZGVmLCBhbmQgTWFjcm9zCi8vCi8vIE5hbWU6IDxLeWxlIE1lcnJpaGV3PgovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgPFNwcmluZyAyMDI1PgovLwovLyBEYXRlOiA8QXByaWwgMTcsMjAyNT4KLy8KLy8gRGVzY3JpcHRpb246IFByb2dyYW0gd2hpY2ggZGV0ZXJtaW5lcyBvdmVydGltZSBhbmQgCi8vIGdyb3NzIHBheSBmb3IgYSBzZXQgb2YgZW1wbG95ZWVzIHdpdGggb3V0cHV0cyBzZW50IAovLyB0byBzdGFuZGFyZCBvdXRwdXQgKHRoZSBzY3JlZW4pLgovLwovLyBUaGlzIGFzc2lnbm1lbnQgYWxzbyBhZGRzIHRoZSBlbXBsb3llZSBuYW1lLCB0aGVpciB0YXggc3RhdGUsCi8vIGFuZCBjYWxjdWxhdGVzIHRoZSBzdGF0ZSB0YXgsIGZlZGVyYWwgdGF4LCBhbmQgbmV0IHBheS4gICBJdAovLyBhbHNvIGNhbGN1bGF0ZXMgdG90YWxzLCBhdmVyYWdlcywgbWluaW11bSwgYW5kIG1heGltdW0gdmFsdWVzLgovLwovLyBBcnJheSBhbmQgU3RydWN0dXJlIHJlZmVyZW5jZXMgaGF2ZSBhbGwgYmVlbiByZXBsYWNlZCB3aXRoCi8vIHBvaW50ZXIgcmVmZXJlbmNlcyB0byBzcGVlZCB1cCB0aGUgcHJvY2Vzc2luZyBvZiB0aGlzIGNvZGUuCi8vIEEgbGlua2VkIGxpc3QgaGFzIGJlZW4gY3JlYXRlZCBhbmQgZGVwbG95ZWQgdG8gZHluYW1pY2FsbHkKLy8gYWxsb2NhdGUgYW5kIHByb2Nlc3MgZW1wbG95ZWVzIGFzIG5lZWRlZC4KLy8KLy8gSXQgd2lsbCBhbHNvIHRha2UgYWR2YW50YWdlIG9mIHRoZSBDIFByZXByb2Nlc3NvciBmZWF0dXJlcywKLy8gaW4gcGFydGljdWxhciB3aXRoIHVzaW5nIG1hY3JvcywgYW5kIHdpbGwgcmVwbGFjZSBhbGwgCi8vIHN0cnVjdCB0eXBlIHJlZmVyZW5jZXMgaW4gdGhlIGNvZGUgd2l0aCBhIHR5cGVkZWYgYWxpYXMKLy8gcmVmZXJlbmNlLgovLwovLyBDYWxsIGJ5IFJlZmVyZW5jZSBkZXNpZ24gKHVzaW5nIHBvaW50ZXJzKQovLwovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgovLyBuZWNlc3NhcnkgaGVhZGVyIGZpbGVzCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPiAgIC8vIGZvciBjaGFyIGZ1bmN0aW9ucwojaW5jbHVkZSA8c3RkbGliLmg+ICAvLyBmb3IgbWFsbG9jCgovLyBkZWZpbmUgY29uc3RhbnRzCiNkZWZpbmUgU1REX0hPVVJTIDQwLjAKI2RlZmluZSBPVF9SQVRFIDEuNQojZGVmaW5lIE1BX1RBWF9SQVRFIDAuMDUKI2RlZmluZSBOSF9UQVhfUkFURSAwLjAKI2RlZmluZSBWVF9UQVhfUkFURSAwLjA2CiNkZWZpbmUgQ0FfVEFYX1JBVEUgMC4wNwojZGVmaW5lIERFRkFVTFRfU1RBVEVfVEFYX1JBVEUgMC4wOAojZGVmaW5lIE5BTUVfU0laRSAyMAojZGVmaW5lIFRBWF9TVEFURV9TSVpFIDMKI2RlZmluZSBGRURfVEFYX1JBVEUgMC4yNQojZGVmaW5lIEZJUlNUX05BTUVfU0laRSAxMAojZGVmaW5lIExBU1RfTkFNRV9TSVpFIDEwCgovLyBkZWZpbmUgbWFjcm9zCiNkZWZpbmUgQ0FMQ19PVF9IT1VSUyh0aGVIb3VycykgKCh0aGVIb3VycyA+IFNURF9IT1VSUykgPyB0aGVIb3VycyAtIFNURF9IT1VSUyA6IDApCiNkZWZpbmUgQ0FMQ19TVEFURV9UQVgodGhlUGF5LHRoZVN0YXRlVGF4UmF0ZSkgKHRoZVBheSAqIHRoZVN0YXRlVGF4UmF0ZSkKCi8vIOKchSBDQUxDX0ZFRF9UQVggbWFjcm8KI2RlZmluZSBDQUxDX0ZFRF9UQVgodGhlUGF5KSAodGhlUGF5ICogRkVEX1RBWF9SQVRFKQoKLy8g4pyFIE5ldCBQYXksIFJlZ3VsYXIgUGF5LCBPdmVydGltZSBQYXkKI2RlZmluZSBDQUxDX05FVF9QQVkodGhlUGF5LHRoZVN0YXRlVGF4LHRoZUZlZFRheCkgKHRoZVBheSAtICh0aGVTdGF0ZVRheCArIHRoZUZlZFRheCkpCiNkZWZpbmUgQ0FMQ19OT1JNQUxfUEFZKHRoZVdhZ2VSYXRlLHRoZUhvdXJzLHRoZU92ZXJ0aW1lSHJzKSBcCih0aGVXYWdlUmF0ZSAqICh0aGVIb3VycyAtIHRoZU92ZXJ0aW1lSHJzKSkKI2RlZmluZSBDQUxDX09UX1BBWSh0aGVXYWdlUmF0ZSx0aGVPdmVydGltZUhycykgKHRoZU92ZXJ0aW1lSHJzICogKE9UX1JBVEUgKiB0aGVXYWdlUmF0ZSkpCgovLyDinIUgTWluIGFuZCBNYXggbWFjcm9zCiNkZWZpbmUgQ0FMQ19NSU4odGhlVmFsdWUsIGN1cnJlbnRNaW4pICgodGhlVmFsdWUgPCBjdXJyZW50TWluKSA/IHRoZVZhbHVlIDogY3VycmVudE1pbikKI2RlZmluZSBDQUxDX01BWCh0aGVWYWx1ZSwgY3VycmVudE1heCkgKCh0aGVWYWx1ZSA+IGN1cnJlbnRNYXgpID8gdGhlVmFsdWUgOiBjdXJyZW50TWF4KQoKLy8gRGVmaW5lIGEgZ2xvYmFsIHN0cnVjdHVyZSB0eXBlIHRvIHN0b3JlIGFuIGVtcGxveWVlIG5hbWUKc3RydWN0IG5hbWUKewogICAgY2hhciBmaXJzdE5hbWVbRklSU1RfTkFNRV9TSVpFXTsKICAgIGNoYXIgbGFzdE5hbWUgW0xBU1RfTkFNRV9TSVpFXTsKfTsKCi8vIERlZmluZSBhIGdsb2JhbCBzdHJ1Y3R1cmUgdHlwZSB0byBwYXNzIGVtcGxveWVlIGRhdGEgYmV0d2VlbiBmdW5jdGlvbnMKdHlwZWRlZiBzdHJ1Y3QgZW1wbG95ZWUKewogICAgc3RydWN0IG5hbWUgZW1wTmFtZTsKICAgIGNoYXIgdGF4U3RhdGUgW1RBWF9TVEFURV9TSVpFXTsKICAgIGxvbmcgaW50IGNsb2NrTnVtYmVyOwogICAgZmxvYXQgd2FnZVJhdGU7CiAgICBmbG9hdCBob3VyczsKICAgIGZsb2F0IG92ZXJ0aW1lSHJzOwogICAgZmxvYXQgZ3Jvc3NQYXk7CiAgICBmbG9hdCBzdGF0ZVRheDsKICAgIGZsb2F0IGZlZFRheDsKICAgIGZsb2F0IG5ldFBheTsKICAgIHN0cnVjdCBlbXBsb3llZSAqIG5leHQ7Cn0gRU1QTE9ZRUU7CgovLyBEZWZpbmUgdG90YWxzIHN0cnVjdHVyZQp0eXBlZGVmIHN0cnVjdCB0b3RhbHMKewogICAgZmxvYXQgdG90YWxfd2FnZVJhdGU7CiAgICBmbG9hdCB0b3RhbF9ob3VyczsKICAgIGZsb2F0IHRvdGFsX292ZXJ0aW1lSHJzOwogICAgZmxvYXQgdG90YWxfZ3Jvc3NQYXk7CiAgICBmbG9hdCB0b3RhbF9zdGF0ZVRheDsKICAgIGZsb2F0IHRvdGFsX2ZlZFRheDsKICAgIGZsb2F0IHRvdGFsX25ldFBheTsKfSBUT1RBTFM7CgovLyDinIUgRGVmaW5lIE1JTl9NQVggYWxpYXMgZm9yIG1pbiBhbmQgbWF4IHRyYWNraW5nCnR5cGVkZWYgc3RydWN0IG1pbl9tYXgKewogICAgZmxvYXQgbWluX3dhZ2VSYXRlOwogICAgZmxvYXQgbWluX2hvdXJzOwogICAgZmxvYXQgbWluX292ZXJ0aW1lSHJzOwogICAgZmxvYXQgbWluX2dyb3NzUGF5OwogICAgZmxvYXQgbWluX3N0YXRlVGF4OwogICAgZmxvYXQgbWluX2ZlZFRheDsKICAgIGZsb2F0IG1pbl9uZXRQYXk7CiAgICBmbG9hdCBtYXhfd2FnZVJhdGU7CiAgICBmbG9hdCBtYXhfaG91cnM7CiAgICBmbG9hdCBtYXhfb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtYXhfZ3Jvc3NQYXk7CiAgICBmbG9hdCBtYXhfc3RhdGVUYXg7CiAgICBmbG9hdCBtYXhfZmVkVGF4OwogICAgZmxvYXQgbWF4X25ldFBheTsKfSBNSU5fTUFYOwovLyBGdW5jdGlvbiBQcm90b3R5cGVzCnZvaWQgcHJpbnRIZWFkZXIodm9pZCk7CkVNUExPWUVFICogY3JlYXRlRW1wbG95ZWUoY2hhciBmaXJzdFtdLCBjaGFyIGxhc3RbXSwgY2hhciBzdGF0ZVtdLCBsb25nIGludCBjbG9jaywgZmxvYXQgd2FnZSwgZmxvYXQgaG91cnMpOwp2b2lkIHByaW50RW1wbG95ZWVEYXRhKEVNUExPWUVFICogZW1wKTsKdm9pZCBjb21wdXRlUGF5cm9sbChFTVBMT1lFRSAqIGVtcCwgVE9UQUxTICogdG90YWxzLCBNSU5fTUFYICogbWlubWF4KTsKdm9pZCBwcmludFRvdGFscyhUT1RBTFMgdG90YWxzLCBpbnQgY291bnQpOwp2b2lkIHByaW50TWluTWF4KE1JTl9NQVggbWlubWF4KTsKCmludCBtYWluKHZvaWQpCnsKICAgIEVNUExPWUVFICogaGVhZCA9IE5VTEw7CiAgICBFTVBMT1lFRSAqIGN1cnJlbnQgPSBOVUxMOwoKICAgIC8vIEluaXRpYWxpemUgdG90YWxzCiAgICBUT1RBTFMgdG90YWxzID0gezB9OwogICAgTUlOX01BWCBtaW5tYXggPSB7CiAgICAgICAgLm1pbl93YWdlUmF0ZSA9IDk5OTk5OS4wLCAubWluX2hvdXJzID0gOTk5OTk5LjAsIC5taW5fb3ZlcnRpbWVIcnMgPSA5OTk5OTkuMCwKICAgICAgICAubWluX2dyb3NzUGF5ID0gOTk5OTk5LjAsIC5taW5fc3RhdGVUYXggPSA5OTk5OTkuMCwgLm1pbl9mZWRUYXggPSA5OTk5OTkuMCwgLm1pbl9uZXRQYXkgPSA5OTk5OTkuMCwKICAgICAgICAubWF4X3dhZ2VSYXRlID0gMC4wLCAubWF4X2hvdXJzID0gMC4wLCAubWF4X292ZXJ0aW1lSHJzID0gMC4wLAogICAgICAgIC5tYXhfZ3Jvc3NQYXkgPSAwLjAsIC5tYXhfc3RhdGVUYXggPSAwLjAsIC5tYXhfZmVkVGF4ID0gMC4wLCAubWF4X25ldFBheSA9IDAuMAogICAgfTsKCiAgICAvLyBDcmVhdGUgZW1wbG95ZWUgbGlua2VkIGxpc3QKICAgIGhlYWQgPSBjcmVhdGVFbXBsb3llZSgiSm9obiIsICJEb2UiLCAiTUEiLCA5ODQwMSwgMTAuNjAsIDUxLjApOwogICAgaGVhZC0+bmV4dCA9IGNyZWF0ZUVtcGxveWVlKCJKYW5lIiwgIlNtaXRoIiwgIk5IIiwgNTI2NDg4LCA5Ljc1LCA0Mi41KTsKICAgIGhlYWQtPm5leHQtPm5leHQgPSBjcmVhdGVFbXBsb3llZSgiQWxpY2UiLCAiSm9obnNvbiIsICJWVCIsIDc2NTM0OSwgMTAuNTAsIDM3LjApOwogICAgaGVhZC0+bmV4dC0+bmV4dC0+bmV4dCA9IGNyZWF0ZUVtcGxveWVlKCJCb2IiLCAiTGVlIiwgIkNBIiwgMzQ2NDUsIDEyLjI1LCA0NS4wKTsKICAgIGhlYWQtPm5leHQtPm5leHQtPm5leHQtPm5leHQgPSBjcmVhdGVFbXBsb3llZSgiRW1tYSIsICJEYXZpcyIsICJUWCIsIDEyNzYxNSwgOC4zNSwgMC4wKTsKCiAgICBwcmludEhlYWRlcigpOwoKICAgIGN1cnJlbnQgPSBoZWFkOwogICAgaW50IGNvdW50ID0gMDsKCiAgICB3aGlsZSAoY3VycmVudCAhPSBOVUxMKQogICAgewogICAgICAgIGNvbXB1dGVQYXlyb2xsKGN1cnJlbnQsICZ0b3RhbHMsICZtaW5tYXgpOwogICAgICAgIHByaW50RW1wbG95ZWVEYXRhKGN1cnJlbnQpOwogICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LT5uZXh0OwogICAgICAgIGNvdW50Kys7CiAgICB9CgogICAgcHJpbnRUb3RhbHModG90YWxzLCBjb3VudCk7CiAgICBwcmludE1pbk1heChtaW5tYXgpOwoKICAgIHJldHVybiAwOwp9CgovLyBEdW1teSBpbXBsZW1lbnRhdGlvbnMgYmVsb3cgZm9yIGlsbHVzdHJhdGlvbiDigJQgYWRkIGZ1bGwgbG9naWMgYXMgbmVlZGVkCgpFTVBMT1lFRSAqIGNyZWF0ZUVtcGxveWVlKGNoYXIgZmlyc3RbXSwgY2hhciBsYXN0W10sIGNoYXIgc3RhdGVbXSwgbG9uZyBpbnQgY2xvY2ssIGZsb2F0IHdhZ2UsIGZsb2F0IGhvdXJzKQp7CiAgICBFTVBMT1lFRSAqIGVtcCA9IChFTVBMT1lFRSAqKSBtYWxsb2Moc2l6ZW9mKEVNUExPWUVFKSk7CgogICAgc3RyY3B5KGVtcC0+ZW1wTmFtZS5maXJzdE5hbWUsIGZpcnN0KTsKICAgIHN0cmNweShlbXAtPmVtcE5hbWUubGFzdE5hbWUsIGxhc3QpOwogICAgc3RyY3B5KGVtcC0+dGF4U3RhdGUsIHN0YXRlKTsKICAgIGVtcC0+Y2xvY2tOdW1iZXIgPSBjbG9jazsKICAgIGVtcC0+d2FnZVJhdGUgPSB3YWdlOwogICAgZW1wLT5ob3VycyA9IGhvdXJzOwogICAgZW1wLT5uZXh0ID0gTlVMTDsKCiAgICByZXR1cm4gZW1wOwp9Cgp2b2lkIGNvbXB1dGVQYXlyb2xsKEVNUExPWUVFICogZW1wLCBUT1RBTFMgKiB0b3RhbHMsIE1JTl9NQVggKiBtaW5tYXgpCnsKICAgIGVtcC0+b3ZlcnRpbWVIcnMgPSBDQUxDX09UX0hPVVJTKGVtcC0+aG91cnMpOwogICAgZmxvYXQgcmVndWxhclBheSA9IENBTENfTk9STUFMX1BBWShlbXAtPndhZ2VSYXRlLCBlbXAtPmhvdXJzLCBlbXAtPm92ZXJ0aW1lSHJzKTsKICAgIGZsb2F0IG92ZXJ0aW1lUGF5ID0gQ0FMQ19PVF9QQVkoZW1wLT53YWdlUmF0ZSwgZW1wLT5vdmVydGltZUhycyk7CiAgICBlbXAtPmdyb3NzUGF5ID0gcmVndWxhclBheSArIG92ZXJ0aW1lUGF5OwoKICAgIGZsb2F0IHN0YXRlVGF4UmF0ZTsKCiAgICBpZiAoc3RyY21wKGVtcC0+dGF4U3RhdGUsICJNQSIpID09IDApCiAgICAgICAgc3RhdGVUYXhSYXRlID0gTUFfVEFYX1JBVEU7CiAgICBlbHNlIGlmIChzdHJjbXAoZW1wLT50YXhTdGF0ZSwgIk5IIikgPT0gMCkKICAgICAgICBzdGF0ZVRheFJhdGUgPSBOSF9UQVhfUkFURTsKICAgIGVsc2UgaWYgKHN0cmNtcChlbXAtPnRheFN0YXRlLCAiVlQiKSA9PSAwKQogICAgICAgIHN0YXRlVGF4UmF0ZSA9IFZUX1RBWF9SQVRFOwogICAgZWxzZSBpZiAoc3RyY21wKGVtcC0+dGF4U3RhdGUsICJDQSIpID09IDApCiAgICAgICAgc3RhdGVUYXhSYXRlID0gQ0FfVEFYX1JBVEU7CiAgICBlbHNlCiAgICAgICAgc3RhdGVUYXhSYXRlID0gREVGQVVMVF9TVEFURV9UQVhfUkFURTsKCiAgICBlbXAtPnN0YXRlVGF4ID0gQ0FMQ19TVEFURV9UQVgoZW1wLT5ncm9zc1BheSwgc3RhdGVUYXhSYXRlKTsKICAgIGVtcC0+ZmVkVGF4ID0gQ0FMQ19GRURfVEFYKGVtcC0+Z3Jvc3NQYXkpOwogICAgZW1wLT5uZXRQYXkgPSBDQUxDX05FVF9QQVkoZW1wLT5ncm9zc1BheSwgZW1wLT5zdGF0ZVRheCwgZW1wLT5mZWRUYXgpOwoKICAgIC8vIFVwZGF0ZSB0b3RhbHMKICAgIHRvdGFscy0+dG90YWxfd2FnZVJhdGUgKz0gZW1wLT53YWdlUmF0ZTsKICAgIHRvdGFscy0+dG90YWxfaG91cnMgKz0gZW1wLT5ob3VyczsKICAgIHRvdGFscy0+dG90YWxfb3ZlcnRpbWVIcnMgKz0gZW1wLT5vdmVydGltZUhyczsKICAgIHRvdGFscy0+dG90YWxfZ3Jvc3NQYXkgKz0gZW1wLT5ncm9zc1BheTsKICAgIHRvdGFscy0+dG90YWxfc3RhdGVUYXggKz0gZW1wLT5zdGF0ZVRheDsKICAgIHRvdGFscy0+dG90YWxfZmVkVGF4ICs9IGVtcC0+ZmVkVGF4OwogICAgdG90YWxzLT50b3RhbF9uZXRQYXkgKz0gZW1wLT5uZXRQYXk7CgogICAgLy8gVXBkYXRlIG1pbiB2YWx1ZXMKICAgIG1pbm1heC0+bWluX3dhZ2VSYXRlID0gQ0FMQ19NSU4oZW1wLT53YWdlUmF0ZSwgbWlubWF4LT5taW5fd2FnZVJhdGUpOwogICAgbWlubWF4LT5taW5faG91cnMgPSBDQUxDX01JTihlbXAtPmhvdXJzLCBtaW5tYXgtPm1pbl9ob3Vycyk7CiAgICBtaW5tYXgtPm1pbl9vdmVydGltZUhycyA9IENBTENfTUlOKGVtcC0+b3ZlcnRpbWVIcnMsIG1pbm1heC0+bWluX292ZXJ0aW1lSHJzKTsKICAgIG1pbm1heC0+bWluX2dyb3NzUGF5ID0gQ0FMQ19NSU4oZW1wLT5ncm9zc1BheSwgbWlubWF4LT5taW5fZ3Jvc3NQYXkpOwogICAgbWlubWF4LT5taW5fc3RhdGVUYXggPSBDQUxDX01JTihlbXAtPnN0YXRlVGF4LCBtaW5tYXgtPm1pbl9zdGF0ZVRheCk7CiAgICBtaW5tYXgtPm1pbl9mZWRUYXggPSBDQUxDX01JTihlbXAtPmZlZFRheCwgbWlubWF4LT5taW5fZmVkVGF4KTsKICAgIG1pbm1heC0+bWluX25ldFBheSA9IENBTENfTUlOKGVtcC0+bmV0UGF5LCBtaW5tYXgtPm1pbl9uZXRQYXkpOwoKICAgIC8vIFVwZGF0ZSBtYXggdmFsdWVzCiAgICBtaW5tYXgtPm1heF93YWdlUmF0ZSA9IENBTENfTUFYKGVtcC0+d2FnZVJhdGUsIG1pbm1heC0+bWF4X3dhZ2VSYXRlKTsKICAgIG1pbm1heC0+bWF4X2hvdXJzID0gQ0FMQ19NQVgoZW1wLT5ob3VycywgbWlubWF4LT5tYXhfaG91cnMpOwogICAgbWlubWF4LT5tYXhfb3ZlcnRpbWVIcnMgPSBDQUxDX01BWChlbXAtPm92ZXJ0aW1lSHJzLCBtaW5tYXgtPm1heF9vdmVydGltZUhycyk7CiAgICBtaW5tYXgtPm1heF9ncm9zc1BheSA9IENBTENfTUFYKGVtcC0+Z3Jvc3NQYXksIG1pbm1heC0+bWF4X2dyb3NzUGF5KTsKICAgIG1pbm1heC0+bWF4X3N0YXRlVGF4ID0gQ0FMQ19NQVgoZW1wLT5zdGF0ZVRheCwgbWlubWF4LT5tYXhfc3RhdGVUYXgpOwogICAgbWlubWF4LT5tYXhfZmVkVGF4ID0gQ0FMQ19NQVgoZW1wLT5mZWRUYXgsIG1pbm1heC0+bWF4X2ZlZFRheCk7CiAgICBtaW5tYXgtPm1heF9uZXRQYXkgPSBDQUxDX01BWChlbXAtPm5ldFBheSwgbWlubWF4LT5tYXhfbmV0UGF5KTsKfQoKdm9pZCBwcmludEhlYWRlcih2b2lkKQp7CiAgICBwcmludGYoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKICAgIHByaW50ZigiTmFtZSAgICAgICAgICAgICAgIENsb2NrIyAgIFdhZ2UgICBIb3VycyAgT1QgICAgIEdyb3NzICAgU3RhdGUgIEZlZCAgICBOZXRcbiIpOwogICAgcHJpbnRmKCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhvdXJzICBQYXkgICAgIFRheCAgICBUYXggICAgUGF5XG4iKTsKICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwp9Cgp2b2lkIHByaW50RW1wbG95ZWVEYXRhKEVNUExPWUVFICogZW1wKQp7CiAgICBwcmludGYoIiUtMTBzICUtMTBzICUwNmxpICAlNS4yZiAgJTUuMWYgICU1LjFmICAlNy4yZiAgJTYuMmYgICU2LjJmICAlNy4yZlxuIiwKICAgICAgICBlbXAtPmVtcE5hbWUuZmlyc3ROYW1lLAogICAgICAgIGVtcC0+ZW1wTmFtZS5sYXN0TmFtZSwKICAgICAgICBlbXAtPmNsb2NrTnVtYmVyLAogICAgICAgIGVtcC0+d2FnZVJhdGUsCiAgICAgICAgZW1wLT5ob3VycywKICAgICAgICBlbXAtPm92ZXJ0aW1lSHJzLAogICAgICAgIGVtcC0+Z3Jvc3NQYXksCiAgICAgICAgZW1wLT5zdGF0ZVRheCwKICAgICAgICBlbXAtPmZlZFRheCwKICAgICAgICBlbXAtPm5ldFBheSk7Cn0KCnZvaWQgcHJpbnRUb3RhbHMoVE9UQUxTIHRvdGFscywgaW50IGNvdW50KQp7CiAgICBwcmludGYoIlxuQXZlcmFnZXM6ICAgICAgICAgIik7CiAgICBwcmludGYoIiAgICAgICAgJTUuMmYgICU1LjFmICAlNS4xZiAgJTcuMmYgICU2LjJmICAlNi4yZiAgJTcuMmZcbiIsCiAgICAgICAgdG90YWxzLnRvdGFsX3dhZ2VSYXRlIC8gY291bnQsCiAgICAgICAgdG90YWxzLnRvdGFsX2hvdXJzIC8gY291bnQsCiAgICAgICAgdG90YWxzLnRvdGFsX292ZXJ0aW1lSHJzIC8gY291bnQsCiAgICAgICAgdG90YWxzLnRvdGFsX2dyb3NzUGF5IC8gY291bnQsCiAgICAgICAgdG90YWxzLnRvdGFsX3N0YXRlVGF4IC8gY291bnQsCiAgICAgICAgdG90YWxzLnRvdGFsX2ZlZFRheCAvIGNvdW50LAogICAgICAgIHRvdGFscy50b3RhbF9uZXRQYXkgLyBjb3VudCk7Cn0KCnZvaWQgcHJpbnRNaW5NYXgoTUlOX01BWCBtaW5tYXgpCnsKICAgIHByaW50ZigiXG5NaW5pbXVtczogICAgICAgICAiKTsKICAgIHByaW50ZigiICAgICAgICAlNS4yZiAgJTUuMWYgICU1LjFmICAlNy4yZiAgJTYuMmYgICU2LjJmICAlNy4yZlxuIiwKICAgICAgICBtaW5tYXgubWluX3dhZ2VSYXRlLAogICAgICAgIG1pbm1heC5taW5faG91cnMsCiAgICAgICAgbWlubWF4Lm1pbl9vdmVydGltZUhycywKICAgICAgICBtaW5tYXgubWluX2dyb3NzUGF5LAogICAgICAgIG1pbm1heC5taW5fc3RhdGVUYXgsCiAgICAgICAgbWlubWF4Lm1pbl9mZWRUYXgsCiAgICAgICAgbWlubWF4Lm1pbl9uZXRQYXkpOwoKICAgIHByaW50ZigiTWF4aW11bXM6ICAgICAgICAgIik7CiAgICBwcmludGYoIiAgICAgICAgJTUuMmYgICU1LjFmICAlNS4xZiAgJTcuMmYgICU2LjJmICAlNi4yZiAgJTcuMmZcbiIsCiAgICAgICAgbWlubWF4Lm1heF93YWdlUmF0ZSwKICAgICAgICBtaW5tYXgubWF4X2hvdXJzLAogICAgICAgIG1pbm1heC5tYXhfb3ZlcnRpbWVIcnMsCiAgICAgICAgbWlubWF4Lm1heF9ncm9zc1BheSwKICAgICAgICBtaW5tYXgubWF4X3N0YXRlVGF4LAogICAgICAgIG1pbm1heC5tYXhfZmVkVGF4LAogICAgICAgIG1pbm1heC5tYXhfbmV0UGF5KTsKfQo=