//********************************************************
//
// 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>
#include <stdlib.h>
// 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 NY_TAX_RATE 0.08
#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)
#define CALC_FED_TAX(thePay) (thePay * FED_TAX_RATE)
#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))
#define CALC_MIN(theValue, currentMin) ((theValue < currentMin) ? theValue : currentMin)
#define CALC_MAX(theValue, currentMax) ((theValue > currentMax) ? theValue : currentMax)
struct name {
char firstName[ FIRST_NAME_SIZE] ;
char lastName [ LAST_NAME_SIZE] ;
} ;
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;
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;
typedef struct min_max {
float min_wageRate, min_hours, min_overtimeHrs, min_grossPay, min_stateTax, min_fedTax, min_netPay;
float max_wageRate, max_hours, max_overtimeHrs, max_grossPay, max_stateTax, max_fedTax, max_netPay;
} MIN_MAX;
EMPLOYEE
* createEmployee
( char first
[ ] , char last
[ ] , char state
[ ] , long int clock , float wage
, float hours
) ; void printHeader( void ) ;
void computePayroll( EMPLOYEE * emp, TOTALS * totals, MIN_MAX * minmax) ;
void printEmployeeData( EMPLOYEE * emp) ;
void printTotals( TOTALS totals, int count) ;
void printMinMax( MIN_MAX minmax) ;
int main( void ) {
EMPLOYEE * head = NULL, * current = NULL;
TOTALS totals = { 0 } ;
MIN_MAX minmax = { 999999 , 999999 , 999999 , 999999 , 999999 , 999999 , 999999 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
head = createEmployee( "Connie" , "Cobol" , "MA" , 98401 , 10.60 , 51.0 ) ;
head-> next = createEmployee( "Mary" , "Apl" , "NH" , 526488 , 9.75 , 42.5 ) ;
head-> next-> next = createEmployee( "Frank" , "Fortran" , "VT" , 765349 , 10.50 , 37.0 ) ;
head-> next-> next-> next = createEmployee( "Jeff" , "Ada" , "NY" , 34645 , 12.25 , 45 ) ;
head-> next-> next-> next-> next = createEmployee( "Anton" , "Pascal" , "CA" , 127615 , 8.35 , 40.0 ) ;
printf ( "\n *** Pay Calculator ***\n \n " ) ; printHeader( ) ;
current = head;
int count = 0 ;
while ( current != NULL) {
computePayroll( current, & totals, & minmax) ;
printEmployeeData( current) ;
current = current-> next;
count++;
}
printf ( "---------------------------------------------------------------------------------\n " ) ; printf ( "Totals: %5.2f %6.1f %5.1f %7.2f %7.2f %7.2f %8.2f\n " , totals.total_wageRate , totals.total_hours , totals.total_overtimeHrs ,
totals.total_grossPay , totals.total_stateTax , totals.total_fedTax , totals.total_netPay ) ;
printTotals( totals, count) ;
printMinMax( minmax) ;
printf ( "\n \n The total employees processed was: %d\n \n " , count
) ; printf ( " *** End of Program ***\n " ) ; return 0 ;
}
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 regPay = CALC_NORMAL_PAY( emp-> wageRate, emp-> hours, emp-> overtimeHrs) ;
float otPay = CALC_OT_PAY( emp-> wageRate, emp-> overtimeHrs) ;
emp-> grossPay = regPay + otPay;
float rate;
if ( strcmp ( emp
-> taxState
, "MA" ) == 0 ) rate
= MA_TAX_RATE
; else if ( strcmp ( emp
-> taxState
, "NH" ) == 0 ) rate
= NH_TAX_RATE
; else if ( strcmp ( emp
-> taxState
, "VT" ) == 0 ) rate
= VT_TAX_RATE
; else if ( strcmp ( emp
-> taxState
, "CA" ) == 0 ) rate
= CA_TAX_RATE
; else if ( strcmp ( emp
-> taxState
, "NY" ) == 0 ) rate
= NY_TAX_RATE
; else rate = DEFAULT_STATE_TAX_RATE;
emp-> stateTax = CALC_STATE_TAX( emp-> grossPay, rate) ;
emp-> fedTax = CALC_FED_TAX( emp-> grossPay) ;
emp-> netPay = CALC_NET_PAY( emp-> grossPay, emp-> stateTax, emp-> fedTax) ;
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;
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) ;
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 Tax Clock# Wage Hours OT Gross State Fed Net\n " ) ; printf ( " State Pay Tax Tax Pay\n " ) ; printf ( "---------------------------------------------------------------------------------\n " ) ; }
void printEmployeeData( EMPLOYEE * emp) {
printf ( "%-10s %-10s %-2s %06li %5.2f %5.1f %5.1f %7.2f %6.2f %6.2f %8.2f\n " , emp-> empName.firstName , emp-> empName.lastName , emp-> taxState,
emp-> clockNumber, emp-> wageRate, emp-> hours, emp-> overtimeHrs,
emp-> grossPay, emp-> stateTax, emp-> fedTax, emp-> netPay) ;
}
void printTotals( TOTALS totals, int count) {
printf ( "Averages: %5.2f %6.1f %5.1f %7.2f %7.2f %7.2f %8.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 ( "Minimum: %5.2f %6.1f %5.1f %7.2f %7.2f %7.2f %8.2f\n " , minmax.min_wageRate , minmax.min_hours , minmax.min_overtimeHrs ,
minmax.min_grossPay , minmax.min_stateTax , minmax.min_fedTax , minmax.min_netPay ) ;
printf ( "Maximum: %5.2f %6.1f %5.1f %7.2f %7.2f %7.2f %8.2f\n " , minmax.max_wageRate , minmax.max_hours , minmax.max_overtimeHrs ,
minmax.max_grossPay , minmax.max_stateTax , minmax.max_fedTax , minmax.max_netPay ) ;
}
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDEwIC0gTGlua2VkIExpc3RzLCBUeXBlZGVmLCBhbmQgTWFjcm9zCi8vCi8vIE5hbWU6IDxLeWxlIE1lcnJpaGV3PgovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgPFNwcmluZyAyMDI1PgovLwovLyBEYXRlOiA8QXByaWwgMTcsMjAyNT4KLy8KLy8gRGVzY3JpcHRpb246IFByb2dyYW0gd2hpY2ggZGV0ZXJtaW5lcyBvdmVydGltZSBhbmQgCi8vIGdyb3NzIHBheSBmb3IgYSBzZXQgb2YgZW1wbG95ZWVzIHdpdGggb3V0cHV0cyBzZW50IAovLyB0byBzdGFuZGFyZCBvdXRwdXQgKHRoZSBzY3JlZW4pLgovLwovLyBUaGlzIGFzc2lnbm1lbnQgYWxzbyBhZGRzIHRoZSBlbXBsb3llZSBuYW1lLCB0aGVpciB0YXggc3RhdGUsCi8vIGFuZCBjYWxjdWxhdGVzIHRoZSBzdGF0ZSB0YXgsIGZlZGVyYWwgdGF4LCBhbmQgbmV0IHBheS4gICBJdAovLyBhbHNvIGNhbGN1bGF0ZXMgdG90YWxzLCBhdmVyYWdlcywgbWluaW11bSwgYW5kIG1heGltdW0gdmFsdWVzLgovLwovLyBBcnJheSBhbmQgU3RydWN0dXJlIHJlZmVyZW5jZXMgaGF2ZSBhbGwgYmVlbiByZXBsYWNlZCB3aXRoCi8vIHBvaW50ZXIgcmVmZXJlbmNlcyB0byBzcGVlZCB1cCB0aGUgcHJvY2Vzc2luZyBvZiB0aGlzIGNvZGUuCi8vIEEgbGlua2VkIGxpc3QgaGFzIGJlZW4gY3JlYXRlZCBhbmQgZGVwbG95ZWQgdG8gZHluYW1pY2FsbHkKLy8gYWxsb2NhdGUgYW5kIHByb2Nlc3MgZW1wbG95ZWVzIGFzIG5lZWRlZC4KLy8KLy8gSXQgd2lsbCBhbHNvIHRha2UgYWR2YW50YWdlIG9mIHRoZSBDIFByZXByb2Nlc3NvciBmZWF0dXJlcywKLy8gaW4gcGFydGljdWxhciB3aXRoIHVzaW5nIG1hY3JvcywgYW5kIHdpbGwgcmVwbGFjZSBhbGwgCi8vIHN0cnVjdCB0eXBlIHJlZmVyZW5jZXMgaW4gdGhlIGNvZGUgd2l0aCBhIHR5cGVkZWYgYWxpYXMKLy8gcmVmZXJlbmNlLgovLwovLyBDYWxsIGJ5IFJlZmVyZW5jZSBkZXNpZ24gKHVzaW5nIHBvaW50ZXJzKQovLwovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgovLyBuZWNlc3NhcnkgaGVhZGVyIGZpbGVzCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+Ci8vIGRlZmluZSBjb25zdGFudHMKI2RlZmluZSBTVERfSE9VUlMgNDAuMAojZGVmaW5lIE9UX1JBVEUgMS41CiNkZWZpbmUgTUFfVEFYX1JBVEUgMC4wNQojZGVmaW5lIE5IX1RBWF9SQVRFIDAuMAojZGVmaW5lIFZUX1RBWF9SQVRFIDAuMDYKI2RlZmluZSBDQV9UQVhfUkFURSAwLjA3CiNkZWZpbmUgTllfVEFYX1JBVEUgMC4wOAojZGVmaW5lIERFRkFVTFRfU1RBVEVfVEFYX1JBVEUgMC4wOAojZGVmaW5lIE5BTUVfU0laRSAyMAojZGVmaW5lIFRBWF9TVEFURV9TSVpFIDMKI2RlZmluZSBGRURfVEFYX1JBVEUgMC4yNQojZGVmaW5lIEZJUlNUX05BTUVfU0laRSAxMAojZGVmaW5lIExBU1RfTkFNRV9TSVpFIDEwCi8vIGRlZmluZSBtYWNyb3MKI2RlZmluZSBDQUxDX09UX0hPVVJTKHRoZUhvdXJzKSAoKHRoZUhvdXJzID4gU1REX0hPVVJTKSA/IHRoZUhvdXJzIC0gU1REX0hPVVJTIDogMCkKI2RlZmluZSBDQUxDX1NUQVRFX1RBWCh0aGVQYXksdGhlU3RhdGVUYXhSYXRlKSAodGhlUGF5ICogdGhlU3RhdGVUYXhSYXRlKQojZGVmaW5lIENBTENfRkVEX1RBWCh0aGVQYXkpICh0aGVQYXkgKiBGRURfVEFYX1JBVEUpCiNkZWZpbmUgQ0FMQ19ORVRfUEFZKHRoZVBheSx0aGVTdGF0ZVRheCx0aGVGZWRUYXgpICh0aGVQYXkgLSAodGhlU3RhdGVUYXggKyB0aGVGZWRUYXgpKQojZGVmaW5lIENBTENfTk9STUFMX1BBWSh0aGVXYWdlUmF0ZSx0aGVIb3Vycyx0aGVPdmVydGltZUhycykgKHRoZVdhZ2VSYXRlICogKHRoZUhvdXJzIC0gdGhlT3ZlcnRpbWVIcnMpKQojZGVmaW5lIENBTENfT1RfUEFZKHRoZVdhZ2VSYXRlLHRoZU92ZXJ0aW1lSHJzKSAodGhlT3ZlcnRpbWVIcnMgKiAoT1RfUkFURSAqIHRoZVdhZ2VSYXRlKSkKI2RlZmluZSBDQUxDX01JTih0aGVWYWx1ZSwgY3VycmVudE1pbikgKCh0aGVWYWx1ZSA8IGN1cnJlbnRNaW4pID8gdGhlVmFsdWUgOiBjdXJyZW50TWluKQojZGVmaW5lIENBTENfTUFYKHRoZVZhbHVlLCBjdXJyZW50TWF4KSAoKHRoZVZhbHVlID4gY3VycmVudE1heCkgPyB0aGVWYWx1ZSA6IGN1cnJlbnRNYXgpCgpzdHJ1Y3QgbmFtZSB7CiAgICBjaGFyIGZpcnN0TmFtZVtGSVJTVF9OQU1FX1NJWkVdOwogICAgY2hhciBsYXN0TmFtZSBbTEFTVF9OQU1FX1NJWkVdOwp9OwoKdHlwZWRlZiBzdHJ1Y3QgZW1wbG95ZWUgewogICAgc3RydWN0IG5hbWUgZW1wTmFtZTsKICAgIGNoYXIgdGF4U3RhdGVbVEFYX1NUQVRFX1NJWkVdOwogICAgbG9uZyBpbnQgY2xvY2tOdW1iZXI7CiAgICBmbG9hdCB3YWdlUmF0ZTsKICAgIGZsb2F0IGhvdXJzOwogICAgZmxvYXQgb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBncm9zc1BheTsKICAgIGZsb2F0IHN0YXRlVGF4OwogICAgZmxvYXQgZmVkVGF4OwogICAgZmxvYXQgbmV0UGF5OwogICAgc3RydWN0IGVtcGxveWVlICogbmV4dDsKfSBFTVBMT1lFRTsKCnR5cGVkZWYgc3RydWN0IHRvdGFscyB7CiAgICBmbG9hdCB0b3RhbF93YWdlUmF0ZTsKICAgIGZsb2F0IHRvdGFsX2hvdXJzOwogICAgZmxvYXQgdG90YWxfb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCB0b3RhbF9ncm9zc1BheTsKICAgIGZsb2F0IHRvdGFsX3N0YXRlVGF4OwogICAgZmxvYXQgdG90YWxfZmVkVGF4OwogICAgZmxvYXQgdG90YWxfbmV0UGF5Owp9IFRPVEFMUzsKCnR5cGVkZWYgc3RydWN0IG1pbl9tYXggewogICAgZmxvYXQgbWluX3dhZ2VSYXRlLCBtaW5faG91cnMsIG1pbl9vdmVydGltZUhycywgbWluX2dyb3NzUGF5LCBtaW5fc3RhdGVUYXgsIG1pbl9mZWRUYXgsIG1pbl9uZXRQYXk7CiAgICBmbG9hdCBtYXhfd2FnZVJhdGUsIG1heF9ob3VycywgbWF4X292ZXJ0aW1lSHJzLCBtYXhfZ3Jvc3NQYXksIG1heF9zdGF0ZVRheCwgbWF4X2ZlZFRheCwgbWF4X25ldFBheTsKfSBNSU5fTUFYOwoKRU1QTE9ZRUUgKiBjcmVhdGVFbXBsb3llZShjaGFyIGZpcnN0W10sIGNoYXIgbGFzdFtdLCBjaGFyIHN0YXRlW10sIGxvbmcgaW50IGNsb2NrLCBmbG9hdCB3YWdlLCBmbG9hdCBob3Vycyk7CnZvaWQgcHJpbnRIZWFkZXIodm9pZCk7CnZvaWQgY29tcHV0ZVBheXJvbGwoRU1QTE9ZRUUgKiBlbXAsIFRPVEFMUyAqIHRvdGFscywgTUlOX01BWCAqIG1pbm1heCk7CnZvaWQgcHJpbnRFbXBsb3llZURhdGEoRU1QTE9ZRUUgKiBlbXApOwp2b2lkIHByaW50VG90YWxzKFRPVEFMUyB0b3RhbHMsIGludCBjb3VudCk7CnZvaWQgcHJpbnRNaW5NYXgoTUlOX01BWCBtaW5tYXgpOwoKaW50IG1haW4odm9pZCkgewogICAgRU1QTE9ZRUUgKiBoZWFkID0gTlVMTCwgKiBjdXJyZW50ID0gTlVMTDsKICAgIFRPVEFMUyB0b3RhbHMgPSB7MH07CiAgICBNSU5fTUFYIG1pbm1heCA9IHs5OTk5OTksOTk5OTk5LDk5OTk5OSw5OTk5OTksOTk5OTk5LDk5OTk5OSw5OTk5OTksMCwwLDAsMCwwLDAsMH07CgogICAgaGVhZCA9IGNyZWF0ZUVtcGxveWVlKCJDb25uaWUiLCJDb2JvbCIsIk1BIiw5ODQwMSwxMC42MCw1MS4wKTsKICAgIGhlYWQtPm5leHQgPSBjcmVhdGVFbXBsb3llZSgiTWFyeSIsIkFwbCIsIk5IIiw1MjY0ODgsOS43NSw0Mi41KTsKICAgIGhlYWQtPm5leHQtPm5leHQgPSBjcmVhdGVFbXBsb3llZSgiRnJhbmsiLCJGb3J0cmFuIiwiVlQiLDc2NTM0OSwxMC41MCwzNy4wKTsKICAgIGhlYWQtPm5leHQtPm5leHQtPm5leHQgPSBjcmVhdGVFbXBsb3llZSgiSmVmZiIsIkFkYSIsIk5ZIiwzNDY0NSwxMi4yNSw0NSk7CiAgICBoZWFkLT5uZXh0LT5uZXh0LT5uZXh0LT5uZXh0ID0gY3JlYXRlRW1wbG95ZWUoIkFudG9uIiwiUGFzY2FsIiwiQ0EiLDEyNzYxNSw4LjM1LDQwLjApOwoKICAgIHByaW50ZigiXG4gKioqIFBheSBDYWxjdWxhdG9yICoqKlxuXG4iKTsKICAgIHByaW50SGVhZGVyKCk7CiAgICBjdXJyZW50ID0gaGVhZDsKICAgIGludCBjb3VudCA9IDA7CiAgICB3aGlsZSAoY3VycmVudCAhPSBOVUxMKSB7CiAgICAgICAgY29tcHV0ZVBheXJvbGwoY3VycmVudCwgJnRvdGFscywgJm1pbm1heCk7CiAgICAgICAgcHJpbnRFbXBsb3llZURhdGEoY3VycmVudCk7CiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQtPm5leHQ7CiAgICAgICAgY291bnQrKzsKICAgIH0KICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKICAgIHByaW50ZigiVG90YWxzOiAgICAgICAgICAgICAgICAgICAgICAgICAgJTUuMmYgJTYuMWYgJTUuMWYgJTcuMmYgJTcuMmYgJTcuMmYgJTguMmZcbiIsCiAgICAgICAgICAgdG90YWxzLnRvdGFsX3dhZ2VSYXRlLCB0b3RhbHMudG90YWxfaG91cnMsIHRvdGFscy50b3RhbF9vdmVydGltZUhycywKICAgICAgICAgICB0b3RhbHMudG90YWxfZ3Jvc3NQYXksIHRvdGFscy50b3RhbF9zdGF0ZVRheCwgdG90YWxzLnRvdGFsX2ZlZFRheCwgdG90YWxzLnRvdGFsX25ldFBheSk7CiAgICBwcmludFRvdGFscyh0b3RhbHMsIGNvdW50KTsKICAgIHByaW50TWluTWF4KG1pbm1heCk7CiAgICBwcmludGYoIlxuXG5UaGUgdG90YWwgZW1wbG95ZWVzIHByb2Nlc3NlZCB3YXM6ICVkXG5cbiIsIGNvdW50KTsKICAgIHByaW50ZigiICoqKiBFbmQgb2YgUHJvZ3JhbSAqKipcbiIpOwogICAgcmV0dXJuIDA7Cn0KCkVNUExPWUVFICogY3JlYXRlRW1wbG95ZWUoY2hhciBmaXJzdFtdLCBjaGFyIGxhc3RbXSwgY2hhciBzdGF0ZVtdLCBsb25nIGludCBjbG9jaywgZmxvYXQgd2FnZSwgZmxvYXQgaG91cnMpIHsKICAgIEVNUExPWUVFICogZW1wID0gKEVNUExPWUVFICopIG1hbGxvYyhzaXplb2YoRU1QTE9ZRUUpKTsKICAgIHN0cmNweShlbXAtPmVtcE5hbWUuZmlyc3ROYW1lLCBmaXJzdCk7CiAgICBzdHJjcHkoZW1wLT5lbXBOYW1lLmxhc3ROYW1lLCBsYXN0KTsKICAgIHN0cmNweShlbXAtPnRheFN0YXRlLCBzdGF0ZSk7CiAgICBlbXAtPmNsb2NrTnVtYmVyID0gY2xvY2s7CiAgICBlbXAtPndhZ2VSYXRlID0gd2FnZTsKICAgIGVtcC0+aG91cnMgPSBob3VyczsKICAgIGVtcC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gZW1wOwp9Cgp2b2lkIGNvbXB1dGVQYXlyb2xsKEVNUExPWUVFICogZW1wLCBUT1RBTFMgKiB0b3RhbHMsIE1JTl9NQVggKiBtaW5tYXgpIHsKICAgIGVtcC0+b3ZlcnRpbWVIcnMgPSBDQUxDX09UX0hPVVJTKGVtcC0+aG91cnMpOwogICAgZmxvYXQgcmVnUGF5ID0gQ0FMQ19OT1JNQUxfUEFZKGVtcC0+d2FnZVJhdGUsIGVtcC0+aG91cnMsIGVtcC0+b3ZlcnRpbWVIcnMpOwogICAgZmxvYXQgb3RQYXkgPSBDQUxDX09UX1BBWShlbXAtPndhZ2VSYXRlLCBlbXAtPm92ZXJ0aW1lSHJzKTsKICAgIGVtcC0+Z3Jvc3NQYXkgPSByZWdQYXkgKyBvdFBheTsKCiAgICBmbG9hdCByYXRlOwogICAgaWYgKHN0cmNtcChlbXAtPnRheFN0YXRlLCAiTUEiKSA9PSAwKSByYXRlID0gTUFfVEFYX1JBVEU7CiAgICBlbHNlIGlmIChzdHJjbXAoZW1wLT50YXhTdGF0ZSwgIk5IIikgPT0gMCkgcmF0ZSA9IE5IX1RBWF9SQVRFOwogICAgZWxzZSBpZiAoc3RyY21wKGVtcC0+dGF4U3RhdGUsICJWVCIpID09IDApIHJhdGUgPSBWVF9UQVhfUkFURTsKICAgIGVsc2UgaWYgKHN0cmNtcChlbXAtPnRheFN0YXRlLCAiQ0EiKSA9PSAwKSByYXRlID0gQ0FfVEFYX1JBVEU7CiAgICBlbHNlIGlmIChzdHJjbXAoZW1wLT50YXhTdGF0ZSwgIk5ZIikgPT0gMCkgcmF0ZSA9IE5ZX1RBWF9SQVRFOwogICAgZWxzZSByYXRlID0gREVGQVVMVF9TVEFURV9UQVhfUkFURTsKCiAgICBlbXAtPnN0YXRlVGF4ID0gQ0FMQ19TVEFURV9UQVgoZW1wLT5ncm9zc1BheSwgcmF0ZSk7CiAgICBlbXAtPmZlZFRheCA9IENBTENfRkVEX1RBWChlbXAtPmdyb3NzUGF5KTsKICAgIGVtcC0+bmV0UGF5ID0gQ0FMQ19ORVRfUEFZKGVtcC0+Z3Jvc3NQYXksIGVtcC0+c3RhdGVUYXgsIGVtcC0+ZmVkVGF4KTsKCiAgICB0b3RhbHMtPnRvdGFsX3dhZ2VSYXRlICs9IGVtcC0+d2FnZVJhdGU7CiAgICB0b3RhbHMtPnRvdGFsX2hvdXJzICs9IGVtcC0+aG91cnM7CiAgICB0b3RhbHMtPnRvdGFsX292ZXJ0aW1lSHJzICs9IGVtcC0+b3ZlcnRpbWVIcnM7CiAgICB0b3RhbHMtPnRvdGFsX2dyb3NzUGF5ICs9IGVtcC0+Z3Jvc3NQYXk7CiAgICB0b3RhbHMtPnRvdGFsX3N0YXRlVGF4ICs9IGVtcC0+c3RhdGVUYXg7CiAgICB0b3RhbHMtPnRvdGFsX2ZlZFRheCArPSBlbXAtPmZlZFRheDsKICAgIHRvdGFscy0+dG90YWxfbmV0UGF5ICs9IGVtcC0+bmV0UGF5OwoKICAgIG1pbm1heC0+bWluX3dhZ2VSYXRlID0gQ0FMQ19NSU4oZW1wLT53YWdlUmF0ZSwgbWlubWF4LT5taW5fd2FnZVJhdGUpOwogICAgbWlubWF4LT5taW5faG91cnMgPSBDQUxDX01JTihlbXAtPmhvdXJzLCBtaW5tYXgtPm1pbl9ob3Vycyk7CiAgICBtaW5tYXgtPm1pbl9vdmVydGltZUhycyA9IENBTENfTUlOKGVtcC0+b3ZlcnRpbWVIcnMsIG1pbm1heC0+bWluX292ZXJ0aW1lSHJzKTsKICAgIG1pbm1heC0+bWluX2dyb3NzUGF5ID0gQ0FMQ19NSU4oZW1wLT5ncm9zc1BheSwgbWlubWF4LT5taW5fZ3Jvc3NQYXkpOwogICAgbWlubWF4LT5taW5fc3RhdGVUYXggPSBDQUxDX01JTihlbXAtPnN0YXRlVGF4LCBtaW5tYXgtPm1pbl9zdGF0ZVRheCk7CiAgICBtaW5tYXgtPm1pbl9mZWRUYXggPSBDQUxDX01JTihlbXAtPmZlZFRheCwgbWlubWF4LT5taW5fZmVkVGF4KTsKICAgIG1pbm1heC0+bWluX25ldFBheSA9IENBTENfTUlOKGVtcC0+bmV0UGF5LCBtaW5tYXgtPm1pbl9uZXRQYXkpOwoKICAgIG1pbm1heC0+bWF4X3dhZ2VSYXRlID0gQ0FMQ19NQVgoZW1wLT53YWdlUmF0ZSwgbWlubWF4LT5tYXhfd2FnZVJhdGUpOwogICAgbWlubWF4LT5tYXhfaG91cnMgPSBDQUxDX01BWChlbXAtPmhvdXJzLCBtaW5tYXgtPm1heF9ob3Vycyk7CiAgICBtaW5tYXgtPm1heF9vdmVydGltZUhycyA9IENBTENfTUFYKGVtcC0+b3ZlcnRpbWVIcnMsIG1pbm1heC0+bWF4X292ZXJ0aW1lSHJzKTsKICAgIG1pbm1heC0+bWF4X2dyb3NzUGF5ID0gQ0FMQ19NQVgoZW1wLT5ncm9zc1BheSwgbWlubWF4LT5tYXhfZ3Jvc3NQYXkpOwogICAgbWlubWF4LT5tYXhfc3RhdGVUYXggPSBDQUxDX01BWChlbXAtPnN0YXRlVGF4LCBtaW5tYXgtPm1heF9zdGF0ZVRheCk7CiAgICBtaW5tYXgtPm1heF9mZWRUYXggPSBDQUxDX01BWChlbXAtPmZlZFRheCwgbWlubWF4LT5tYXhfZmVkVGF4KTsKICAgIG1pbm1heC0+bWF4X25ldFBheSA9IENBTENfTUFYKGVtcC0+bmV0UGF5LCBtaW5tYXgtPm1heF9uZXRQYXkpOwp9Cgp2b2lkIHByaW50SGVhZGVyKHZvaWQpIHsKICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKICAgIHByaW50ZigiTmFtZSAgICAgICAgICAgICAgICBUYXggIENsb2NrIyAgV2FnZSAgIEhvdXJzICBPVCAgIEdyb3NzICAgU3RhdGUgIEZlZCAgICAgIE5ldFxuIik7CiAgICBwcmludGYoIiAgICAgICAgICAgICAgICAgICAgU3RhdGUgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXkgICAgIFRheCAgICBUYXggICAgICBQYXlcbiIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwp9Cgp2b2lkIHByaW50RW1wbG95ZWVEYXRhKEVNUExPWUVFICogZW1wKSB7CiAgICBwcmludGYoIiUtMTBzICUtMTBzICAlLTJzICAlMDZsaSAgJTUuMmYgICU1LjFmICU1LjFmICAlNy4yZiAgJTYuMmYgICU2LjJmICAlOC4yZlxuIiwKICAgICAgICAgICBlbXAtPmVtcE5hbWUuZmlyc3ROYW1lLCBlbXAtPmVtcE5hbWUubGFzdE5hbWUsIGVtcC0+dGF4U3RhdGUsCiAgICAgICAgICAgZW1wLT5jbG9ja051bWJlciwgZW1wLT53YWdlUmF0ZSwgZW1wLT5ob3VycywgZW1wLT5vdmVydGltZUhycywKICAgICAgICAgICBlbXAtPmdyb3NzUGF5LCBlbXAtPnN0YXRlVGF4LCBlbXAtPmZlZFRheCwgZW1wLT5uZXRQYXkpOwp9Cgp2b2lkIHByaW50VG90YWxzKFRPVEFMUyB0b3RhbHMsIGludCBjb3VudCkgewogICAgcHJpbnRmKCJBdmVyYWdlczogICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNi4xZiAlNS4xZiAlNy4yZiAlNy4yZiAlNy4yZiAlOC4yZlxuIiwKICAgICAgICAgICB0b3RhbHMudG90YWxfd2FnZVJhdGUgLyBjb3VudCwgdG90YWxzLnRvdGFsX2hvdXJzIC8gY291bnQsCiAgICAgICAgICAgdG90YWxzLnRvdGFsX292ZXJ0aW1lSHJzIC8gY291bnQsIHRvdGFscy50b3RhbF9ncm9zc1BheSAvIGNvdW50LAogICAgICAgICAgIHRvdGFscy50b3RhbF9zdGF0ZVRheCAvIGNvdW50LCB0b3RhbHMudG90YWxfZmVkVGF4IC8gY291bnQsCiAgICAgICAgICAgdG90YWxzLnRvdGFsX25ldFBheSAvIGNvdW50KTsKfQoKdm9pZCBwcmludE1pbk1heChNSU5fTUFYIG1pbm1heCkgewogICAgcHJpbnRmKCJNaW5pbXVtOiAgICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNi4xZiAlNS4xZiAlNy4yZiAlNy4yZiAlNy4yZiAlOC4yZlxuIiwKICAgICAgICAgICBtaW5tYXgubWluX3dhZ2VSYXRlLCBtaW5tYXgubWluX2hvdXJzLCBtaW5tYXgubWluX292ZXJ0aW1lSHJzLAogICAgICAgICAgIG1pbm1heC5taW5fZ3Jvc3NQYXksIG1pbm1heC5taW5fc3RhdGVUYXgsIG1pbm1heC5taW5fZmVkVGF4LCBtaW5tYXgubWluX25ldFBheSk7CiAgICBwcmludGYoIk1heGltdW06ICAgICAgICAgICAgICAgICAgICAgICAgICU1LjJmICU2LjFmICU1LjFmICU3LjJmICU3LjJmICU3LjJmICU4LjJmXG4iLAogICAgICAgICAgIG1pbm1heC5tYXhfd2FnZVJhdGUsIG1pbm1heC5tYXhfaG91cnMsIG1pbm1heC5tYXhfb3ZlcnRpbWVIcnMsCiAgICAgICAgICAgbWlubWF4Lm1heF9ncm9zc1BheSwgbWlubWF4Lm1heF9zdGF0ZVRheCwgbWlubWF4Lm1heF9mZWRUYXgsIG1pbm1heC5tYXhfbmV0UGF5KTsKfQo=