//********************************************************
//
// Assignment 10 - Linked Lists, Typedef, and Macros
//
// Name: <replace with your name>
//
// Class: C Programming, <replace with Semester and Year>
//
// Date: <replace with the current date>
//
// 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
//---------------- MACROS ----------------
#define CALC_OT_HOURS(h) ((h > STD_HOURS) ? (h - STD_HOURS) : 0)
#define CALC_STATE_TAX(pay, rate) ((pay) * (rate))
#define CALC_FED_TAX(pay) ((pay) * FED_TAX_RATE)
#define CALC_NET_PAY(pay, st, ft) ((pay) - ((st) + (ft)))
#define CALC_NORMAL_PAY(w, h, ot) ((w) * ((h) - (ot)))
#define CALC_OT_PAY(w, ot) ((ot) * ((w) * OT_RATE))
#define CALC_MIN(val, min) ((val < min) ? val : min)
#define CALC_MAX(val, max) ((val > max) ? val : max)
//---------------- STRUCTURES ----------------
typedef struct name {
char firstName[ FIRST_NAME_SIZE] ;
char lastName[ FIRST_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 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;
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;
//---------------- PROTOTYPES ----------------
EMPLOYEE * getEmpData( void ) ;
int isEmployeeSize( EMPLOYEE * head_ptr) ;
void calcOvertimeHrs( EMPLOYEE * head_ptr) ;
void calcGrossPay( EMPLOYEE * head_ptr) ;
void calcStateTax( EMPLOYEE * head_ptr) ;
void calcFedTax( EMPLOYEE * head_ptr) ;
void calcNetPay( EMPLOYEE * head_ptr) ;
void calcEmployeeTotals( EMPLOYEE * head_ptr, TOTALS * totals) ;
void calcEmployeeMinMax( EMPLOYEE * head_ptr, MIN_MAX * mm) ;
void printHeader( void ) ;
void printEmp( EMPLOYEE * head_ptr) ;
void printEmpStatistics( TOTALS * totals, MIN_MAX * mm, int size) ;
//---------------- MAIN ----------------
int main( ) {
EMPLOYEE * head_ptr;
int size;
TOTALS totals = { 0 } ;
MIN_MAX mm = { 0 } ;
head_ptr = getEmpData( ) ;
size = isEmployeeSize( head_ptr) ;
if ( size > 0 ) {
calcOvertimeHrs( head_ptr) ;
calcGrossPay( head_ptr) ;
calcStateTax( head_ptr) ;
calcFedTax( head_ptr) ;
calcNetPay( head_ptr) ;
calcEmployeeTotals( head_ptr, & totals) ;
calcEmployeeMinMax( head_ptr, & mm) ;
printHeader( ) ;
printEmp( head_ptr) ;
printEmpStatistics( & totals, & mm, size) ;
}
else {
printf ( "\n \n **** There was no employee input to process ***\n " ) ; }
printf ( "\n \n *** End of Program *** \n " ) ; return 0 ;
}
//---------------- INPUT ----------------
EMPLOYEE * getEmpData( void ) {
EMPLOYEE * head = NULL, * current = NULL;
char ans;
while ( 1 ) {
EMPLOYEE
* node
= ( EMPLOYEE
* ) malloc ( sizeof ( EMPLOYEE
) ) ;
scanf ( "%9s" , node
-> empName.
firstName ) ; scanf ( "%9s" , node
-> empName.
lastName ) ; scanf ( "%2s" , node
-> taxState
) ; scanf ( "%ld" , & node
-> clockNumber
) ; scanf ( "%f" , & node
-> wageRate
) ; scanf ( "%f" , & node
-> hours
) ;
node-> overtimeHrs = 0 ;
node-> grossPay = 0 ;
node-> stateTax = 0 ;
node-> fedTax = 0 ;
node-> netPay = 0 ;
node-> next = NULL;
if ( ! head)
head = node;
else
current-> next = node;
current = node;
break ;
}
return head;
}
//---------------- SIZE ----------------
int isEmployeeSize( EMPLOYEE * head_ptr) {
int count = 0 ;
while ( head_ptr) {
count++;
head_ptr = head_ptr-> next;
}
return count;
}
//---------------- CALCULATIONS ----------------
void calcOvertimeHrs( EMPLOYEE * h) {
while ( h) {
h-> overtimeHrs = CALC_OT_HOURS( h-> hours) ;
h = h-> next;
}
}
void calcGrossPay( EMPLOYEE * h) {
while ( h) {
float normal = CALC_NORMAL_PAY( h-> wageRate, h-> hours, h-> overtimeHrs) ;
float ot = CALC_OT_PAY( h-> wageRate, h-> overtimeHrs) ;
h-> grossPay = normal + ot;
h = h-> next;
}
}
void calcStateTax( EMPLOYEE * h) {
while ( h) {
if ( strcmp ( h
-> taxState
, "MA" ) == 0 ) h-> stateTax = CALC_STATE_TAX( h-> grossPay, MA_TAX_RATE) ;
else if ( strcmp ( h
-> taxState
, "NH" ) == 0 ) h-> stateTax = CALC_STATE_TAX( h-> grossPay, NH_TAX_RATE) ;
else if ( strcmp ( h
-> taxState
, "VT" ) == 0 ) h-> stateTax = CALC_STATE_TAX( h-> grossPay, VT_TAX_RATE) ;
else if ( strcmp ( h
-> taxState
, "CA" ) == 0 ) h-> stateTax = CALC_STATE_TAX( h-> grossPay, CA_TAX_RATE) ;
else
h-> stateTax = CALC_STATE_TAX( h-> grossPay, DEFAULT_STATE_TAX_RATE) ;
h = h-> next;
}
}
void calcFedTax( EMPLOYEE * h) {
while ( h) {
h-> fedTax = CALC_FED_TAX( h-> grossPay) ;
h = h-> next;
}
}
void calcNetPay( EMPLOYEE * h) {
while ( h) {
h-> netPay = CALC_NET_PAY( h-> grossPay, h-> stateTax, h-> fedTax) ;
h = h-> next;
}
}
//---------------- TOTALS ----------------
void calcEmployeeTotals( EMPLOYEE * h, TOTALS * t) {
while ( h) {
t-> total_wageRate += h-> wageRate;
t-> total_hours += h-> hours;
t-> total_overtimeHrs += h-> overtimeHrs;
t-> total_grossPay += h-> grossPay;
t-> total_stateTax += h-> stateTax;
t-> total_fedTax += h-> fedTax;
t-> total_netPay += h-> netPay;
h = h-> next;
}
}
//---------------- MIN/MAX ----------------
void calcEmployeeMinMax( EMPLOYEE * h, MIN_MAX * m) {
if ( ! h) return ;
m-> min_wageRate = m-> max_wageRate = h-> wageRate;
m-> min_hours = m-> max_hours = h-> hours;
m-> min_overtimeHrs = m-> max_overtimeHrs = h-> overtimeHrs;
m-> min_grossPay = m-> max_grossPay = h-> grossPay;
m-> min_stateTax = m-> max_stateTax = h-> stateTax;
m-> min_fedTax = m-> max_fedTax = h-> fedTax;
m-> min_netPay = m-> max_netPay = h-> netPay;
h = h-> next;
while ( h) {
m-> min_wageRate = CALC_MIN( h-> wageRate, m-> min_wageRate) ;
m-> max_wageRate = CALC_MAX( h-> wageRate, m-> max_wageRate) ;
m-> min_hours = CALC_MIN( h-> hours, m-> min_hours) ;
m-> max_hours = CALC_MAX( h-> hours, m-> max_hours) ;
m-> min_overtimeHrs = CALC_MIN( h-> overtimeHrs, m-> min_overtimeHrs) ;
m-> max_overtimeHrs = CALC_MAX( h-> overtimeHrs, m-> max_overtimeHrs) ;
m-> min_grossPay = CALC_MIN( h-> grossPay, m-> min_grossPay) ;
m-> max_grossPay = CALC_MAX( h-> grossPay, m-> max_grossPay) ;
m-> min_stateTax = CALC_MIN( h-> stateTax, m-> min_stateTax) ;
m-> max_stateTax = CALC_MAX( h-> stateTax, m-> max_stateTax) ;
m-> min_fedTax = CALC_MIN( h-> fedTax, m-> min_fedTax) ;
m-> max_fedTax = CALC_MAX( h-> fedTax, m-> max_fedTax) ;
m-> min_netPay = CALC_MIN( h-> netPay, m-> min_netPay) ;
m-> max_netPay = CALC_MAX( h-> netPay, m-> max_netPay) ;
h = h-> next;
}
}
//---------------- OUTPUT ----------------
void printHeader( void ) {
printf ( "\n *** Pay Calculator ***\n " ) ; printf ( "\n ---------------------------------------------------------------------------------" ) ; printf ( "\n Name Tax Clock# Wage Hours OT Gross State Fed Net" ) ; printf ( "\n State Pay Tax Tax Pay" ) ; printf ( "\n ---------------------------------------------------------------------------------" ) ; }
void printEmp( EMPLOYEE * h) {
while ( h) {
char name[ 25 ] ;
strcpy ( name
, h
-> empName.
firstName ) ; strcat ( name
, h
-> empName.
lastName ) ;
printf ( "\n %-20s %-2s %06ld %5.2f %5.1f %4.1f %7.2f %6.2f %7.2f %8.2f" , name,
h-> taxState,
h-> clockNumber,
h-> wageRate,
h-> hours,
h-> overtimeHrs,
h-> grossPay,
h-> stateTax,
h-> fedTax,
h-> netPay) ;
h = h-> next;
}
}
void printEmpStatistics( TOTALS * t, MIN_MAX * m, int size) {
printf ( "\n ---------------------------------------------------------------------------------" ) ;
printf ( "\n Totals: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f" , t-> total_wageRate,
t-> total_hours,
t-> total_overtimeHrs,
t-> total_grossPay,
t-> total_stateTax,
t-> total_fedTax,
t-> total_netPay) ;
printf ( "\n Averages: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f" , t-> total_wageRate/ size,
t-> total_hours/ size,
t-> total_overtimeHrs/ size,
t-> total_grossPay/ size,
t-> total_stateTax/ size,
t-> total_fedTax/ size,
t-> total_netPay/ size) ;
printf ( "\n Minimum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f" , m-> min_wageRate,
m-> min_hours,
m-> min_overtimeHrs,
m-> min_grossPay,
m-> min_stateTax,
m-> min_fedTax,
m-> min_netPay) ;
printf ( "\n Maximum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f" , m-> max_wageRate,
m-> max_hours,
m-> max_overtimeHrs,
m-> max_grossPay,
m-> max_stateTax,
m-> max_fedTax,
m-> max_netPay) ;
printf ( "\n \n The total employees processed was: %d\n " , size
) ; }
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDEwIC0gTGlua2VkIExpc3RzLCBUeXBlZGVmLCBhbmQgTWFjcm9zCi8vCi8vIE5hbWU6IDxyZXBsYWNlIHdpdGggeW91ciBuYW1lPgovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgPHJlcGxhY2Ugd2l0aCBTZW1lc3RlciBhbmQgWWVhcj4KLy8KLy8gRGF0ZTogPHJlcGxhY2Ugd2l0aCB0aGUgY3VycmVudCBkYXRlPgovLwovLyBEZXNjcmlwdGlvbjogUHJvZ3JhbSB3aGljaCBkZXRlcm1pbmVzIG92ZXJ0aW1lIGFuZCAKLy8gZ3Jvc3MgcGF5IGZvciBhIHNldCBvZiBlbXBsb3llZXMgd2l0aCBvdXRwdXRzIHNlbnQgCi8vIHRvIHN0YW5kYXJkIG91dHB1dCAodGhlIHNjcmVlbikuCi8vCi8vIFRoaXMgYXNzaWdubWVudCBhbHNvIGFkZHMgdGhlIGVtcGxveWVlIG5hbWUsIHRoZWlyIHRheCBzdGF0ZSwKLy8gYW5kIGNhbGN1bGF0ZXMgdGhlIHN0YXRlIHRheCwgZmVkZXJhbCB0YXgsIGFuZCBuZXQgcGF5LiAgIEl0Ci8vIGFsc28gY2FsY3VsYXRlcyB0b3RhbHMsIGF2ZXJhZ2VzLCBtaW5pbXVtLCBhbmQgbWF4aW11bSB2YWx1ZXMuCi8vCi8vIEFycmF5IGFuZCBTdHJ1Y3R1cmUgcmVmZXJlbmNlcyBoYXZlIGFsbCBiZWVuIHJlcGxhY2VkIHdpdGgKLy8gcG9pbnRlciByZWZlcmVuY2VzIHRvIHNwZWVkIHVwIHRoZSBwcm9jZXNzaW5nIG9mIHRoaXMgY29kZS4KLy8gQSBsaW5rZWQgbGlzdCBoYXMgYmVlbiBjcmVhdGVkIGFuZCBkZXBsb3llZCB0byBkeW5hbWljYWxseQovLyBhbGxvY2F0ZSBhbmQgcHJvY2VzcyBlbXBsb3llZXMgYXMgbmVlZGVkLgovLwovLyBJdCB3aWxsIGFsc28gdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIEMgUHJlcHJvY2Vzc29yIGZlYXR1cmVzLAovLyBpbiBwYXJ0aWN1bGFyIHdpdGggdXNpbmcgbWFjcm9zLCBhbmQgd2lsbCByZXBsYWNlIGFsbCAKLy8gc3RydWN0IHR5cGUgcmVmZXJlbmNlcyBpbiB0aGUgY29kZSB3aXRoIGEgdHlwZWRlZiBhbGlhcwovLyByZWZlcmVuY2UuCi8vCi8vIENhbGwgYnkgUmVmZXJlbmNlIGRlc2lnbiAodXNpbmcgcG9pbnRlcnMpCi8vCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCi8vIG5lY2Vzc2FyeSBoZWFkZXIgZmlsZXMKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+ICAgLy8gZm9yIGNoYXIgZnVuY3Rpb25zCiNpbmNsdWRlIDxzdGRsaWIuaD4gIC8vIGZvciBtYWxsb2MKCi8vIGRlZmluZSBjb25zdGFudHMKI2RlZmluZSBTVERfSE9VUlMgNDAuMAojZGVmaW5lIE9UX1JBVEUgMS41CiNkZWZpbmUgTUFfVEFYX1JBVEUgMC4wNQojZGVmaW5lIE5IX1RBWF9SQVRFIDAuMAojZGVmaW5lIFZUX1RBWF9SQVRFIDAuMDYKI2RlZmluZSBDQV9UQVhfUkFURSAwLjA3CiNkZWZpbmUgREVGQVVMVF9TVEFURV9UQVhfUkFURSAwLjA4CiNkZWZpbmUgTkFNRV9TSVpFIDIwCiNkZWZpbmUgVEFYX1NUQVRFX1NJWkUgMwojZGVmaW5lIEZFRF9UQVhfUkFURSAwLjI1CiNkZWZpbmUgRklSU1RfTkFNRV9TSVpFIDEwCiNkZWZpbmUgTEFTVF9OQU1FX1NJWkUgMTAKCi8vIGRlZmluZSBtYWNyb3MKLy8tLS0tLS0tLS0tLS0tLS0tIE1BQ1JPUyAtLS0tLS0tLS0tLS0tLS0tCgojZGVmaW5lIENBTENfT1RfSE9VUlMoaCkgKChoID4gU1REX0hPVVJTKSA/IChoIC0gU1REX0hPVVJTKSA6IDApCiNkZWZpbmUgQ0FMQ19TVEFURV9UQVgocGF5LCByYXRlKSAoKHBheSkgKiAocmF0ZSkpCiNkZWZpbmUgQ0FMQ19GRURfVEFYKHBheSkgKChwYXkpICogRkVEX1RBWF9SQVRFKQoKI2RlZmluZSBDQUxDX05FVF9QQVkocGF5LCBzdCwgZnQpICgocGF5KSAtICgoc3QpICsgKGZ0KSkpCiNkZWZpbmUgQ0FMQ19OT1JNQUxfUEFZKHcsIGgsIG90KSAoKHcpICogKChoKSAtIChvdCkpKQojZGVmaW5lIENBTENfT1RfUEFZKHcsIG90KSAoKG90KSAqICgodykgKiBPVF9SQVRFKSkKCiNkZWZpbmUgQ0FMQ19NSU4odmFsLCBtaW4pICgodmFsIDwgbWluKSA/IHZhbCA6IG1pbikKI2RlZmluZSBDQUxDX01BWCh2YWwsIG1heCkgKCh2YWwgPiBtYXgpID8gdmFsIDogbWF4KQoKLy8tLS0tLS0tLS0tLS0tLS0tIFNUUlVDVFVSRVMgLS0tLS0tLS0tLS0tLS0tLQoKdHlwZWRlZiBzdHJ1Y3QgbmFtZSB7CiAgICBjaGFyIGZpcnN0TmFtZVtGSVJTVF9OQU1FX1NJWkVdOwogICAgY2hhciBsYXN0TmFtZVtGSVJTVF9OQU1FX1NJWkVdOwp9IE5BTUU7Cgp0eXBlZGVmIHN0cnVjdCBlbXBsb3llZSB7CiAgICBOQU1FIGVtcE5hbWU7CiAgICBjaGFyIHRheFN0YXRlW1RBWF9TVEFURV9TSVpFXTsKICAgIGxvbmcgY2xvY2tOdW1iZXI7CiAgICBmbG9hdCB3YWdlUmF0ZTsKICAgIGZsb2F0IGhvdXJzOwogICAgZmxvYXQgb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBncm9zc1BheTsKICAgIGZsb2F0IHN0YXRlVGF4OwogICAgZmxvYXQgZmVkVGF4OwogICAgZmxvYXQgbmV0UGF5OwogICAgc3RydWN0IGVtcGxveWVlICpuZXh0Owp9IEVNUExPWUVFOwoKdHlwZWRlZiBzdHJ1Y3QgdG90YWxzIHsKICAgIGZsb2F0IHRvdGFsX3dhZ2VSYXRlOwogICAgZmxvYXQgdG90YWxfaG91cnM7CiAgICBmbG9hdCB0b3RhbF9vdmVydGltZUhyczsKICAgIGZsb2F0IHRvdGFsX2dyb3NzUGF5OwogICAgZmxvYXQgdG90YWxfc3RhdGVUYXg7CiAgICBmbG9hdCB0b3RhbF9mZWRUYXg7CiAgICBmbG9hdCB0b3RhbF9uZXRQYXk7Cn0gVE9UQUxTOwoKdHlwZWRlZiBzdHJ1Y3QgbWluX21heCB7CiAgICBmbG9hdCBtaW5fd2FnZVJhdGU7CiAgICBmbG9hdCBtaW5faG91cnM7CiAgICBmbG9hdCBtaW5fb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtaW5fZ3Jvc3NQYXk7CiAgICBmbG9hdCBtaW5fc3RhdGVUYXg7CiAgICBmbG9hdCBtaW5fZmVkVGF4OwogICAgZmxvYXQgbWluX25ldFBheTsKCiAgICBmbG9hdCBtYXhfd2FnZVJhdGU7CiAgICBmbG9hdCBtYXhfaG91cnM7CiAgICBmbG9hdCBtYXhfb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtYXhfZ3Jvc3NQYXk7CiAgICBmbG9hdCBtYXhfc3RhdGVUYXg7CiAgICBmbG9hdCBtYXhfZmVkVGF4OwogICAgZmxvYXQgbWF4X25ldFBheTsKfSBNSU5fTUFYOwoKLy8tLS0tLS0tLS0tLS0tLS0tIFBST1RPVFlQRVMgLS0tLS0tLS0tLS0tLS0tLQoKRU1QTE9ZRUUgKmdldEVtcERhdGEodm9pZCk7CmludCBpc0VtcGxveWVlU2l6ZShFTVBMT1lFRSAqaGVhZF9wdHIpOwoKdm9pZCBjYWxjT3ZlcnRpbWVIcnMoRU1QTE9ZRUUgKmhlYWRfcHRyKTsKdm9pZCBjYWxjR3Jvc3NQYXkoRU1QTE9ZRUUgKmhlYWRfcHRyKTsKdm9pZCBjYWxjU3RhdGVUYXgoRU1QTE9ZRUUgKmhlYWRfcHRyKTsKdm9pZCBjYWxjRmVkVGF4KEVNUExPWUVFICpoZWFkX3B0cik7CnZvaWQgY2FsY05ldFBheShFTVBMT1lFRSAqaGVhZF9wdHIpOwoKdm9pZCBjYWxjRW1wbG95ZWVUb3RhbHMoRU1QTE9ZRUUgKmhlYWRfcHRyLCBUT1RBTFMgKnRvdGFscyk7CnZvaWQgY2FsY0VtcGxveWVlTWluTWF4KEVNUExPWUVFICpoZWFkX3B0ciwgTUlOX01BWCAqbW0pOwoKdm9pZCBwcmludEhlYWRlcih2b2lkKTsKdm9pZCBwcmludEVtcChFTVBMT1lFRSAqaGVhZF9wdHIpOwp2b2lkIHByaW50RW1wU3RhdGlzdGljcyhUT1RBTFMgKnRvdGFscywgTUlOX01BWCAqbW0sIGludCBzaXplKTsKCi8vLS0tLS0tLS0tLS0tLS0tLSBNQUlOIC0tLS0tLS0tLS0tLS0tLS0KCmludCBtYWluKCkgewoKICAgIEVNUExPWUVFICpoZWFkX3B0cjsKICAgIGludCBzaXplOwoKICAgIFRPVEFMUyB0b3RhbHMgPSB7MH07CiAgICBNSU5fTUFYIG1tID0gezB9OwoKICAgIGhlYWRfcHRyID0gZ2V0RW1wRGF0YSgpOwogICAgc2l6ZSA9IGlzRW1wbG95ZWVTaXplKGhlYWRfcHRyKTsKCiAgICBpZiAoc2l6ZSA+IDApIHsKCiAgICAgICAgY2FsY092ZXJ0aW1lSHJzKGhlYWRfcHRyKTsKICAgICAgICBjYWxjR3Jvc3NQYXkoaGVhZF9wdHIpOwogICAgICAgIGNhbGNTdGF0ZVRheChoZWFkX3B0cik7CiAgICAgICAgY2FsY0ZlZFRheChoZWFkX3B0cik7CiAgICAgICAgY2FsY05ldFBheShoZWFkX3B0cik7CgogICAgICAgIGNhbGNFbXBsb3llZVRvdGFscyhoZWFkX3B0ciwgJnRvdGFscyk7CiAgICAgICAgY2FsY0VtcGxveWVlTWluTWF4KGhlYWRfcHRyLCAmbW0pOwoKICAgICAgICBwcmludEhlYWRlcigpOwogICAgICAgIHByaW50RW1wKGhlYWRfcHRyKTsKICAgICAgICBwcmludEVtcFN0YXRpc3RpY3MoJnRvdGFscywgJm1tLCBzaXplKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHByaW50ZigiXG5cbioqKiogVGhlcmUgd2FzIG5vIGVtcGxveWVlIGlucHV0IHRvIHByb2Nlc3MgKioqXG4iKTsKICAgIH0KCiAgICBwcmludGYoIlxuXG4gKioqIEVuZCBvZiBQcm9ncmFtICoqKiBcbiIpOwogICAgcmV0dXJuIDA7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLSBJTlBVVCAtLS0tLS0tLS0tLS0tLS0tCgpFTVBMT1lFRSAqZ2V0RW1wRGF0YSh2b2lkKSB7CgogICAgRU1QTE9ZRUUgKmhlYWQgPSBOVUxMLCAqY3VycmVudCA9IE5VTEw7CiAgICBjaGFyIGFuczsKCiAgICB3aGlsZSAoMSkgewoKICAgICAgICBFTVBMT1lFRSAqbm9kZSA9IChFTVBMT1lFRSAqKW1hbGxvYyhzaXplb2YoRU1QTE9ZRUUpKTsKCiAgICAgICAgc2NhbmYoIiU5cyIsIG5vZGUtPmVtcE5hbWUuZmlyc3ROYW1lKTsKICAgICAgICBzY2FuZigiJTlzIiwgbm9kZS0+ZW1wTmFtZS5sYXN0TmFtZSk7CiAgICAgICAgc2NhbmYoIiUycyIsIG5vZGUtPnRheFN0YXRlKTsKICAgICAgICBzY2FuZigiJWxkIiwgJm5vZGUtPmNsb2NrTnVtYmVyKTsKICAgICAgICBzY2FuZigiJWYiLCAmbm9kZS0+d2FnZVJhdGUpOwogICAgICAgIHNjYW5mKCIlZiIsICZub2RlLT5ob3Vycyk7CgogICAgICAgIG5vZGUtPm92ZXJ0aW1lSHJzID0gMDsKICAgICAgICBub2RlLT5ncm9zc1BheSA9IDA7CiAgICAgICAgbm9kZS0+c3RhdGVUYXggPSAwOwogICAgICAgIG5vZGUtPmZlZFRheCA9IDA7CiAgICAgICAgbm9kZS0+bmV0UGF5ID0gMDsKICAgICAgICBub2RlLT5uZXh0ID0gTlVMTDsKCiAgICAgICAgaWYgKCFoZWFkKQogICAgICAgICAgICBoZWFkID0gbm9kZTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSBub2RlOwoKICAgICAgICBjdXJyZW50ID0gbm9kZTsKCiAgICAgICAgc2NhbmYoIiAlYyIsICZhbnMpOwogICAgICAgIGlmICh0b3VwcGVyKGFucykgIT0gJ1knKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gaGVhZDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tIFNJWkUgLS0tLS0tLS0tLS0tLS0tLQoKaW50IGlzRW1wbG95ZWVTaXplKEVNUExPWUVFICpoZWFkX3B0cikgewogICAgaW50IGNvdW50ID0gMDsKICAgIHdoaWxlIChoZWFkX3B0cikgewogICAgICAgIGNvdW50Kys7CiAgICAgICAgaGVhZF9wdHIgPSBoZWFkX3B0ci0+bmV4dDsKICAgIH0KICAgIHJldHVybiBjb3VudDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tIENBTENVTEFUSU9OUyAtLS0tLS0tLS0tLS0tLS0tCgp2b2lkIGNhbGNPdmVydGltZUhycyhFTVBMT1lFRSAqaCkgewogICAgd2hpbGUgKGgpIHsKICAgICAgICBoLT5vdmVydGltZUhycyA9IENBTENfT1RfSE9VUlMoaC0+aG91cnMpOwogICAgICAgIGggPSBoLT5uZXh0OwogICAgfQp9Cgp2b2lkIGNhbGNHcm9zc1BheShFTVBMT1lFRSAqaCkgewogICAgd2hpbGUgKGgpIHsKICAgICAgICBmbG9hdCBub3JtYWwgPSBDQUxDX05PUk1BTF9QQVkoaC0+d2FnZVJhdGUsIGgtPmhvdXJzLCBoLT5vdmVydGltZUhycyk7CiAgICAgICAgZmxvYXQgb3QgPSBDQUxDX09UX1BBWShoLT53YWdlUmF0ZSwgaC0+b3ZlcnRpbWVIcnMpOwogICAgICAgIGgtPmdyb3NzUGF5ID0gbm9ybWFsICsgb3Q7CiAgICAgICAgaCA9IGgtPm5leHQ7CiAgICB9Cn0KCnZvaWQgY2FsY1N0YXRlVGF4KEVNUExPWUVFICpoKSB7CiAgICB3aGlsZSAoaCkgewoKICAgICAgICBpZiAoc3RyY21wKGgtPnRheFN0YXRlLCAiTUEiKSA9PSAwKQogICAgICAgICAgICBoLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGgtPmdyb3NzUGF5LCBNQV9UQVhfUkFURSk7CiAgICAgICAgZWxzZSBpZiAoc3RyY21wKGgtPnRheFN0YXRlLCAiTkgiKSA9PSAwKQogICAgICAgICAgICBoLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGgtPmdyb3NzUGF5LCBOSF9UQVhfUkFURSk7CiAgICAgICAgZWxzZSBpZiAoc3RyY21wKGgtPnRheFN0YXRlLCAiVlQiKSA9PSAwKQogICAgICAgICAgICBoLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGgtPmdyb3NzUGF5LCBWVF9UQVhfUkFURSk7CiAgICAgICAgZWxzZSBpZiAoc3RyY21wKGgtPnRheFN0YXRlLCAiQ0EiKSA9PSAwKQogICAgICAgICAgICBoLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGgtPmdyb3NzUGF5LCBDQV9UQVhfUkFURSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBoLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGgtPmdyb3NzUGF5LCBERUZBVUxUX1NUQVRFX1RBWF9SQVRFKTsKCiAgICAgICAgaCA9IGgtPm5leHQ7CiAgICB9Cn0KCnZvaWQgY2FsY0ZlZFRheChFTVBMT1lFRSAqaCkgewogICAgd2hpbGUgKGgpIHsKICAgICAgICBoLT5mZWRUYXggPSBDQUxDX0ZFRF9UQVgoaC0+Z3Jvc3NQYXkpOwogICAgICAgIGggPSBoLT5uZXh0OwogICAgfQp9Cgp2b2lkIGNhbGNOZXRQYXkoRU1QTE9ZRUUgKmgpIHsKICAgIHdoaWxlIChoKSB7CiAgICAgICAgaC0+bmV0UGF5ID0gQ0FMQ19ORVRfUEFZKGgtPmdyb3NzUGF5LCBoLT5zdGF0ZVRheCwgaC0+ZmVkVGF4KTsKICAgICAgICBoID0gaC0+bmV4dDsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tIFRPVEFMUyAtLS0tLS0tLS0tLS0tLS0tCgp2b2lkIGNhbGNFbXBsb3llZVRvdGFscyhFTVBMT1lFRSAqaCwgVE9UQUxTICp0KSB7CgogICAgd2hpbGUgKGgpIHsKICAgICAgICB0LT50b3RhbF93YWdlUmF0ZSArPSBoLT53YWdlUmF0ZTsKICAgICAgICB0LT50b3RhbF9ob3VycyArPSBoLT5ob3VyczsKICAgICAgICB0LT50b3RhbF9vdmVydGltZUhycyArPSBoLT5vdmVydGltZUhyczsKICAgICAgICB0LT50b3RhbF9ncm9zc1BheSArPSBoLT5ncm9zc1BheTsKICAgICAgICB0LT50b3RhbF9zdGF0ZVRheCArPSBoLT5zdGF0ZVRheDsKICAgICAgICB0LT50b3RhbF9mZWRUYXggKz0gaC0+ZmVkVGF4OwogICAgICAgIHQtPnRvdGFsX25ldFBheSArPSBoLT5uZXRQYXk7CiAgICAgICAgaCA9IGgtPm5leHQ7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLSBNSU4vTUFYIC0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgY2FsY0VtcGxveWVlTWluTWF4KEVNUExPWUVFICpoLCBNSU5fTUFYICptKSB7CgogICAgaWYgKCFoKSByZXR1cm47CgogICAgbS0+bWluX3dhZ2VSYXRlID0gbS0+bWF4X3dhZ2VSYXRlID0gaC0+d2FnZVJhdGU7CiAgICBtLT5taW5faG91cnMgPSBtLT5tYXhfaG91cnMgPSBoLT5ob3VyczsKICAgIG0tPm1pbl9vdmVydGltZUhycyA9IG0tPm1heF9vdmVydGltZUhycyA9IGgtPm92ZXJ0aW1lSHJzOwogICAgbS0+bWluX2dyb3NzUGF5ID0gbS0+bWF4X2dyb3NzUGF5ID0gaC0+Z3Jvc3NQYXk7CiAgICBtLT5taW5fc3RhdGVUYXggPSBtLT5tYXhfc3RhdGVUYXggPSBoLT5zdGF0ZVRheDsKICAgIG0tPm1pbl9mZWRUYXggPSBtLT5tYXhfZmVkVGF4ID0gaC0+ZmVkVGF4OwogICAgbS0+bWluX25ldFBheSA9IG0tPm1heF9uZXRQYXkgPSBoLT5uZXRQYXk7CgogICAgaCA9IGgtPm5leHQ7CgogICAgd2hpbGUgKGgpIHsKCiAgICAgICAgbS0+bWluX3dhZ2VSYXRlID0gQ0FMQ19NSU4oaC0+d2FnZVJhdGUsIG0tPm1pbl93YWdlUmF0ZSk7CiAgICAgICAgbS0+bWF4X3dhZ2VSYXRlID0gQ0FMQ19NQVgoaC0+d2FnZVJhdGUsIG0tPm1heF93YWdlUmF0ZSk7CgogICAgICAgIG0tPm1pbl9ob3VycyA9IENBTENfTUlOKGgtPmhvdXJzLCBtLT5taW5faG91cnMpOwogICAgICAgIG0tPm1heF9ob3VycyA9IENBTENfTUFYKGgtPmhvdXJzLCBtLT5tYXhfaG91cnMpOwoKICAgICAgICBtLT5taW5fb3ZlcnRpbWVIcnMgPSBDQUxDX01JTihoLT5vdmVydGltZUhycywgbS0+bWluX292ZXJ0aW1lSHJzKTsKICAgICAgICBtLT5tYXhfb3ZlcnRpbWVIcnMgPSBDQUxDX01BWChoLT5vdmVydGltZUhycywgbS0+bWF4X292ZXJ0aW1lSHJzKTsKCiAgICAgICAgbS0+bWluX2dyb3NzUGF5ID0gQ0FMQ19NSU4oaC0+Z3Jvc3NQYXksIG0tPm1pbl9ncm9zc1BheSk7CiAgICAgICAgbS0+bWF4X2dyb3NzUGF5ID0gQ0FMQ19NQVgoaC0+Z3Jvc3NQYXksIG0tPm1heF9ncm9zc1BheSk7CgogICAgICAgIG0tPm1pbl9zdGF0ZVRheCA9IENBTENfTUlOKGgtPnN0YXRlVGF4LCBtLT5taW5fc3RhdGVUYXgpOwogICAgICAgIG0tPm1heF9zdGF0ZVRheCA9IENBTENfTUFYKGgtPnN0YXRlVGF4LCBtLT5tYXhfc3RhdGVUYXgpOwoKICAgICAgICBtLT5taW5fZmVkVGF4ID0gQ0FMQ19NSU4oaC0+ZmVkVGF4LCBtLT5taW5fZmVkVGF4KTsKICAgICAgICBtLT5tYXhfZmVkVGF4ID0gQ0FMQ19NQVgoaC0+ZmVkVGF4LCBtLT5tYXhfZmVkVGF4KTsKCiAgICAgICAgbS0+bWluX25ldFBheSA9IENBTENfTUlOKGgtPm5ldFBheSwgbS0+bWluX25ldFBheSk7CiAgICAgICAgbS0+bWF4X25ldFBheSA9IENBTENfTUFYKGgtPm5ldFBheSwgbS0+bWF4X25ldFBheSk7CgogICAgICAgIGggPSBoLT5uZXh0OwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0gT1VUUFVUIC0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgcHJpbnRIZWFkZXIodm9pZCkgewoKICAgIHByaW50ZigiXG4qKiogUGF5IENhbGN1bGF0b3IgKioqXG4iKTsKICAgIHByaW50ZigiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKICAgIHByaW50ZigiXG5OYW1lICAgICAgICAgICAgICAgIFRheCAgQ2xvY2sjICBXYWdlICAgSG91cnMgIE9UICAgR3Jvc3MgICBTdGF0ZSAgRmVkICAgICAgTmV0Iik7CiAgICBwcmludGYoIlxuICAgICAgICAgICAgICAgICAgICBTdGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgIFBheSAgICAgVGF4ICAgIFRheCAgICAgIFBheSIpOwogICAgcHJpbnRmKCJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwp9Cgp2b2lkIHByaW50RW1wKEVNUExPWUVFICpoKSB7CgogICAgd2hpbGUgKGgpIHsKCiAgICAgICAgY2hhciBuYW1lWzI1XTsKICAgICAgICBzdHJjcHkobmFtZSwgaC0+ZW1wTmFtZS5maXJzdE5hbWUpOwogICAgICAgIHN0cmNhdChuYW1lLCAiICIpOwogICAgICAgIHN0cmNhdChuYW1lLCBoLT5lbXBOYW1lLmxhc3ROYW1lKTsKCiAgICAgICAgcHJpbnRmKCJcbiUtMjBzICUtMnMgICUwNmxkICAlNS4yZiAgJTUuMWYgICU0LjFmICAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgIGgtPnRheFN0YXRlLAogICAgICAgICAgICBoLT5jbG9ja051bWJlciwKICAgICAgICAgICAgaC0+d2FnZVJhdGUsCiAgICAgICAgICAgIGgtPmhvdXJzLAogICAgICAgICAgICBoLT5vdmVydGltZUhycywKICAgICAgICAgICAgaC0+Z3Jvc3NQYXksCiAgICAgICAgICAgIGgtPnN0YXRlVGF4LAogICAgICAgICAgICBoLT5mZWRUYXgsCiAgICAgICAgICAgIGgtPm5ldFBheSk7CgogICAgICAgIGggPSBoLT5uZXh0OwogICAgfQp9Cgp2b2lkIHByaW50RW1wU3RhdGlzdGljcyhUT1RBTFMgKnQsIE1JTl9NQVggKm0sIGludCBzaXplKSB7CgogICAgcHJpbnRmKCJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwoKICAgIHByaW50ZigiXG5Ub3RhbHM6ICAgICAgICAgICAgICAgICAgICAgICAgICU1LjJmICU1LjFmICU1LjFmICU3LjJmICU2LjJmICU3LjJmICU4LjJmIiwKICAgICAgICB0LT50b3RhbF93YWdlUmF0ZSwKICAgICAgICB0LT50b3RhbF9ob3VycywKICAgICAgICB0LT50b3RhbF9vdmVydGltZUhycywKICAgICAgICB0LT50b3RhbF9ncm9zc1BheSwKICAgICAgICB0LT50b3RhbF9zdGF0ZVRheCwKICAgICAgICB0LT50b3RhbF9mZWRUYXgsCiAgICAgICAgdC0+dG90YWxfbmV0UGF5KTsKCiAgICBwcmludGYoIlxuQXZlcmFnZXM6ICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNS4xZiAlNS4xZiAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgdC0+dG90YWxfd2FnZVJhdGUvc2l6ZSwKICAgICAgICB0LT50b3RhbF9ob3Vycy9zaXplLAogICAgICAgIHQtPnRvdGFsX292ZXJ0aW1lSHJzL3NpemUsCiAgICAgICAgdC0+dG90YWxfZ3Jvc3NQYXkvc2l6ZSwKICAgICAgICB0LT50b3RhbF9zdGF0ZVRheC9zaXplLAogICAgICAgIHQtPnRvdGFsX2ZlZFRheC9zaXplLAogICAgICAgIHQtPnRvdGFsX25ldFBheS9zaXplKTsKCiAgICBwcmludGYoIlxuTWluaW11bTogICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNS4xZiAlNS4xZiAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgbS0+bWluX3dhZ2VSYXRlLAogICAgICAgIG0tPm1pbl9ob3VycywKICAgICAgICBtLT5taW5fb3ZlcnRpbWVIcnMsCiAgICAgICAgbS0+bWluX2dyb3NzUGF5LAogICAgICAgIG0tPm1pbl9zdGF0ZVRheCwKICAgICAgICBtLT5taW5fZmVkVGF4LAogICAgICAgIG0tPm1pbl9uZXRQYXkpOwoKICAgIHByaW50ZigiXG5NYXhpbXVtOiAgICAgICAgICAgICAgICAgICAgICAgICU1LjJmICU1LjFmICU1LjFmICU3LjJmICU2LjJmICU3LjJmICU4LjJmIiwKICAgICAgICBtLT5tYXhfd2FnZVJhdGUsCiAgICAgICAgbS0+bWF4X2hvdXJzLAogICAgICAgIG0tPm1heF9vdmVydGltZUhycywKICAgICAgICBtLT5tYXhfZ3Jvc3NQYXksCiAgICAgICAgbS0+bWF4X3N0YXRlVGF4LAogICAgICAgIG0tPm1heF9mZWRUYXgsCiAgICAgICAgbS0+bWF4X25ldFBheSk7CgogICAgcHJpbnRmKCJcblxuVGhlIHRvdGFsIGVtcGxveWVlcyBwcm9jZXNzZWQgd2FzOiAlZFxuIiwgc2l6ZSk7Cn0=