From dc4eca7285226416652679822f3c03042ee4c39a Mon Sep 17 00:00:00 2001 From: cdez Date: Tue, 30 Jan 2024 03:07:38 -0700 Subject: [PATCH] Sim1 Complete up until Step 5 +- .gitignore ++ Sim01 Files ++ SimTimer stuff ++ SimProgGen --- .gitignore | 3 + ProgramGenerator_Project.zip | Bin 0 -> 15030 bytes ProgramGenerator_Project/proggen | Bin 0 -> 17322 bytes ProgramGenerator_Project/proggen.c | 397 +++++++++++++++ ProgramGenerator_Project/proggen.h | 27 ++ ProgramGenerator_Project/proggen_mf | 14 + ProgramGenerator_Project/testfile.mdf | 40 ++ Sim01/OS_SimDriver.c | 246 ++++++++++ Sim01/OS_SimDriver.h | 74 +++ Sim01/StandardConstants.h | 73 +++ Sim01/StringUtils.c | 454 ++++++++++++++++++ Sim01/StringUtils.h | 176 +++++++ Sim01/configops.c | 53 ++ Sim01/configops.h | 50 ++ Sim01/metadataops.c | 56 +++ Sim01/metadataops.h | 53 ++ Sim01/sim01_mf | 29 ++ Sim01/simulator.c | 19 + Sim01/simulator.h | 19 + Sim01_GradingForm_v01.xlsx | Bin 0 -> 18524 bytes ...1_Specifications_Spring24_v01-Trimmed.docx | Bin 0 -> 40571 bytes Sim01_Specifications_Spring24_v01.docx | Bin 0 -> 54028 bytes SimTimerCode.zip | Bin 0 -> 2483 bytes SimTimerCode/simtimer.c | 231 +++++++++ SimTimerCode/simtimer.h | 45 ++ 25 files changed, 2059 insertions(+) create mode 100644 ProgramGenerator_Project.zip create mode 100644 ProgramGenerator_Project/proggen create mode 100644 ProgramGenerator_Project/proggen.c create mode 100644 ProgramGenerator_Project/proggen.h create mode 100644 ProgramGenerator_Project/proggen_mf create mode 100644 ProgramGenerator_Project/testfile.mdf create mode 100644 Sim01/OS_SimDriver.c create mode 100644 Sim01/OS_SimDriver.h create mode 100644 Sim01/StandardConstants.h create mode 100644 Sim01/StringUtils.c create mode 100644 Sim01/StringUtils.h create mode 100644 Sim01/configops.c create mode 100644 Sim01/configops.h create mode 100644 Sim01/metadataops.c create mode 100644 Sim01/metadataops.h create mode 100644 Sim01/sim01_mf create mode 100644 Sim01/simulator.c create mode 100644 Sim01/simulator.h create mode 100644 Sim01_GradingForm_v01.xlsx create mode 100644 Sim01_Specifications_Spring24_v01-Trimmed.docx create mode 100644 Sim01_Specifications_Spring24_v01.docx create mode 100644 SimTimerCode.zip create mode 100644 SimTimerCode/simtimer.c create mode 100644 SimTimerCode/simtimer.h diff --git a/.gitignore b/.gitignore index a29abfb..35346cd 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,6 @@ compile_commands.json CTestTestfile.cmake _deps +# Text Docs +*.txt + diff --git a/ProgramGenerator_Project.zip b/ProgramGenerator_Project.zip new file mode 100644 index 0000000000000000000000000000000000000000..afcf6afb7ac9a1da7b53ec80d98b5666fcaedcee GIT binary patch literal 15030 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 +#include +#include +#include +#include "proggen.h" + +// main program +int main() + { + // initialize program + + // initialize variables + int procPercentage, numOps, numPrograms; + int progCtr, opCtr; + char fileName[ STD_STR_LEN ]; + FILE *outFilePtr; + char opString[ STD_STR_LEN ]; + char tempString[ STD_STR_LEN ]; + + // initialize random generator + // function: srand + srand( time( NULL ) ); + + // show title + // function: printf + printf( "Program Meta-Data Creation Program\n\n" ); + + // get file name for meta-data file + // function: printf, scanf + printf( "Enter file name to use: " ); + scanf( "%s", fileName ); + + // get weight of processing + // function: printf, scanf + printf( "Enter percentage of processing: " ); + scanf( "%d", &procPercentage ); + + // get number of actions + // function: printf, scanf + printf( "Enter number of operations per program: " ); + scanf( "%d", &numOps ); + + // get number of programs to generate + // function: printf, scanf + printf( "Enter number of programs: " ); + scanf( "%d", &numPrograms ); + + // open file + // function: fopen + outFilePtr = fopen( fileName, "w" ); + + // output file description header + // function: fputs + fputs( "Start Program Meta-Data Code:\r\n", outFilePtr ); + + // set temporary string with string literal + // function: strcpy + strcpy( tempString, "sys start\r\n" ); + + // output Operating System start + // function: fputs + fputs( tempString, outFilePtr ); + + // loop across number of programs + for( progCtr = 0; progCtr < numPrograms; progCtr++ ) + { + // set temporary string with string literal + // function: strcpy + strcpy( tempString, "app start, 0\r\n" ); + + // show begin of program + // function: fputs + fputs( tempString, outFilePtr ); + + // get new op, force first item to be input + // function: getNewOp + getNewOp( procPercentage, opString, True ); + + // loop across number of operations + for( opCtr = 0; opCtr < numOps; opCtr++ ) + { + // output new op + // function: fputs + fputs( opString, outFilePtr ); + + // get new op + // function: getNewOp + getNewOp( procPercentage, opString, False ); + } + // end loop across number of operations + + // set temporary string with string literal + // function: strcpy + strcpy( tempString, "app end\r\n" ); + + // add end of program + // function: fputs + fputs( tempString, outFilePtr ); + } + // end number of programs loop + + // set temporary string with string literal + // function: strcpy + strcpy( tempString, "sys end\r\n" ); + + // output end of operating system + // function: fputs + fputs( tempString, outFilePtr ); + + // output file description header + // function: fputs + fputs( "End Program Meta-Data Code.\n\n", outFilePtr ); + + // close file + // function: fclose + fclose( outFilePtr ); + + // shut down program + + // return success + return 0; + } + +// supporting function implementations + +int getRandBetween( int low, int high ) + { + // initialize range + int range = high - low + 1; + + // set random result and return + // function: rand + return rand() % range + low; + } + +Boolean getOdds( int oddPercent ) + { + // initialize odds + // function: rand + int randVal = rand() % 100 + 1; + + // check for odds less than/equal to specification + if( randVal <= oddPercent ) + { + // return true + return True; + } + + // otherwise, if odds not met, return false + return False; + } + +void getNewOp( int percent, char opStr[], Boolean firstOpFlag ) + { + // initialize recursive start index + int recStartIndex = 0; + int selectionChance = 25; // roughly 1 in 7 chance + + // initialize speedFactor to 1, for processor + // speedFactor makes I/O devices relatively slower than the processor + // - although not as relatively slow as they would really be + int speedFactor = 1; + + // declare other variables + int numCycles; + char numStr[ STD_STR_LEN ]; + + // check for chance of processing + // function: getOdds + if( firstOpFlag == False && getOdds( percent ) == True ) + { + // place a processing action + // function: strcpy + strcpy( opStr, "cpu process, " ); + } + + // otherwise, assume some kind of I/O + else + { + // check for first I/O operations, or chance of input operation + // function: getOdds + if( firstOpFlag == True + || getOdds( INPUT_CHANCE ) == True ) // input process + { + // check for odds of Ethernet + if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev in, ethernet, " ); + + // 10x slower than processor + speedFactor = 2; + } + + // check for odds of hard drive + // function: getOdds + if( getOdds( selectionChance ) == True ) + { + // place a hard drive operation + // function: strcpy + strcpy( opStr, "dev in, hard drive, " ); + + // 3x slower than processor + speedFactor = 3; + } + + // otherwise, assume keyboard + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev in, keyboard, " ); + + // 10x slower than processor + speedFactor = 10; + } + + // otherwise, assume serial + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev in, serial, " ); + + // 10x slower than processor + speedFactor = 4; + } + + // otherwise, assume sound signal + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev in, sound signal, " ); + + // 10x slower than processor + speedFactor = 5; + } + + // otherwise, assume USB + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev in, usb, " ); + + // 10x slower than processor + speedFactor = 2; + } + + // otherwise, assume video signal + else + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev in, video signal, " ); + + // 10x slower than processor + speedFactor = 7; + } + } + + // otherwise, assume output operation + else + { + // check for odds of Ethernet + if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev out, ethernet, " ); + + // 10x slower than processor + speedFactor = 2; + } + + // check for odds of hard drive + // function: getOdds + if( getOdds( selectionChance ) == True ) + { + // place a hard drive operation + // function: strcpy + strcpy( opStr, "dev out, hard drive, " ); + + // 3x slower than processor + speedFactor = 3; + } + + // otherwise, assume keyboard + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev out, monitor, " ); + + // 10x slower than processor + speedFactor = 10; + } + + // otherwise, assume serial + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev out, serial, " ); + + // 10x slower than processor + speedFactor = 4; + } + + // otherwise, assume sound signal + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev out, sound signal, " ); + + // 10x slower than processor + speedFactor = 5; + } + + // otherwise, assume USB + else if( getOdds( selectionChance ) == True ) + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev out, usb, " ); + + // 10x slower than processor + speedFactor = 2; + } + + // otherwise, assume video signal + else + { + // place a keyboard operation + // function: strcpy + strcpy( opStr, "dev out, video signal, " ); + + // 10x slower than processor + speedFactor = 7; + } + } + } + + // find random number of I/O cycles + // function: getRandBetween + numCycles = getRandBetween( OPTIME_MIN, OPTIME_MAX ) * speedFactor; + + // set number as string + // function: intToString + intToString( numCycles, numStr, recStartIndex ); + + // append string number to metadata item, with endlines + // function: strcat + strcat( opStr, numStr ); + + strcat( opStr, "\r\n" ); + + } + +int intToString( int value, char valStr[], int index ) + { + // initialize function, variables + char digit; + + // check for digits remaining + if( value > 0 ) + { + // convert digit to character + digit = (char) ( value % 10 + '0' ); + + // call recursive function to get next digt + // function: intToString + index = intToString( value / 10, valStr, index + 1 ); + } + + // otherwise, assume no digits remaining + else + { + // end string with NULL_CHAR + valStr[ index ] = NULL_CHAR; + + // return uncounted character + return 0; + } + + // add character to string + valStr[ index ] = digit; + + // return updated string length + return index + 1; + } + + diff --git a/ProgramGenerator_Project/proggen.h b/ProgramGenerator_Project/proggen.h new file mode 100644 index 0000000..166831f --- /dev/null +++ b/ProgramGenerator_Project/proggen.h @@ -0,0 +1,27 @@ +// Header file for proggen.c + +// Precompiler directive, to eliminate multiple compiles of h file +#ifndef PROGGEN_H +#define PROGGEN_H + +// global constants + +const int STD_STR_LEN = 45; +const int INPUT_CHANCE = 40; +const int OPTIME_MAX = 10; +const int OPTIME_MIN = 5; +const char NULL_CHAR = '\0'; +const char ENDLINE_CHAR[] = "\n"; + +typedef enum { False, True } Boolean; + +// function prototypes + +void getNewOp( int percent, char opStr[], Boolean firstOpFlag ); +Boolean getOdds( int oddPercent ); +int getRandBetween( int low, int high ); +int intToString( int value, char valStr[], int index ); + +#endif // PROGGEN_H + + diff --git a/ProgramGenerator_Project/proggen_mf b/ProgramGenerator_Project/proggen_mf new file mode 100644 index 0000000..d88c9d9 --- /dev/null +++ b/ProgramGenerator_Project/proggen_mf @@ -0,0 +1,14 @@ +CC = gcc +DEBUG = -g +CFLAGS = -Wall -std=c99 -pedantic -c $(DEBUG) +LFLAGS = -Wall -std=c99 -pedantic $(DEBUG) + +proggen : proggen.o + $(CC) $(LFLAGS) proggen.o -o proggen + +proggen.o : proggen.c proggen.h + $(CC) $(CFLAGS) proggen.c + +clean: + \rm *.o proggen + diff --git a/ProgramGenerator_Project/testfile.mdf b/ProgramGenerator_Project/testfile.mdf new file mode 100644 index 0000000..b8da714 --- /dev/null +++ b/ProgramGenerator_Project/testfile.mdf @@ -0,0 +1,40 @@ +Start Program Meta-Data Code: +sys start +app start, 0 +dev in, hard drive, 18 +cpu process, 9 +cpu process, 9 +cpu process, 9 +dev out, monitor, 60 +app end +app start, 0 +dev in, sound signal, 40 +dev in, hard drive, 30 +dev in, sound signal, 25 +cpu process, 6 +dev out, usb, 10 +app end +app start, 0 +dev in, video signal, 70 +cpu process, 10 +dev out, monitor, 70 +dev in, hard drive, 18 +cpu process, 9 +app end +app start, 0 +dev in, sound signal, 35 +dev out, monitor, 100 +dev in, keyboard, 50 +cpu process, 9 +dev out, video signal, 49 +app end +app start, 0 +dev in, keyboard, 90 +dev out, sound signal, 40 +dev out, serial, 32 +cpu process, 10 +dev in, hard drive, 15 +app end +sys end +End Program Meta-Data Code. + diff --git a/Sim01/OS_SimDriver.c b/Sim01/OS_SimDriver.c new file mode 100644 index 0000000..7d1fbf0 --- /dev/null +++ b/Sim01/OS_SimDriver.c @@ -0,0 +1,246 @@ +// header files +#include "OS_SimDriver.h" + +int main(int argc, char **argv) +{ + // initialize program (variables and title) + ConfigDataType *configDataPtr = NULL; + OpCodeType *metaDataPtr = NULL; + char errorMsg[MAX_STR_LEN]; + CmdLineData cmdLineData; + bool configUploadSuccess = false; + + // show title + // fct: printf + printf("\nSimulator Program\n"); + printf("=================\n\n"); + + // process command line arguments + // check for at least one correct switch and config file name verified + // fct: processCmdLine + if(processCmdLine(argc, argv, &cmdLineData)) + { + // upload config file, check for success + // fct: getConfigData + if(getConfigData(cmdLineData.fileName, &configDataPtr, errorMsg)) + { + // check for config display flag + if(cmdLineData.configDisplayFlag) + { + // display config display flag + // fct: displayConfigData + displayConfigData(configDataPtr); + } + // set config upload success flag + configUploadSuccess = true; + } + // otherwise, assume config file upload failure + else + { + // show error message, end program + // fct: printf + printf("\nConfig Upload Error: %s, program aborted\n\n", errorMsg); + } + + // check for config success and need for metadata + if(configUploadSuccess && + (cmdLineData.mdDisplayFlag || cmdLineData.runSimFlag)) + { + // upload metadata file, check for success + // fct: getMetaData + if(getMetaData(configDataPtr->metaDataFileName, + &metaDataPtr, errorMsg)) + { + // check metadata display flag + if(cmdLineData.mdDisplayFlag) + { + // display metadata + // fct: displayMetaData + displayMetaData(metaDataPtr); + } + // check run simulator flag + if(cmdLineData.runSimFlag) + { + // run simulator + // fct: runSim + runSim(configDataPtr, metaDataPtr); + } + + } + // otherwise, assume metadata upload failure + else + { + // show error message, end program + // fct: printf + printf("\nMetadata Upload Error: %s, program aborted\n", + errorMsg); + } + } + // end check for config success and need for metadata + + // clean up config data as needed + // fct: clearConfigData + configDataPtr = clearConfigData(configDataPtr); + + // clean up metadata as needed + // fct: clearMetaDataList + metaDataPtr = clearMetaDataList(metaDataPtr); + } + // end process command line arguments + + // otherwise, assume command line failure + else + { + // show command line argument requirements + // fct: showCommandLineFormat + showCommandLineFormat(); + } + // show program end + // fct: printf + printf("\nSimulator Program End.\n"); + + // return program success + return 0; +} + +/* +Name: clearCmdLineStruct +Process: sets command line structure data to defaults + Booleans to false, fileName to empty string +Function Input/Parameters: pointer to command line structure (CmdLineData *) +Function Output/Parameters: pointer to command line structure (CmdLineData *) + with updated members +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: none +*/ +void clearCmdLineStruct(CmdLineData *clDataPtr) +{ + // set all struct members to default + clDataPtr->programRunFlag = false; + clDataPtr->configDisplayFlag = false; + clDataPtr->mdDisplayFlag = false; + clDataPtr->runSimFlag = false; + clDataPtr->fileName[0] = NULL_CHAR; + // void function, no return. +} + +/* +Name: processCmdLine +Process: checks for at least two arguments, + then sets Booleans depending on command line switches + which can be in any order, + also captures config file name which must be last arugment +Function Input/Parameters: number of arguments (int), + vector of arguments (char **) +Function Output/Parameters: pointer to command line structure (CmdLineData *) + with updated members, + set to default values if failure + to capture arguments +Function Output/Returned: Boolean result of argument capture + true if at least one switch and config file name, + false otherwise +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +bool processCmdLine(int numArgs, char **strVector, CmdLineData *clDataPtr) +{ + // initialize function and variables + + // initialize structure to defaults + // fct: clearCmdLineStruct + clearCmdLineStruct(clDataPtr); + // initialize success flags to false + bool atLeastOneSwitchFlag = false; + bool correctConfigFileFlag = false; + // initialize first arg index to one + int argIndex = 1; + // iniitialize file variables + int fileStrLen, fileStrSubLoc; + // must have program name, one switch, config file name at minimum + if(numArgs >= MIN_NUM_ARGS) + { + // loop across args (starting at 1) and program run flag + while(argIndex < numArgs) + { + // check for -dc + if(compareString(strVector[argIndex], "-dc") == 0) + { + // set config display flag + clDataPtr->configDisplayFlag = true; + // set at least one switch flag + atLeastOneSwitchFlag = true; + } + // otherwise, check for -dm + else if(compareString(strVector[argIndex], "-dm") == 0) + { + // set metadata display flag + clDataPtr->mdDisplayFlag = true; + // set at least one switch flag + atLeastOneSwitchFlag = true; + } + // otherwise, check for -rs + else if(compareString(strVector[argIndex], "-rs") == 0) + { + // set run simulator flag + clDataPtr->runSimFlag = true; + // set at least one switch flag + atLeastOneSwitchFlag = true; + } + // otherwise, check for file name, ending in .cfg (must be last) + else + { + // find lengths to verify file name + // file name must be last argument, have '.cnf' extension + fileStrLen = getStringLength(strVector[numArgs - 1]); + fileStrSubLoc = findSubString(strVector[numArgs - 1], ".cnf"); + // check for file existence and correct file format + if(fileStrSubLoc != SUBSTRING_NOT_FOUND && + fileStrSubLoc == fileStrLen - LAST_FOUR_LETTERS) + { + // set file name to variable + copyString(clDataPtr->fileName, strVector[numArgs - 1]); + // set success flag to true + correctConfigFileFlag = true; + } + // otherwise, assume bad config file name + else + { + // reset struct, correct config file flag stays false + // fct: clearCmdLineStruct + clearCmdLineStruct(clDataPtr); + } + } + // update arg index + argIndex = argIndex + 1; + } + // end loop across args and program run flag + } + // return verification of at least one switch and file name + return atLeastOneSwitchFlag && correctConfigFileFlag; +} + +/* +Name: showCommandLineFormat +Process: displays command line format as assistance to user +Function Input/Parameters: none +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Monitor: data displayed as spec'd +Dependencies: printf +*/ +void showCommandLineFormat() +{ + // display command line format + // fct: printf + printf("Command Line Format:\n"); + printf(" sim_01 [-dc] [-dm] [-rs] \n"); + printf(" -dc [optional] displays configuration data\n"); + printf(" -dm [optional] displays metadata\n"); + printf(" -rs [optional] runs the simulator\n"); + printf(" required configfile.cnf\n"); + // void function, no return. +} \ No newline at end of file diff --git a/Sim01/OS_SimDriver.h b/Sim01/OS_SimDriver.h new file mode 100644 index 0000000..27a3529 --- /dev/null +++ b/Sim01/OS_SimDriver.h @@ -0,0 +1,74 @@ +#ifndef OS_DRIVER +#define OS_DRIVER + +// header files +#include +#include "StringUtils.h" +#include "configops.h" +#include "metadataops.h" +#include "simulator.h" +// ??? #include "datatypes.h" + +// program constants +typedef enum {SUBSTRING_NOT_FOUND = 0, MIN_NUM_ARGS = 3, LAST_FOUR_LETTERS = 4} PRG_CONSTANTS; + +typedef struct CmdLineDataStruct +{ + bool programRunFlag; + bool configDisplayFlag; + bool mdDisplayFlag; + bool runSimFlag; + char fileName[STD_STR_LEN]; +} CmdLineData; + + +// function prototypes + +/* +Name: clearCmdLineStruct +Process: sets command line structure data to defaults + Booleans to false, fileName to empty string +Function Input/Parameters: pointer to command line structure (CmdLineData *) +Function Output/Parameters: pointer to command line structure (CmdLineData *) + with updated members +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: none +*/ +void clearCmdLineStruct(CmdLineData *clDataPtr); + +/* +Name: processCmdLine +Process: checks for at least two arguments, + then sets Booleans depending on command line switches + which can be in any order, + also captures config file name which must be last arugment +Function Input/Parameters: number of arguments (int), + vector of arguments (char **) +Function Output/Parameters: pointer to command line structure (CmdLineData *) + with updated members, + set to default values if failure + to capture arguments +Function Output/Returned: Boolean result of argument capture + true if at least one switch and config file name, + false otherwise +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +bool processCmdLine(int numArgs, char **strVector, CmdLineData *clDataPtr); + +/* +Name: showCommandLineFormat +Process: displays command line format as assistance to user +Function Input/Parameters: none +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Monitor: data displayed as spec'd +Dependencies: printf +*/ +void showCommandLineFormat(); + +#endif //OS_DRIVER \ No newline at end of file diff --git a/Sim01/StandardConstants.h b/Sim01/StandardConstants.h new file mode 100644 index 0000000..e536c24 --- /dev/null +++ b/Sim01/StandardConstants.h @@ -0,0 +1,73 @@ +// Preprocessor directives +#ifndef STANDARD_CONSTANTS_H +#define STANDARD_CONSTANTS_H + +// Include Boolean +#include + +// global constants + +// constant for end of c-string null character +#define CARRIAGE_RETURN_CHAR '\r' + +//constant for a COLON +#define COLON ':' + +//constant for a COMMA +#define COMMA ',' + +//Constant to print a dash +#define DASH '-' + +// highest printable character +#define HIGHEST_PRINTABLE_CHAR '~' + +// constant for huge string length +#define HUGE_STR_LEN 256 + +// lowest printable character +#define LOWEST_PRINTABLE_CHAR ' ' + +// constant for small string length +#define MIN_STR_LEN 32 + +// constant for maximum string length +#define MAX_STR_LEN 128 + +// constant for end of c-string null character +#define NEWLINE_CHAR '\n' + +// first non-printable above ASCII +#define DELETE_KEY 127 + +// constant for end of c-string null character +#define NULL_CHAR '\0' + +// columns found in grade sheet before grading columns +#define NUM_BASE_COLS 5 + +// constant for number of grading frequency bins +#define NUM_FREQUENCY_BINS 10 + +//Constant for printing a pipe +#define PIPE '|' + +//Constant for a period +#define PERIOD '.' + +//Constant for PRECISION, 2 digits +#define PRECISION_2 2 + +//Constant for PRECISION, 4 digits +#define PRECISION_4 4 + +// constant for space character +#define SPACE ' ' + +// constant for standard string length +#define STD_STR_LEN 64 + +// constant for smallest string length +#define TINY_STR_LEN 16 + +#endif // STANDARD_CONSTANTS diff --git a/Sim01/StringUtils.c b/Sim01/StringUtils.c new file mode 100644 index 0000000..b4a55bf --- /dev/null +++ b/Sim01/StringUtils.c @@ -0,0 +1,454 @@ +// header files +#include "StringUtils.h" + +// global constants +const int SUBSTRING_NOT_FOUND = 0; + +// list of utils: + // string length + // getStringLength + // string copy + // copyString + // string concatenate + // catString + // string compare (<, >, =) + // compareString + // string substring get + // getSubString + // string substring find + // findSubString + // string set to lower + // toLowerCase + // string get to delimiter + // stringDelimiter + // string get to end of line + // stringEOL + +// function implementations + +/* +Name: catString +Process: concatenates two strings +Function input/parameters: c-style string (char *) +Function output/parameters: c-style string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: malloc, free, getStringLength +*/ +void catString(char *outString, const char *inString) +{ + // initialize variables + // set dest index + int destIndex = getStringLength(outString); + // set source str length + int sourceStrLen = getStringLength(inString); + // create temp string pointer + char *tempString; + int sourceIndex = 0; + + // copy source string in case of aliasing + tempString = (char *)malloc(sizeof(char) * sourceStrLen); + copyString(tempString, inString); + + // loop to end of source string + while(tempString[sourceIndex] != NULL_CHAR) + { + // assign characters to end of destination string + outString[destIndex] = inString[sourceIndex]; + // update indices + destIndex = destIndex + 1; + sourceIndex = sourceIndex + 1; + } + // end loop to end of source string + // set temporary end of destination string + outString[destIndex] = NULL_CHAR; + + // release memory used for temp string + free(tempString); + + // no return, void. +} + +/* +Name: compareString +Process: compares two strings as follows: + - if left string is alphabetically greater than the right string, + returns value greater than zero + - if left string is alphabetically less than the right string, + returns value less than zero + - if strings are alphabetically equal but one is longer, + longer one is greater + - otherwise, returns zero +Function input/parameters: c-style strings (char *) [first and second/left&right] +Function output/parameters: NONE +Function output/returned: results as specfifed above (int) +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength +*/ +int compareString(const char *firstString, const char *secondString) +{ + // initialize variables + int diff, index = 0; + + // loop to end of string (within bounds) + while(firstString[index] != NULL_CHAR && secondString[index] != NULL_CHAR) + { + // get diff of characters + diff = firstString[index] - secondString[index]; + // check diff of characters + if(diff != 0) + { + // return diff + return diff; + } + // increment index + index = index + 1; + } + // end loop to end of string + + // return difference in length of strings, if needed + return getStringLength(firstString) - getStringLength(secondString); +} + +/* +Name: copyString +Process: copies string into new string variable, overwrites destination. +Function input/parameters: c-style string (char *) +Function output/parameters: c-style string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength +*/ +void copyString(char *outString, const char *inString) +{ + // initialize variables + int index = 0; + + // check to see if outString is not the same as inString. + if(outString != inString) + { + // loop to end of inString + while(inString[index] != NULL_CHAR) + { + // assign characters to end of outString + outString[index] = inString[index]; + // increment index + index = index + 1; + } + // end loop to end of inString + // set end of the outString + outString[index] = NULL_CHAR; + } + + // no return, void. +} + +/* +Name: findSubString +Process: linear search for given substring within another string +Function input/parameters: c-style test string (char *), + c-style source string (char *) +Function output/parameters: NONE +Function output/returned: index of found substring, or + SUBSTRING_NOT_FOUND constant + if string not found +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength +*/ +int findSubString(const char *testStr, const char *searchSubStr) +{ + // initialize variables + // initialize test string length + int testStrLength = getStringLength(testStr); + // initialize master index (location of substring start point) + int masterIndex = 0; + int searchIndex, internalIndex; + + // loop across testStr + while(masterIndex < testStrLength) + { + // set internal loop index to current test string index + internalIndex = masterIndex; + // set internal search index to zero + searchIndex = 0; + // loop to end of testStr + // while testStr/searchSubStr characters are the same + while(internalIndex <= testStrLength && + testStr[internalIndex] == searchSubStr[searchIndex]) + { + // increment testStr and substring indices + internalIndex = internalIndex + 1; + searchIndex = searchIndex + 1; + // check for end of substring (search complete) + if(searchSubStr[searchIndex] == NULL_CHAR) + { + // return beginning location of substring + return masterIndex; + } + } + // end while testStr/searchSubStr characters are the same + // increment current location starting index + masterIndex = masterIndex + 1; + } + // end loop across testStr + + // return SUBSTRING_NOT_FOUND + return SUBSTRING_NOT_FOUND; +} + +/* +Name: getStringConstrained +Process: captures a string from the file stream with various constraints +Function input/parameters: input stream (FILE *), + clears leading non printable (bool), + clears leading space (bool), + stops at non printable (bool), + stops at specified delimiter (char) + will consume the delimiter. +Function output/parameters: c-style string (char *) +Function output/returned: success of operation (bool) +Device input/---: NONE +Device output/---: NONE +Dependencies: fgetc +*/ +bool getStringConstrained(FILE *inStream, bool clearLeadingNonPrintable, + bool clearLeadingSpace, bool stopAtNonPrintable, + char delimiter, char *capString) +{ + // initialize variables + int intChar = EOF, index = 0; + + // initialize output string + capString[index] = NULL_CHAR; + // capture first value in stream using fgetc + intChar = fgetc(inStream); + // loop to clear non-printable or space if indicated + while((((intChar != EOF) && + (clearLeadingNonPrintable && (intChar < (int)SPACE))) + || (clearLeadingSpace && (intChar == (int)SPACE)))) + { + // get next character in stream using fgetc + intChar = fgetc(inStream); + } + // end loop to clear non-printable or space if indicated + // check for end of file found + if(intChar == EOF) + { + // return false (failed) + return false; + } + // loop to get input from file stream + while(((intChar != EOF && index < MAX_STR_LEN - 1) && + (stopAtNonPrintable && intChar >= (int)SPACE)) + || ((!stopAtNonPrintable) && (intChar != (char)delimiter))) + { + // [continues if not at end of file and max string len not reached ] + // [AND continues if not printable flag set and characters printable ] + // [OR continues if not printable flag not set ] + // [AND continues if specified delimited is not found ] + + // place character in array element + capString[index] = (char)intChar; + // increment array index + index = index + 1; + // set next element to null character + capString[index] = NULL_CHAR; + // get next character as integer using fgetc + intChar = fgetc(inStream); + } + // end loop to get input from file stream + // return success + return true; +} + +/* +Name: getStringLength +Process: gets length of string from start to NULL_CHAR ('\0') +Function input/parameters: c-style string (char *) +Function output/parameters: NONE +Function output/returned: length of string (int) +Device input/---: NONE +Device output/---: NONE +Dependencies: included by standard libraries +*/ +int getStringLength(const char *stringIn) +{ + // define variables + int stringLength = 0, currentCharacter = 0; + // get user input (not needed) + // do calculations + while (currentCharacter < STD_STR_LEN && stringIn[currentCharacter] != NULL_CHAR) + { + // increment string length + stringLength = stringLength + 1; + // increment currentCharacter + currentCharacter = currentCharacter + 1; + } + // display results (not needed) + // return success + return stringLength; +} + +/* +Name: getStringToDelimiter +Process: captures a string from the input stream to a specified delimiter. + will consume the delimiter. +Function input/parameters: input stream (FILE *), + stops at specified character +Function output/parameters: c-style string (char *) +Function output/returned: success of operation (bool) +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringConstrained +*/ +bool getStringToDelimiter(FILE *inStream, char delimiter, char *capString) +{ + // use getStringConstrained with delimiter to get string + return getStringConstrained(inStream, true, true, true, delimiter, capString); +} + +/* +Name: getStringToLineEnd +Process: captures a string from the input stream to the end of the line +Function input/parameters: input file stream (FILE *) +Function output/parameters: c-style string (char *) +Function output/returned: success of operation (bool) +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringConstrained +*/ +bool getStringToLineEnd(FILE *inStream, char *capString) +{ + // use getStringConstrained with line end character to get string + return getStringConstrained(inStream, true, true, true, '\n', capString); +} + +/* +Name: getSubString +Process: captures sub string within larger string + between two inclusive indices. + returns empty string if either index is out of range, + assumes enough memory in dest string +Function input/parameters: c-style string (char *) + start and end indices (int) +Function output/parameters: c-style destination string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength, malloc, copyString, free +*/ +void getSubString(char *destStr, const char *sourceStr, + int startIndex, int endIndex) +{ + // initialize variables + // set length of source string using getStringLength + int sourceStrLen = getStringLength(sourceStr); + // initialize the destination index to zero + int destIndex = 0; + // initialize source index to start index (parameter) + int sourceIndex = startIndex; + // create pointer for temp string + char *tempStr; + + // check for indices within limits + if(startIndex >= 0 && startIndex <= endIndex && endIndex < sourceStrLen) + { + // create temp string using malloc and copyString + tempStr = (char *)malloc(sourceStrLen + 1); + copyString(tempStr, sourceStr); + // loop across requested substring indices + while(sourceIndex <= endIndex) + { + // assign source character to destination element + destStr[destIndex] = tempStr[sourceIndex]; + // increment indices + destIndex = destIndex + 1; + sourceIndex = sourceIndex + 1; + // set temporary end of destination string + destStr[destIndex] = NULL_CHAR; + } + // end loop across requested substring indices + // free temp string + free(tempStr); + } + + // no return, void. +} + +/* +Name: strToLowerCase +Process: iterates through string, sets any uppercase letter to lowercase + equivalent, does not affect any letter with an upper/lower diff. +Function input/parameters: c-style source string (char *) +Function output/parameters: c-style dest string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: toLowerCase +*/ +void strToLowerCase(char *outString, const char *inString) +{ + // initialize variables + // get source string length + int sourceStrLen = getStringLength(inString); + // create temporary string pointer + char *tempStr; + int index = 0; + + // copy source string in case of aliasing using malloc and copyString + tempStr = (char *)malloc((sizeof(char) * (sourceStrLen + 1))); + copyString(tempStr, inString); + // loop across source string + while(tempStr[index] != NULL_CHAR && index < MAX_STR_LEN) + { + // set individual character to lowercase as needed, assigning back + outString[index] = toLowerCase(tempStr[index]); + // update index + index = index + 1; + // set temporary end of destination string + outString[index] = NULL_CHAR; + } + // end loop across source string + // free temporary string + free(tempStr); + + // no return, void. +} + +/* +Name: toLowerCase +Process: sets character to lowercase letter if uppercase letter, + returns character +Function input/parameters: character input (char) +Function output/parameters: NONE +Function output/returned: character output (char) +Device input/---: NONE +Device output/---: NONE +Dependencies: none +*/ +char toLowerCase(char testChar) +{ + // check for uppercase letter + if(testChar >= 'A' && testChar <= 'Z') + { + // return lowercase letter + return testChar - 'A' + 'a'; + } + // otherwise, assume not uppercase letter, return unchanged + return testChar; +} + +/* +Name: ??? +Process: ??? +Function input/parameters: ??? +Function output/parameters: NONE +Function output/returned: ??? +Device input/---: NONE +Device output/---: NONE +Dependencies: included by standard libraries +*/ \ No newline at end of file diff --git a/Sim01/StringUtils.h b/Sim01/StringUtils.h new file mode 100644 index 0000000..0ff4f49 --- /dev/null +++ b/Sim01/StringUtils.h @@ -0,0 +1,176 @@ +#ifndef STRINGUTILS +#define STRINGUTILS + +// header files +#include +#include +#include +#include +#include +#include "StandardConstants.h" + +// data structures + +// program constants + +// function prototypes + +/* +Name: catString +Process: concatenates two strings +Function input/parameters: c-style string (char *) +Function output/parameters: c-style string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: malloc, free, getStringLength +*/ +void catString(char *outString, const char *inString); + +/* +Name: compareString +Process: compares two strings as follows: + - if left string is alphabetically greater than the right string, + returns value greater than zero + - if left string is alphabetically less than the right string, + returns value less than zero + - if strings are alphabetically equal but one is longer, + longer one is greater + - otherwise, returns zero +Function input/parameters: c-style strings (char *) [first and second/left&right] +Function output/parameters: NONE +Function output/returned: results as specfifed above (int) +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength +*/ +int compareString(const char *firstString, const char *secondString); + +/* +Name: copyString +Process: copies string into new string variable, overwrites destination. +Function input/parameters: c-style string (char *) +Function output/parameters: c-style string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength +*/ +void copyString(char *outString, const char *inString); + +/* +Name: findSubString +Process: linear search for given substring within another string +Function input/parameters: c-style test string (char *), + c-style source string (char *) +Function output/parameters: NONE +Function output/returned: index of found substring, or + SUBSTRING_NOT_FOUND constant + if string not found +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength +*/ +int findSubString(const char *testStr, const char *searchSubStr); + +/* +Name: getStringConstrained +Process: captures a string from the file stream with various constraints +Function input/parameters: input stream (FILE *), + clears leading non printable (bool), + clears leading space (bool), + stops at non printable (bool), + stops at specified delimiter (char) + will consume the delimiter. +Function output/parameters: c-style string (char *) +Function output/returned: success of operation (bool) +Device input/---: NONE +Device output/---: NONE +Dependencies: fgetc +*/ +bool getStringConstrained(FILE *inStream, bool clearLeadingNonPrintable, + bool clearLeadingSpace, bool stopAtNonPrintable, + char delimiter, char *capString); + +/* +Name: getStringLength +Process: gets length of string from start to NULL_CHAR ('\0') +Function input/parameters: c-style string (char *) +Function output/parameters: NONE +Function output/returned: length of string (int) +Device input/---: NONE +Device output/---: NONE +Dependencies: included by standard libraries +*/ +int getStringLength(const char *stringIn); + +/* +Name: getStringToDelimiter +Process: captures a string from the input stream to a specified delimiter. + will consume the delimiter. +Function input/parameters: input stream (FILE *), + stops at specified character +Function output/parameters: c-style string (char *) +Function output/returned: success of operation (bool) +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringConstrained +*/ +bool getStringToDelimiter(FILE *inStream, char delimiter, char *capString); + +/* +Name: getStringToLineEnd +Process: captures a string from the input stream to the end of the line +Function input/parameters: input file stream (FILE *) +Function output/parameters: c-style string (char *) +Function output/returned: success of operation (bool) +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringConstrained +*/ +bool getStringToLineEnd(FILE *inStream, char *capString); + +/* +Name: getSubString +Process: captures sub string within larger string + between two inclusive indices. + returns empty string if either index is out of range, + assumes enough memory in dest string +Function input/parameters: c-style string (char *) + start and end indices (int) +Function output/parameters: c-style destination string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: getStringLength, malloc, copyString, free +*/ +void getSubString(char *destStr, const char *sourceStr, + int startIndex, int endIndex); + +/* +Name: strToLowerCase +Process: iterates through string, sets any uppercase letter to lowercase + equivalent, does not affect any letter with an upper/lower diff. +Function input/parameters: c-style source string (char *) +Function output/parameters: c-style dest string (char *) +Function output/returned: NONE +Device input/---: NONE +Device output/---: NONE +Dependencies: toLowerCase +*/ +void strToLowerCase(char *outString, const char *inString); + +/* +Name: toLowerCase +Process: sets character to lowercase letter if uppercase letter, + returns character +Function input/parameters: character input (char) +Function output/parameters: NONE +Function output/returned: character output (char) +Device input/---: NONE +Device output/---: NONE +Dependencies: none +*/ +char toLowerCase(char testChar); + +#endif // STRINGUTILS \ No newline at end of file diff --git a/Sim01/configops.c b/Sim01/configops.c new file mode 100644 index 0000000..dd583f2 --- /dev/null +++ b/Sim01/configops.c @@ -0,0 +1,53 @@ +#include "configops.h" +#include "StandardConstants.h" +#include "StringUtils.h" + +/* +Name: clearConfigData +Process: frees dynamically allocated config data structure + if it has not already been freed +Function Input/Parameters: pointer to config data structure (ConfigDataType *) +Function Output/Parameters: none +Function Output/Returned: NULL (ConfigDataType *) +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +ConfigDataType *clearConfigData(ConfigDataType *configData) +{ + // return NULL (temp) + return NULL; +} + +/* +Name: displayConfigData +Process: screen dump/display of all config data +Function Input/Parameters: pointer to config data structure (ConfigDataType *) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Monitor: displayed as spec'd +Dependencies: ??? +*/ +void displayConfigData(ConfigDataType *configData) +{ + // void function, no return. +} + +/* +Name: getConfigData +Process: driver function for capturing config data from config file +Function Input/Parameters: file name (const char *) +Function Output/Parameters: pointer to config data pointer (ConfigDataType **) + end/result state message pointer (char *) +Function Output/Returned: Boolean result of data access operation (bool) +Device Input/File: config data uploaded +Device Output/Device: none +Dependencies: ??? +*/ +bool getConfigData(const char *fileName, + ConfigDataType **configData, char *endStateMsg) +{ + // return false (temp) + return false; +} \ No newline at end of file diff --git a/Sim01/configops.h b/Sim01/configops.h new file mode 100644 index 0000000..aecb605 --- /dev/null +++ b/Sim01/configops.h @@ -0,0 +1,50 @@ +#ifndef CONFIGOPS +#define CONFIGOPS + +#include "StandardConstants.h" + +typedef struct ConfigDataTypeStruct +{ + char metaDataFileName[STD_STR_LEN]; +} ConfigDataType; + +/* +Name: clearConfigData +Process: frees dynamically allocated config data structure + if it has not already been freed +Function Input/Parameters: pointer to config data structure (ConfigDataType *) +Function Output/Parameters: none +Function Output/Returned: NULL (ConfigDataType *) +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +ConfigDataType *clearConfigData(ConfigDataType *configData); + +/* +Name: displayConfigData +Process: screen dump/display of all config data +Function Input/Parameters: pointer to config data structure (ConfigDataType *) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Monitor: displayed as spec'd +Dependencies: ??? +*/ +void displayConfigData(ConfigDataType *configData); + +/* +Name: getConfigData +Process: driver function for capturing config data from config file +Function Input/Parameters: file name (const char *) +Function Output/Parameters: pointer to config data pointer (ConfigDataType **) + end/result state message pointer (char *) +Function Output/Returned: Boolean result of data access operation (bool) +Device Input/File: config data uploaded +Device Output/Device: none +Dependencies: ??? +*/ +bool getConfigData(const char *fileName, + ConfigDataType **configData, char *endStateMsg); + +#endif // CONFIGOPS \ No newline at end of file diff --git a/Sim01/metadataops.c b/Sim01/metadataops.c new file mode 100644 index 0000000..7d711c6 --- /dev/null +++ b/Sim01/metadataops.c @@ -0,0 +1,56 @@ +#include "metadataops.h" +#include "StandardConstants.h" +#include "StringUtils.h" + +/* +Name: clearMetaDataList +Process: recursively traverses list, frees dynamically allocated nodes +Function Input/Parameters: node opcode (const OpCodeType *) +Function Output/Parameters: none +Function Output/Returned: NULL (OpCodeType *) +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +OpCodeType *clearMetaDataList(OpCodeType *localPtr) +{ + // return NULL (temp) + return NULL; +} + +/* +Name: displayMetaData +Process: data dump/display of all opcode items +Function Input/Parameters: pointer to + head of opcode/metadata list (const OpCodeType *) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void displayMetaData(const OpCodeType *localPtr) +{ + // void function, no return. +} + +/* +Name: getMetaData +Process: main driver function to upload, parse, and store list + of op code commands in a linked list +Function Input/Parameters: file name (const char *) +Function Output/Parameters: ptr to opcode linked list head ptr (OpCodeType **), + result msg of fct state after completion (char *) +Function Output/Returned: Boolean result of operation (bool) +Device Input/File: op code list uploaded +Device Output/Device: none +Dependencies: copyString fopen, getStringToDelimiter, compareString, fclose, + malloc, getOpCommand, updateStartCount, updateEndCount, + clearMetaDataList, free, addNode +*/ +bool getMetaData(const char *fileName, + OpCodeType **opCodeDataHead, char *endStateMsg) +{ + // return false (temp) + return false; +} \ No newline at end of file diff --git a/Sim01/metadataops.h b/Sim01/metadataops.h new file mode 100644 index 0000000..2c149e6 --- /dev/null +++ b/Sim01/metadataops.h @@ -0,0 +1,53 @@ +#ifndef METADATAOPS +#define METADATAOPS + +#include "StandardConstants.h" + +typedef struct OpCodeTypeStruct +{ + int temp; +} OpCodeType; + +/* +Name: clearMetaDataList +Process: recursively traverses list, frees dynamically allocated nodes +Function Input/Parameters: node opcode (const OpCodeType *) +Function Output/Parameters: none +Function Output/Returned: NULL (OpCodeType *) +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +OpCodeType *clearMetaDataList(OpCodeType *localPtr); + +/* +Name: displayMetaData +Process: data dump/display of all opcode items +Function Input/Parameters: pointer to + head of opcode/metadata list (const OpCodeType *) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void displayMetaData(const OpCodeType *localPtr); + +/* +Name: getMetaData +Process: main driver function to upload, parse, and store list + of op code commands in a linked list +Function Input/Parameters: file name (const char *) +Function Output/Parameters: ptr to opcode linked list head ptr (OpCodeType **), + result msg of fct state after completion (char *) +Function Output/Returned: Boolean result of operation (bool) +Device Input/File: op code list uploaded +Device Output/Device: none +Dependencies: copyString fopen, getStringToDelimiter, compareString, fclose, + malloc, getOpCommand, updateStartCount, updateEndCount, + clearMetaDataList, free, addNode +*/ +bool getMetaData(const char *fileName, + OpCodeType **opCodeDataHead, char *endStateMsg); + +#endif // METADATAOPS \ No newline at end of file diff --git a/Sim01/sim01_mf b/Sim01/sim01_mf new file mode 100644 index 0000000..b697bbf --- /dev/null +++ b/Sim01/sim01_mf @@ -0,0 +1,29 @@ +CC = gcc -Wall -std=c99 -pedantic -g +SOURCES = StringUtils.c simulator.c metadataops.c configops.c OS_SimDriver.c +OBJECTS = OS_SimDriver.o simulator.o metadataops.o configops.o StringUtils.o + +all: Simulator + +Simulator: $(OBJECTS) + $(CC) $(OBJECTS) -o sim01 + +StringUtils.o: StringUtils.c + $(CC) -c StringUtils.c -o StringUtils.o + +simulator.o: simulator.c + $(CC) -c simulator.c -o simulator.o + +metadataops.o: metadataops.c + $(CC) -c metadataops.c -o metadataops.o + +configops.o: configops.c + $(CC) -c configops.c -o configops.o + +OS_SimDriver.o: OS_SimDriver.c + $(CC) -c OS_SimDriver.c -o OS_SimDriver.o + +clean: + rm -f $(OBJECTS) sim01 sim01.out + +clean_objects: + rm -f $(OBJECTS) diff --git a/Sim01/simulator.c b/Sim01/simulator.c new file mode 100644 index 0000000..86a0e86 --- /dev/null +++ b/Sim01/simulator.c @@ -0,0 +1,19 @@ +#include "configops.h" +#include "metadataops.h" +#include "StandardConstants.h" + +/* +Name: runSim +Process: primary simulation driver +Function Input/Parameters: configuration data (ConfigDataType *), + metadata (OpCodeType *) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) +{ + // void function, no return. +} \ No newline at end of file diff --git a/Sim01/simulator.h b/Sim01/simulator.h new file mode 100644 index 0000000..94018a8 --- /dev/null +++ b/Sim01/simulator.h @@ -0,0 +1,19 @@ +#ifndef SIMULATORX +#define SIMULATORX + +#include "StandardConstants.h" + +/* +Name: runSim +Process: primary simulation driver +Function Input/Parameters: configuration data (ConfigDataType *), + metadata (OpCodeType *) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr); + +#endif // SIMULATORX \ No newline at end of file diff --git a/Sim01_GradingForm_v01.xlsx b/Sim01_GradingForm_v01.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..af3f902b60e0631aca9d10e6bc8eeaf76644698d GIT binary patch literal 18524 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 literal 0 HcmV?d00001 diff --git a/Sim01_Specifications_Spring24_v01-Trimmed.docx b/Sim01_Specifications_Spring24_v01-Trimmed.docx new file mode 100644 index 0000000000000000000000000000000000000000..40168330e4bdd95ad669aa1100d19a85736d0898 GIT binary patch literal 40571 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 L0Hu2z_v7q;tL80Q literal 0 HcmV?d00001 diff --git a/Sim01_Specifications_Spring24_v01.docx b/Sim01_Specifications_Spring24_v01.docx new file mode 100644 index 0000000000000000000000000000000000000000..79303807498fa36e2c8c0dbacf5d124893368fdc GIT binary patch literal 54028 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®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

