//********************************************************
//
// Assignment 10 - Linked Lists, Typedef, and Macros
//
// Name: John Semenuk
//
// Class: C Programming, Spring 2026
//
// Date: April 20, 2026
//
// 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 employee name, tax state,
// and calculates state tax, federal tax, and net pay.
// It also calculates totals, averages, minimum, and maximum.
//
// Linked list + typedef + macros version
//
//********************************************************
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#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 FED_TAX_RATE 0.25
#define NAME_SIZE 20
#define TAX_STATE_SIZE 3
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10
// Macros
#define CALC_OT_HOURS(theHours) ((theHours > STD_HOURS) ? (theHours - STD_HOURS) : 0)
#define CALC_STATE_TAX(thePay,theStateTaxRate) ((thePay) * (theStateTaxRate))
// ✅ FIXED FED TAX MACRO
#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)))
// ✅ FIXED MIN/MAX MACROS
#define CALC_MIN(theValue, currentMin) (((theValue) < (currentMin)) ? (theValue) : (currentMin))
#define CALC_MAX(theValue, currentMax) (((theValue) > (currentMax)) ? (theValue) : (currentMax))
// structures
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;
// ✅ MIN_MAX typedef added
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 * emp_totals_ptr);
void calcEmployeeMinMax(EMPLOYEE * head_ptr, MIN_MAX * emp_minMax_ptr);
void printHeader(void);
void printEmp(EMPLOYEE * head_ptr);
void printEmpStatistics(TOTALS * emp_totals_ptr, MIN_MAX * emp_minMax_ptr, int size);
//**************************************************************
int main()
{
EMPLOYEE *head_ptr;
int theSize;
TOTALS employeeTotals = {0};
TOTALS *emp_totals_ptr = &employeeTotals;
MIN_MAX employeeMinMax = {0};
MIN_MAX *emp_minMax_ptr = &employeeMinMax;
head_ptr = getEmpData();
theSize = isEmployeeSize(head_ptr);
if (theSize <= 0)
{
printf("\n\n**** There was no employee input to process ***\n"); }
else
{
calcOvertimeHrs(head_ptr);
calcGrossPay(head_ptr);
calcStateTax(head_ptr);
calcFedTax(head_ptr);
calcNetPay(head_ptr);
calcEmployeeTotals(head_ptr, emp_totals_ptr);
calcEmployeeMinMax(head_ptr, emp_minMax_ptr);
printHeader();
printEmp(head_ptr);
printEmpStatistics(emp_totals_ptr, emp_minMax_ptr, theSize);
}
printf("\n\n *** End of Program *** \n"); return 0;
}
//**************************************************************
EMPLOYEE * getEmpData(void)
{
EMPLOYEE *head_ptr, *current_ptr;
char answer[10];
int more_data = 1;
head_ptr
= malloc(sizeof(EMPLOYEE
)); current_ptr = head_ptr;
while (more_data)
{
printf("\nEnter employee first name: "); scanf("%s", current_ptr
->empName.
firstName);
printf("\nEnter employee last name: "); scanf("%s", current_ptr
->empName.
lastName);
printf("\nEnter employee tax state: "); scanf("%s", current_ptr
->taxState
);
printf("\nEnter clock number: "); scanf("%li", ¤t_ptr
->clockNumber
);
printf("\nEnter wage rate: "); scanf("%f", ¤t_ptr
->wageRate
);
scanf("%f", ¤t_ptr
->hours
);
printf("\nAnother employee? (y/n): ");
{
current_ptr->next = NULL;
more_data = 0;
}
else
{
current_ptr
->next
= malloc(sizeof(EMPLOYEE
)); current_ptr = current_ptr->next;
}
}
return head_ptr;
}
//**************************************************************
int isEmployeeSize(EMPLOYEE *head_ptr)
{
int count = 0;
EMPLOYEE *cur;
for (cur = head_ptr; cur; cur = cur->next)
count++;
return count;
}
//**************************************************************
void calcOvertimeHrs(EMPLOYEE *head_ptr)
{
EMPLOYEE *cur;
for (cur = head_ptr; cur; cur = cur->next)
cur->overtimeHrs = CALC_OT_HOURS(cur->hours);
}
//**************************************************************
void calcGrossPay(EMPLOYEE *head_ptr)
{
EMPLOYEE *cur;
float normal, ot;
for (cur = head_ptr; cur; cur = cur->next)
{
normal = CALC_NORMAL_PAY(cur->wageRate, cur->hours, cur->overtimeHrs);
ot = CALC_OT_PAY(cur->wageRate, cur->overtimeHrs);
cur->grossPay = normal + ot;
}
}
//**************************************************************
void calcStateTax(EMPLOYEE *head_ptr)
{
EMPLOYEE *cur;
for (cur = head_ptr; cur; cur = cur->next)
{
if (strcmp(cur
->taxState
, "MA") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, MA_TAX_RATE);
else if (strcmp(cur
->taxState
, "VT") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, VT_TAX_RATE);
else if (strcmp(cur
->taxState
, "NH") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, NH_TAX_RATE);
else if (strcmp(cur
->taxState
, "CA") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, CA_TAX_RATE);
else
cur->stateTax = CALC_STATE_TAX(cur->grossPay, DEFAULT_STATE_TAX_RATE);
}
}
//**************************************************************
void calcFedTax(EMPLOYEE *head_ptr)
{
EMPLOYEE *cur;
for (cur = head_ptr; cur; cur = cur->next)
cur->fedTax = CALC_FED_TAX(cur->grossPay);
}
//**************************************************************
void calcNetPay(EMPLOYEE *head_ptr)
{
EMPLOYEE *cur;
for (cur = head_ptr; cur; cur = cur->next)
cur->netPay = CALC_NET_PAY(cur->grossPay, cur->stateTax, cur->fedTax);
}
//**************************************************************
void calcEmployeeTotals(EMPLOYEE *head_ptr, TOTALS *t)
{
EMPLOYEE *cur;
for (cur = head_ptr; cur; cur = cur->next)
{
t->total_wageRate += cur->wageRate;
t->total_hours += cur->hours;
t->total_overtimeHrs += cur->overtimeHrs;
t->total_grossPay += cur->grossPay;
t->total_stateTax += cur->stateTax;
t->total_fedTax += cur->fedTax;
t->total_netPay += cur->netPay;
}
}
//**************************************************************
void calcEmployeeMinMax(EMPLOYEE *head_ptr, MIN_MAX *m)
{
EMPLOYEE *cur = head_ptr;
m->min_wageRate = m->max_wageRate = cur->wageRate;
m->min_hours = m->max_hours = cur->hours;
m->min_overtimeHrs = m->max_overtimeHrs = cur->overtimeHrs;
m->min_grossPay = m->max_grossPay = cur->grossPay;
m->min_stateTax = m->max_stateTax = cur->stateTax;
m->min_fedTax = m->max_fedTax = cur->fedTax;
m->min_netPay = m->max_netPay = cur->netPay;
cur = cur->next;
for (; cur; cur = cur->next)
{
m->min_wageRate = CALC_MIN(cur->wageRate, m->min_wageRate);
m->max_wageRate = CALC_MAX(cur->wageRate, m->max_wageRate);
m->min_hours = CALC_MIN(cur->hours, m->min_hours);
m->max_hours = CALC_MAX(cur->hours, m->max_hours);
m->min_overtimeHrs = CALC_MIN(cur->overtimeHrs, m->min_overtimeHrs);
m->max_overtimeHrs = CALC_MAX(cur->overtimeHrs, m->max_overtimeHrs);
m->min_grossPay = CALC_MIN(cur->grossPay, m->min_grossPay);
m->max_grossPay = CALC_MAX(cur->grossPay, m->max_grossPay);
m->min_stateTax = CALC_MIN(cur->stateTax, m->min_stateTax);
m->max_stateTax = CALC_MAX(cur->stateTax, m->max_stateTax);
m->min_fedTax = CALC_MIN(cur->fedTax, m->min_fedTax);
m->max_fedTax = CALC_MAX(cur->fedTax, m->max_fedTax);
m->min_netPay = CALC_MIN(cur->netPay, m->min_netPay);
m->max_netPay = CALC_MAX(cur->netPay, m->max_netPay);
}
}
//**************************************************************
void printHeader(void)
{
printf("\n\n*** Pay Calculator ***\n"); printf("\n---------------------------------------------------------------------------------"); printf("\nName Tax Clock# Wage Hours OT Gross State Fed Net"); printf("\n State Pay Tax Tax Pay"); printf("\n---------------------------------------------------------------------------------"); }
//**************************************************************
void printEmp(EMPLOYEE *head_ptr)
{
EMPLOYEE *cur;
char name[30];
for (cur = head_ptr; cur; cur = cur->next)
{
strcpy(name
, cur
->empName.
firstName); strcat(name
, cur
->empName.
lastName);
printf("\n%-20s %-2s %06li %5.2f %4.1f %4.1f %7.2f %6.2f %7.2f %8.2f", name,
cur->taxState,
cur->clockNumber,
cur->wageRate,
cur->hours,
cur->overtimeHrs,
cur->grossPay,
cur->stateTax,
cur->fedTax,
cur->netPay);
}
}
//**************************************************************
void printEmpStatistics(TOTALS *t, MIN_MAX *m, int size)
{
printf("\n---------------------------------------------------------------------------------");
printf("\nTotals: %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("\nAverages: %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("\nMinimum: %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("\nMaximum: %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\nThe total employees processed was: %d\n", size
); }
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDEwIC0gTGlua2VkIExpc3RzLCBUeXBlZGVmLCBhbmQgTWFjcm9zCi8vCi8vIE5hbWU6IEpvaG4gU2VtZW51awovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgU3ByaW5nIDIwMjYKLy8KLy8gRGF0ZTogQXByaWwgMjAsIDIwMjYKLy8KLy8gRGVzY3JpcHRpb246IFByb2dyYW0gd2hpY2ggZGV0ZXJtaW5lcyBvdmVydGltZSBhbmQgCi8vIGdyb3NzIHBheSBmb3IgYSBzZXQgb2YgZW1wbG95ZWVzIHdpdGggb3V0cHV0cyBzZW50IAovLyB0byBzdGFuZGFyZCBvdXRwdXQgKHRoZSBzY3JlZW4pLgovLwovLyBUaGlzIGFzc2lnbm1lbnQgYWxzbyBhZGRzIGVtcGxveWVlIG5hbWUsIHRheCBzdGF0ZSwKLy8gYW5kIGNhbGN1bGF0ZXMgc3RhdGUgdGF4LCBmZWRlcmFsIHRheCwgYW5kIG5ldCBwYXkuCi8vIEl0IGFsc28gY2FsY3VsYXRlcyB0b3RhbHMsIGF2ZXJhZ2VzLCBtaW5pbXVtLCBhbmQgbWF4aW11bS4KLy8KLy8gTGlua2VkIGxpc3QgKyB0eXBlZGVmICsgbWFjcm9zIHZlcnNpb24KLy8KLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgU1REX0hPVVJTIDQwLjAKI2RlZmluZSBPVF9SQVRFIDEuNQoKI2RlZmluZSBNQV9UQVhfUkFURSAwLjA1CiNkZWZpbmUgTkhfVEFYX1JBVEUgMC4wCiNkZWZpbmUgVlRfVEFYX1JBVEUgMC4wNgojZGVmaW5lIENBX1RBWF9SQVRFIDAuMDcKI2RlZmluZSBERUZBVUxUX1NUQVRFX1RBWF9SQVRFIDAuMDgKCiNkZWZpbmUgRkVEX1RBWF9SQVRFIDAuMjUKCiNkZWZpbmUgTkFNRV9TSVpFIDIwCiNkZWZpbmUgVEFYX1NUQVRFX1NJWkUgMwojZGVmaW5lIEZJUlNUX05BTUVfU0laRSAxMAojZGVmaW5lIExBU1RfTkFNRV9TSVpFIDEwCgovLyBNYWNyb3MKI2RlZmluZSBDQUxDX09UX0hPVVJTKHRoZUhvdXJzKSAoKHRoZUhvdXJzID4gU1REX0hPVVJTKSA/ICh0aGVIb3VycyAtIFNURF9IT1VSUykgOiAwKQoKI2RlZmluZSBDQUxDX1NUQVRFX1RBWCh0aGVQYXksdGhlU3RhdGVUYXhSYXRlKSAoKHRoZVBheSkgKiAodGhlU3RhdGVUYXhSYXRlKSkKCi8vIOKchSBGSVhFRCBGRUQgVEFYIE1BQ1JPCiNkZWZpbmUgQ0FMQ19GRURfVEFYKHRoZVBheSkgKCh0aGVQYXkpICogRkVEX1RBWF9SQVRFKQoKI2RlZmluZSBDQUxDX05FVF9QQVkodGhlUGF5LHRoZVN0YXRlVGF4LHRoZUZlZFRheCkgKCh0aGVQYXkpIC0gKCh0aGVTdGF0ZVRheCkgKyAodGhlRmVkVGF4KSkpCgojZGVmaW5lIENBTENfTk9STUFMX1BBWSh0aGVXYWdlUmF0ZSx0aGVIb3Vycyx0aGVPdmVydGltZUhycykgXAooKHRoZVdhZ2VSYXRlKSAqICgodGhlSG91cnMpIC0gKHRoZU92ZXJ0aW1lSHJzKSkpCgojZGVmaW5lIENBTENfT1RfUEFZKHRoZVdhZ2VSYXRlLHRoZU92ZXJ0aW1lSHJzKSBcCigodGhlT3ZlcnRpbWVIcnMpICogKE9UX1JBVEUgKiAodGhlV2FnZVJhdGUpKSkKCi8vIOKchSBGSVhFRCBNSU4vTUFYIE1BQ1JPUwojZGVmaW5lIENBTENfTUlOKHRoZVZhbHVlLCBjdXJyZW50TWluKSAoKCh0aGVWYWx1ZSkgPCAoY3VycmVudE1pbikpID8gKHRoZVZhbHVlKSA6IChjdXJyZW50TWluKSkKI2RlZmluZSBDQUxDX01BWCh0aGVWYWx1ZSwgY3VycmVudE1heCkgKCgodGhlVmFsdWUpID4gKGN1cnJlbnRNYXgpKSA/ICh0aGVWYWx1ZSkgOiAoY3VycmVudE1heCkpCgovLyBzdHJ1Y3R1cmVzCnN0cnVjdCBuYW1lIHsKICAgIGNoYXIgZmlyc3ROYW1lW0ZJUlNUX05BTUVfU0laRV07CiAgICBjaGFyIGxhc3ROYW1lW0xBU1RfTkFNRV9TSVpFXTsKfTsKCnR5cGVkZWYgc3RydWN0IGVtcGxveWVlIHsKICAgIHN0cnVjdCBuYW1lIGVtcE5hbWU7CiAgICBjaGFyIHRheFN0YXRlW1RBWF9TVEFURV9TSVpFXTsKICAgIGxvbmcgaW50IGNsb2NrTnVtYmVyOwogICAgZmxvYXQgd2FnZVJhdGU7CiAgICBmbG9hdCBob3VyczsKICAgIGZsb2F0IG92ZXJ0aW1lSHJzOwogICAgZmxvYXQgZ3Jvc3NQYXk7CiAgICBmbG9hdCBzdGF0ZVRheDsKICAgIGZsb2F0IGZlZFRheDsKICAgIGZsb2F0IG5ldFBheTsKICAgIHN0cnVjdCBlbXBsb3llZSAqbmV4dDsKfSBFTVBMT1lFRTsKCnR5cGVkZWYgc3RydWN0IHRvdGFscyB7CiAgICBmbG9hdCB0b3RhbF93YWdlUmF0ZTsKICAgIGZsb2F0IHRvdGFsX2hvdXJzOwogICAgZmxvYXQgdG90YWxfb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCB0b3RhbF9ncm9zc1BheTsKICAgIGZsb2F0IHRvdGFsX3N0YXRlVGF4OwogICAgZmxvYXQgdG90YWxfZmVkVGF4OwogICAgZmxvYXQgdG90YWxfbmV0UGF5Owp9IFRPVEFMUzsKCi8vIOKchSBNSU5fTUFYIHR5cGVkZWYgYWRkZWQKdHlwZWRlZiBzdHJ1Y3QgbWluX21heCB7CiAgICBmbG9hdCBtaW5fd2FnZVJhdGU7CiAgICBmbG9hdCBtaW5faG91cnM7CiAgICBmbG9hdCBtaW5fb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtaW5fZ3Jvc3NQYXk7CiAgICBmbG9hdCBtaW5fc3RhdGVUYXg7CiAgICBmbG9hdCBtaW5fZmVkVGF4OwogICAgZmxvYXQgbWluX25ldFBheTsKCiAgICBmbG9hdCBtYXhfd2FnZVJhdGU7CiAgICBmbG9hdCBtYXhfaG91cnM7CiAgICBmbG9hdCBtYXhfb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBtYXhfZ3Jvc3NQYXk7CiAgICBmbG9hdCBtYXhfc3RhdGVUYXg7CiAgICBmbG9hdCBtYXhfZmVkVGF4OwogICAgZmxvYXQgbWF4X25ldFBheTsKfSBNSU5fTUFYOwoKLy8gcHJvdG90eXBlcwpFTVBMT1lFRSAqIGdldEVtcERhdGEodm9pZCk7CmludCBpc0VtcGxveWVlU2l6ZShFTVBMT1lFRSAqIGhlYWRfcHRyKTsKdm9pZCBjYWxjT3ZlcnRpbWVIcnMoRU1QTE9ZRUUgKiBoZWFkX3B0cik7CnZvaWQgY2FsY0dyb3NzUGF5KEVNUExPWUVFICogaGVhZF9wdHIpOwp2b2lkIGNhbGNTdGF0ZVRheChFTVBMT1lFRSAqIGhlYWRfcHRyKTsKdm9pZCBjYWxjRmVkVGF4KEVNUExPWUVFICogaGVhZF9wdHIpOwp2b2lkIGNhbGNOZXRQYXkoRU1QTE9ZRUUgKiBoZWFkX3B0cik7Cgp2b2lkIGNhbGNFbXBsb3llZVRvdGFscyhFTVBMT1lFRSAqIGhlYWRfcHRyLCBUT1RBTFMgKiBlbXBfdG90YWxzX3B0cik7Cgp2b2lkIGNhbGNFbXBsb3llZU1pbk1heChFTVBMT1lFRSAqIGhlYWRfcHRyLCBNSU5fTUFYICogZW1wX21pbk1heF9wdHIpOwoKdm9pZCBwcmludEhlYWRlcih2b2lkKTsKdm9pZCBwcmludEVtcChFTVBMT1lFRSAqIGhlYWRfcHRyKTsKCnZvaWQgcHJpbnRFbXBTdGF0aXN0aWNzKFRPVEFMUyAqIGVtcF90b3RhbHNfcHRyLCBNSU5fTUFYICogZW1wX21pbk1heF9wdHIsIGludCBzaXplKTsKCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKaW50IG1haW4oKQp7CiAgICBFTVBMT1lFRSAqaGVhZF9wdHI7CiAgICBpbnQgdGhlU2l6ZTsKCiAgICBUT1RBTFMgZW1wbG95ZWVUb3RhbHMgPSB7MH07CiAgICBUT1RBTFMgKmVtcF90b3RhbHNfcHRyID0gJmVtcGxveWVlVG90YWxzOwoKICAgIE1JTl9NQVggZW1wbG95ZWVNaW5NYXggPSB7MH07CiAgICBNSU5fTUFYICplbXBfbWluTWF4X3B0ciA9ICZlbXBsb3llZU1pbk1heDsKCiAgICBoZWFkX3B0ciA9IGdldEVtcERhdGEoKTsKCiAgICB0aGVTaXplID0gaXNFbXBsb3llZVNpemUoaGVhZF9wdHIpOwoKICAgIGlmICh0aGVTaXplIDw9IDApCiAgICB7CiAgICAgICAgcHJpbnRmKCJcblxuKioqKiBUaGVyZSB3YXMgbm8gZW1wbG95ZWUgaW5wdXQgdG8gcHJvY2VzcyAqKipcbiIpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGNhbGNPdmVydGltZUhycyhoZWFkX3B0cik7CiAgICAgICAgY2FsY0dyb3NzUGF5KGhlYWRfcHRyKTsKICAgICAgICBjYWxjU3RhdGVUYXgoaGVhZF9wdHIpOwogICAgICAgIGNhbGNGZWRUYXgoaGVhZF9wdHIpOwogICAgICAgIGNhbGNOZXRQYXkoaGVhZF9wdHIpOwoKICAgICAgICBjYWxjRW1wbG95ZWVUb3RhbHMoaGVhZF9wdHIsIGVtcF90b3RhbHNfcHRyKTsKICAgICAgICBjYWxjRW1wbG95ZWVNaW5NYXgoaGVhZF9wdHIsIGVtcF9taW5NYXhfcHRyKTsKCiAgICAgICAgcHJpbnRIZWFkZXIoKTsKICAgICAgICBwcmludEVtcChoZWFkX3B0cik7CiAgICAgICAgcHJpbnRFbXBTdGF0aXN0aWNzKGVtcF90b3RhbHNfcHRyLCBlbXBfbWluTWF4X3B0ciwgdGhlU2l6ZSk7CiAgICB9CgogICAgcHJpbnRmKCJcblxuICoqKiBFbmQgb2YgUHJvZ3JhbSAqKiogXG4iKTsKICAgIHJldHVybiAwOwp9CgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCkVNUExPWUVFICogZ2V0RW1wRGF0YSh2b2lkKQp7CiAgICBFTVBMT1lFRSAqaGVhZF9wdHIsICpjdXJyZW50X3B0cjsKICAgIGNoYXIgYW5zd2VyWzEwXTsKICAgIGludCBtb3JlX2RhdGEgPSAxOwoKICAgIGhlYWRfcHRyID0gbWFsbG9jKHNpemVvZihFTVBMT1lFRSkpOwogICAgY3VycmVudF9wdHIgPSBoZWFkX3B0cjsKCiAgICB3aGlsZSAobW9yZV9kYXRhKQogICAgewogICAgICAgIHByaW50ZigiXG5FbnRlciBlbXBsb3llZSBmaXJzdCBuYW1lOiAiKTsKICAgICAgICBzY2FuZigiJXMiLCBjdXJyZW50X3B0ci0+ZW1wTmFtZS5maXJzdE5hbWUpOwoKICAgICAgICBwcmludGYoIlxuRW50ZXIgZW1wbG95ZWUgbGFzdCBuYW1lOiAiKTsKICAgICAgICBzY2FuZigiJXMiLCBjdXJyZW50X3B0ci0+ZW1wTmFtZS5sYXN0TmFtZSk7CgogICAgICAgIHByaW50ZigiXG5FbnRlciBlbXBsb3llZSB0YXggc3RhdGU6ICIpOwogICAgICAgIHNjYW5mKCIlcyIsIGN1cnJlbnRfcHRyLT50YXhTdGF0ZSk7CgogICAgICAgIHByaW50ZigiXG5FbnRlciBjbG9jayBudW1iZXI6ICIpOwogICAgICAgIHNjYW5mKCIlbGkiLCAmY3VycmVudF9wdHItPmNsb2NrTnVtYmVyKTsKCiAgICAgICAgcHJpbnRmKCJcbkVudGVyIHdhZ2UgcmF0ZTogIik7CiAgICAgICAgc2NhbmYoIiVmIiwgJmN1cnJlbnRfcHRyLT53YWdlUmF0ZSk7CgogICAgICAgIHByaW50ZigiXG5FbnRlciBob3VyczogIik7CiAgICAgICAgc2NhbmYoIiVmIiwgJmN1cnJlbnRfcHRyLT5ob3Vycyk7CgogICAgICAgIHByaW50ZigiXG5Bbm90aGVyIGVtcGxveWVlPyAoeS9uKTogIik7CiAgICAgICAgc2NhbmYoIiVzIiwgYW5zd2VyKTsKCiAgICAgICAgaWYgKHRvdXBwZXIoYW5zd2VyWzBdKSAhPSAnWScpCiAgICAgICAgewogICAgICAgICAgICBjdXJyZW50X3B0ci0+bmV4dCA9IE5VTEw7CiAgICAgICAgICAgIG1vcmVfZGF0YSA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGN1cnJlbnRfcHRyLT5uZXh0ID0gbWFsbG9jKHNpemVvZihFTVBMT1lFRSkpOwogICAgICAgICAgICBjdXJyZW50X3B0ciA9IGN1cnJlbnRfcHRyLT5uZXh0OwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaGVhZF9wdHI7Cn0KCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKaW50IGlzRW1wbG95ZWVTaXplKEVNUExPWUVFICpoZWFkX3B0cikKewogICAgaW50IGNvdW50ID0gMDsKICAgIEVNUExPWUVFICpjdXI7CgogICAgZm9yIChjdXIgPSBoZWFkX3B0cjsgY3VyOyBjdXIgPSBjdXItPm5leHQpCiAgICAgICAgY291bnQrKzsKCiAgICByZXR1cm4gY291bnQ7Cn0KCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKdm9pZCBjYWxjT3ZlcnRpbWVIcnMoRU1QTE9ZRUUgKmhlYWRfcHRyKQp7CiAgICBFTVBMT1lFRSAqY3VyOwogICAgZm9yIChjdXIgPSBoZWFkX3B0cjsgY3VyOyBjdXIgPSBjdXItPm5leHQpCiAgICAgICAgY3VyLT5vdmVydGltZUhycyA9IENBTENfT1RfSE9VUlMoY3VyLT5ob3Vycyk7Cn0KCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKdm9pZCBjYWxjR3Jvc3NQYXkoRU1QTE9ZRUUgKmhlYWRfcHRyKQp7CiAgICBFTVBMT1lFRSAqY3VyOwogICAgZmxvYXQgbm9ybWFsLCBvdDsKCiAgICBmb3IgKGN1ciA9IGhlYWRfcHRyOyBjdXI7IGN1ciA9IGN1ci0+bmV4dCkKICAgIHsKICAgICAgICBub3JtYWwgPSBDQUxDX05PUk1BTF9QQVkoY3VyLT53YWdlUmF0ZSwgY3VyLT5ob3VycywgY3VyLT5vdmVydGltZUhycyk7CiAgICAgICAgb3QgPSBDQUxDX09UX1BBWShjdXItPndhZ2VSYXRlLCBjdXItPm92ZXJ0aW1lSHJzKTsKICAgICAgICBjdXItPmdyb3NzUGF5ID0gbm9ybWFsICsgb3Q7CiAgICB9Cn0KCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKdm9pZCBjYWxjU3RhdGVUYXgoRU1QTE9ZRUUgKmhlYWRfcHRyKQp7CiAgICBFTVBMT1lFRSAqY3VyOwoKICAgIGZvciAoY3VyID0gaGVhZF9wdHI7IGN1cjsgY3VyID0gY3VyLT5uZXh0KQogICAgewogICAgICAgIGlmIChzdHJjbXAoY3VyLT50YXhTdGF0ZSwgIk1BIikgPT0gMCkKICAgICAgICAgICAgY3VyLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGN1ci0+Z3Jvc3NQYXksIE1BX1RBWF9SQVRFKTsKICAgICAgICBlbHNlIGlmIChzdHJjbXAoY3VyLT50YXhTdGF0ZSwgIlZUIikgPT0gMCkKICAgICAgICAgICAgY3VyLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGN1ci0+Z3Jvc3NQYXksIFZUX1RBWF9SQVRFKTsKICAgICAgICBlbHNlIGlmIChzdHJjbXAoY3VyLT50YXhTdGF0ZSwgIk5IIikgPT0gMCkKICAgICAgICAgICAgY3VyLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGN1ci0+Z3Jvc3NQYXksIE5IX1RBWF9SQVRFKTsKICAgICAgICBlbHNlIGlmIChzdHJjbXAoY3VyLT50YXhTdGF0ZSwgIkNBIikgPT0gMCkKICAgICAgICAgICAgY3VyLT5zdGF0ZVRheCA9IENBTENfU1RBVEVfVEFYKGN1ci0+Z3Jvc3NQYXksIENBX1RBWF9SQVRFKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGN1ci0+c3RhdGVUYXggPSBDQUxDX1NUQVRFX1RBWChjdXItPmdyb3NzUGF5LCBERUZBVUxUX1NUQVRFX1RBWF9SQVRFKTsKICAgIH0KfQoKLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgp2b2lkIGNhbGNGZWRUYXgoRU1QTE9ZRUUgKmhlYWRfcHRyKQp7CiAgICBFTVBMT1lFRSAqY3VyOwoKICAgIGZvciAoY3VyID0gaGVhZF9wdHI7IGN1cjsgY3VyID0gY3VyLT5uZXh0KQogICAgICAgIGN1ci0+ZmVkVGF4ID0gQ0FMQ19GRURfVEFYKGN1ci0+Z3Jvc3NQYXkpOwp9CgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnZvaWQgY2FsY05ldFBheShFTVBMT1lFRSAqaGVhZF9wdHIpCnsKICAgIEVNUExPWUVFICpjdXI7CgogICAgZm9yIChjdXIgPSBoZWFkX3B0cjsgY3VyOyBjdXIgPSBjdXItPm5leHQpCiAgICAgICAgY3VyLT5uZXRQYXkgPSBDQUxDX05FVF9QQVkoY3VyLT5ncm9zc1BheSwgY3VyLT5zdGF0ZVRheCwgY3VyLT5mZWRUYXgpOwp9CgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnZvaWQgY2FsY0VtcGxveWVlVG90YWxzKEVNUExPWUVFICpoZWFkX3B0ciwgVE9UQUxTICp0KQp7CiAgICBFTVBMT1lFRSAqY3VyOwoKICAgIGZvciAoY3VyID0gaGVhZF9wdHI7IGN1cjsgY3VyID0gY3VyLT5uZXh0KQogICAgewogICAgICAgIHQtPnRvdGFsX3dhZ2VSYXRlICs9IGN1ci0+d2FnZVJhdGU7CiAgICAgICAgdC0+dG90YWxfaG91cnMgKz0gY3VyLT5ob3VyczsKICAgICAgICB0LT50b3RhbF9vdmVydGltZUhycyArPSBjdXItPm92ZXJ0aW1lSHJzOwogICAgICAgIHQtPnRvdGFsX2dyb3NzUGF5ICs9IGN1ci0+Z3Jvc3NQYXk7CiAgICAgICAgdC0+dG90YWxfc3RhdGVUYXggKz0gY3VyLT5zdGF0ZVRheDsKICAgICAgICB0LT50b3RhbF9mZWRUYXggKz0gY3VyLT5mZWRUYXg7CiAgICAgICAgdC0+dG90YWxfbmV0UGF5ICs9IGN1ci0+bmV0UGF5OwogICAgfQp9CgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnZvaWQgY2FsY0VtcGxveWVlTWluTWF4KEVNUExPWUVFICpoZWFkX3B0ciwgTUlOX01BWCAqbSkKewogICAgRU1QTE9ZRUUgKmN1ciA9IGhlYWRfcHRyOwoKICAgIG0tPm1pbl93YWdlUmF0ZSA9IG0tPm1heF93YWdlUmF0ZSA9IGN1ci0+d2FnZVJhdGU7CiAgICBtLT5taW5faG91cnMgPSBtLT5tYXhfaG91cnMgPSBjdXItPmhvdXJzOwogICAgbS0+bWluX292ZXJ0aW1lSHJzID0gbS0+bWF4X292ZXJ0aW1lSHJzID0gY3VyLT5vdmVydGltZUhyczsKICAgIG0tPm1pbl9ncm9zc1BheSA9IG0tPm1heF9ncm9zc1BheSA9IGN1ci0+Z3Jvc3NQYXk7CiAgICBtLT5taW5fc3RhdGVUYXggPSBtLT5tYXhfc3RhdGVUYXggPSBjdXItPnN0YXRlVGF4OwogICAgbS0+bWluX2ZlZFRheCA9IG0tPm1heF9mZWRUYXggPSBjdXItPmZlZFRheDsKICAgIG0tPm1pbl9uZXRQYXkgPSBtLT5tYXhfbmV0UGF5ID0gY3VyLT5uZXRQYXk7CgogICAgY3VyID0gY3VyLT5uZXh0OwoKICAgIGZvciAoOyBjdXI7IGN1ciA9IGN1ci0+bmV4dCkKICAgIHsKICAgICAgICBtLT5taW5fd2FnZVJhdGUgPSBDQUxDX01JTihjdXItPndhZ2VSYXRlLCBtLT5taW5fd2FnZVJhdGUpOwogICAgICAgIG0tPm1heF93YWdlUmF0ZSA9IENBTENfTUFYKGN1ci0+d2FnZVJhdGUsIG0tPm1heF93YWdlUmF0ZSk7CgogICAgICAgIG0tPm1pbl9ob3VycyA9IENBTENfTUlOKGN1ci0+aG91cnMsIG0tPm1pbl9ob3Vycyk7CiAgICAgICAgbS0+bWF4X2hvdXJzID0gQ0FMQ19NQVgoY3VyLT5ob3VycywgbS0+bWF4X2hvdXJzKTsKCiAgICAgICAgbS0+bWluX292ZXJ0aW1lSHJzID0gQ0FMQ19NSU4oY3VyLT5vdmVydGltZUhycywgbS0+bWluX292ZXJ0aW1lSHJzKTsKICAgICAgICBtLT5tYXhfb3ZlcnRpbWVIcnMgPSBDQUxDX01BWChjdXItPm92ZXJ0aW1lSHJzLCBtLT5tYXhfb3ZlcnRpbWVIcnMpOwoKICAgICAgICBtLT5taW5fZ3Jvc3NQYXkgPSBDQUxDX01JTihjdXItPmdyb3NzUGF5LCBtLT5taW5fZ3Jvc3NQYXkpOwogICAgICAgIG0tPm1heF9ncm9zc1BheSA9IENBTENfTUFYKGN1ci0+Z3Jvc3NQYXksIG0tPm1heF9ncm9zc1BheSk7CgogICAgICAgIG0tPm1pbl9zdGF0ZVRheCA9IENBTENfTUlOKGN1ci0+c3RhdGVUYXgsIG0tPm1pbl9zdGF0ZVRheCk7CiAgICAgICAgbS0+bWF4X3N0YXRlVGF4ID0gQ0FMQ19NQVgoY3VyLT5zdGF0ZVRheCwgbS0+bWF4X3N0YXRlVGF4KTsKCiAgICAgICAgbS0+bWluX2ZlZFRheCA9IENBTENfTUlOKGN1ci0+ZmVkVGF4LCBtLT5taW5fZmVkVGF4KTsKICAgICAgICBtLT5tYXhfZmVkVGF4ID0gQ0FMQ19NQVgoY3VyLT5mZWRUYXgsIG0tPm1heF9mZWRUYXgpOwoKICAgICAgICBtLT5taW5fbmV0UGF5ID0gQ0FMQ19NSU4oY3VyLT5uZXRQYXksIG0tPm1pbl9uZXRQYXkpOwogICAgICAgIG0tPm1heF9uZXRQYXkgPSBDQUxDX01BWChjdXItPm5ldFBheSwgbS0+bWF4X25ldFBheSk7CiAgICB9Cn0KCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKdm9pZCBwcmludEhlYWRlcih2b2lkKQp7CiAgICBwcmludGYoIlxuXG4qKiogUGF5IENhbGN1bGF0b3IgKioqXG4iKTsKICAgIHByaW50ZigiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKICAgIHByaW50ZigiXG5OYW1lICAgICAgICAgICAgICAgIFRheCAgQ2xvY2sjICBXYWdlICAgSG91cnMgIE9UICAgR3Jvc3MgICBTdGF0ZSAgRmVkICAgICAgTmV0Iik7CiAgICBwcmludGYoIlxuICAgICAgICAgICAgICAgICAgICBTdGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgIFBheSAgICAgVGF4ICAgIFRheCAgICAgIFBheSIpOwogICAgcHJpbnRmKCJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwp9CgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnZvaWQgcHJpbnRFbXAoRU1QTE9ZRUUgKmhlYWRfcHRyKQp7CiAgICBFTVBMT1lFRSAqY3VyOwogICAgY2hhciBuYW1lWzMwXTsKCiAgICBmb3IgKGN1ciA9IGhlYWRfcHRyOyBjdXI7IGN1ciA9IGN1ci0+bmV4dCkKICAgIHsKICAgICAgICBzdHJjcHkobmFtZSwgY3VyLT5lbXBOYW1lLmZpcnN0TmFtZSk7CiAgICAgICAgc3RyY2F0KG5hbWUsICIgIik7CiAgICAgICAgc3RyY2F0KG5hbWUsIGN1ci0+ZW1wTmFtZS5sYXN0TmFtZSk7CgogICAgICAgIHByaW50ZigiXG4lLTIwcyAlLTJzICAlMDZsaSAgJTUuMmYgICU0LjFmICAlNC4xZiAgJTcuMmYgICU2LjJmICAlNy4yZiAgJTguMmYiLAogICAgICAgICAgICBuYW1lLAogICAgICAgICAgICBjdXItPnRheFN0YXRlLAogICAgICAgICAgICBjdXItPmNsb2NrTnVtYmVyLAogICAgICAgICAgICBjdXItPndhZ2VSYXRlLAogICAgICAgICAgICBjdXItPmhvdXJzLAogICAgICAgICAgICBjdXItPm92ZXJ0aW1lSHJzLAogICAgICAgICAgICBjdXItPmdyb3NzUGF5LAogICAgICAgICAgICBjdXItPnN0YXRlVGF4LAogICAgICAgICAgICBjdXItPmZlZFRheCwKICAgICAgICAgICAgY3VyLT5uZXRQYXkpOwogICAgfQp9CgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnZvaWQgcHJpbnRFbXBTdGF0aXN0aWNzKFRPVEFMUyAqdCwgTUlOX01BWCAqbSwgaW50IHNpemUpCnsKICAgIHByaW50ZigiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKCiAgICBwcmludGYoIlxuVG90YWxzOiAgICAgICAgICAgICAgICAgICAgICAgICAgJTUuMmYgJTUuMWYgJTUuMWYgJTcuMmYgJTYuMmYgJTcuMmYgJTguMmYiLAogICAgICAgIHQtPnRvdGFsX3dhZ2VSYXRlLAogICAgICAgIHQtPnRvdGFsX2hvdXJzLAogICAgICAgIHQtPnRvdGFsX292ZXJ0aW1lSHJzLAogICAgICAgIHQtPnRvdGFsX2dyb3NzUGF5LAogICAgICAgIHQtPnRvdGFsX3N0YXRlVGF4LAogICAgICAgIHQtPnRvdGFsX2ZlZFRheCwKICAgICAgICB0LT50b3RhbF9uZXRQYXkpOwoKICAgIHByaW50ZigiXG5BdmVyYWdlczogICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNS4xZiAlNS4xZiAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgdC0+dG90YWxfd2FnZVJhdGUvc2l6ZSwKICAgICAgICB0LT50b3RhbF9ob3Vycy9zaXplLAogICAgICAgIHQtPnRvdGFsX292ZXJ0aW1lSHJzL3NpemUsCiAgICAgICAgdC0+dG90YWxfZ3Jvc3NQYXkvc2l6ZSwKICAgICAgICB0LT50b3RhbF9zdGF0ZVRheC9zaXplLAogICAgICAgIHQtPnRvdGFsX2ZlZFRheC9zaXplLAogICAgICAgIHQtPnRvdGFsX25ldFBheS9zaXplKTsKCiAgICBwcmludGYoIlxuTWluaW11bTogICAgICAgICAgICAgICAgICAgICAgICAgJTUuMmYgJTUuMWYgJTUuMWYgJTcuMmYgJTYuMmYgJTcuMmYgJTguMmYiLAogICAgICAgIG0tPm1pbl93YWdlUmF0ZSwKICAgICAgICBtLT5taW5faG91cnMsCiAgICAgICAgbS0+bWluX292ZXJ0aW1lSHJzLAogICAgICAgIG0tPm1pbl9ncm9zc1BheSwKICAgICAgICBtLT5taW5fc3RhdGVUYXgsCiAgICAgICAgbS0+bWluX2ZlZFRheCwKICAgICAgICBtLT5taW5fbmV0UGF5KTsKCiAgICBwcmludGYoIlxuTWF4aW11bTogICAgICAgICAgICAgICAgICAgICAgICAgJTUuMmYgJTUuMWYgJTUuMWYgJTcuMmYgJTYuMmYgJTcuMmYgJTguMmYiLAogICAgICAgIG0tPm1heF93YWdlUmF0ZSwKICAgICAgICBtLT5tYXhfaG91cnMsCiAgICAgICAgbS0+bWF4X292ZXJ0aW1lSHJzLAogICAgICAgIG0tPm1heF9ncm9zc1BheSwKICAgICAgICBtLT5tYXhfc3RhdGVUYXgsCiAgICAgICAgbS0+bWF4X2ZlZFRheCwKICAgICAgICBtLT5tYXhfbmV0UGF5KTsKCiAgICBwcmludGYoIlxuXG5UaGUgdG90YWwgZW1wbG95ZWVzIHByb2Nlc3NlZCB3YXM6ICVkXG4iLCBzaXplKTsKfQ==