u$y9drMLjBuGPoz_I{a|IN1!N**W{!{gz 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 0 ) + { + timeStr[ index ] = (char) ( uSecTime % 10 + '0' ); + uSecTime /= 10; + + index++; + + } + + while( index < 6 ) + { + timeStr[ index ] = '0'; + + index++; + } + + timeStr[ index ] = RADIX_POINT; + + index++; + + if( secTime < 10 ) // single digit in display + { + timeStr[ index ] = (char) ( secTime % 10 + '0' ); + + index++; + + timeStr[ index ] = SPACE; + + index++; + + secTime = 0; + } +/* + if( secTime == 0 ) + { + timeStr[ index ] = '0'; + + index++; + } +*/ + while( secTime > 0 ) + { + timeStr[ index ] = (char) ( secTime % 10 + '0' ); + + secTime /= 10; + + index++; + } + + timeStr[ index ] = NULL_CHAR; + + low = 0; high = index - 1; + + while( low < high ) + { + temp = timeStr[ low ]; + timeStr[ low ] = timeStr[ high ]; + timeStr[ high ] = temp; + + low++; high--; + } + } + +#endif // ifndef SIMTIMER_C + + + + + diff --git a/SimTimerCode/simtimer.h b/SimTimerCode/simtimer.h new file mode 100644 index 0000000..21f2e89 --- /dev/null +++ b/SimTimerCode/simtimer.h @@ -0,0 +1,45 @@ +// Program Information //////////////////////////////////////////////////////// +/** + * @file SimpleTimer.h + * + * @brief Header file for micro-second precision timer + * + * @author Michael Leverington + * + * @details Specifies all member methods of the SimpleTimer + * + * @version 2.00 (13 January 2017) + * 1.00 (11 September 2015) + * + * @Note None + */ + +// Precompiler directives ///////////////////////////////////////////////////// + +#ifndef SIMTIMER_H +#define SIMTIMER_H + +// Header files /////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "mainprog.h" + +// Global Constants ////////////////////////////////////////////////////////// + +enum TIMER_CTRL_CODES { ZERO_TIMER, LAP_TIMER, STOP_TIMER }; + +extern const char RADIX_POINT; +extern const char SPACE; + +// Function Prototyp ///////////////////////////////////////////////////////// + +void runTimer( int milliSeconds ); +double accessTimer( int controlCode, char *timeStr ); +double processTime( double startSec, double endSec, + double startUSec, double endUSec, char *timeStr ); +void timeToString( int secTime, int uSecTime, char *timeStr ); + +#endif // ifndef SIMTIMER_H +