Refuse to work on this anymore right now.

This commit is contained in:
Charles Descamps 2024-04-14 18:41:58 -07:00
parent e3441e9fbd
commit fda57566d8
26 changed files with 4988 additions and 94 deletions

246
Sim04/OS_SimDriver.c Normal file
View file

@ -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] <configfile.cnf>\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.
}

74
Sim04/OS_SimDriver.h Normal file
View file

@ -0,0 +1,74 @@
#ifndef OS_DRIVER
#define OS_DRIVER
// header files
#include <stdio.h>
#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

79
Sim04/StandardConstants.h Normal file
View file

@ -0,0 +1,79 @@
// Preprocessor directives
#ifndef STANDARD_CONSTANTS_H
#define STANDARD_CONSTANTS_H
// Include Boolean
#include <stdbool.h>
// global constants
// constant for end of c-string null character
#define CARRIAGE_RETURN_CHAR '\r'
//constant for a COLON
#define COLON ':'
//constant for a SEMICOLON
#define SEMICOLON ';'
//constant for a COMMA
#define COMMA ','
//Constant to print a dash
#define DASH '-'
// constant for equivalent strings
#define EQUIV 0
// 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

454
Sim04/StringUtils.c Normal file
View file

@ -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
*/

176
Sim04/StringUtils.h Normal file
View file

@ -0,0 +1,176 @@
#ifndef STRINGUTILS
#define STRINGUTILS
// header files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#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

13
Sim04/config0.cnf Normal file
View file

@ -0,0 +1,13 @@
Start Simulator Configuration File:
Version/Phase : 1.05
File Path : metadata5.mdf
CPU Scheduling Code : SJF-N
Quantum Time (cycles) : 3
Memory Available (KB) : 11100
Memory Display (On/Off) : On
Processor Cycle Time (msec) : 10
I/O Cycle Time (msec) : 20
Log To : Both
Log File Path : logfile_1.lgf
End Simulator Configuration File.

608
Sim04/configops.c Normal file
View file

@ -0,0 +1,608 @@
#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: free
*/
ConfigDataType *clearConfigData(ConfigDataType *configData)
{
// initialize function and variables
// check that config data pointer is not null
if(configData != NULL)
{
// free data structure memory
// fct: free
free(configData);
// set config pointer to NULL
configData = NULL;
}
// set config data pointer to null
return NULL;
}
/*
Name: configCodeToString
Process: utility fct converts configuration code numbers to string they represent
Function Input/Parameters: configuration code (int)
Function Output/Parameters: resulting output string (char *)
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: copyString
*/
void configCodeToString(int code, char *outString)
{
// define array with eight items, and short (10) lengths
char displayStrings[8][10] = {"SJF-N","SRTF-P","FCFS-P","RR-P",
"FCFS-N","Monitor", "File", "Both"};
// copy string to return parameter
// fct: copyString
copyString(outString, displayStrings[code]);
// void function, no return.
}
/*
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: configCodeToString, printf
*/
void displayConfigData(ConfigDataType *configData)
{
// initialize function and variables
char displayString[STD_STR_LEN];
// print lines of display for all member values
// fct: printf, codeToString
printf("Config File Display\n");
printf("-------------------\n");
printf("Version : %3.2f\n", configData->version);
printf("Program File Name : %s\n", configData->metaDataFileName);
configCodeToString(configData->cpuSchedCode, displayString);
printf("CPU Schedule Selection: %s\n", displayString);
printf("Quantum Time : %d\n", configData->quantumCycles);
printf("Memory Display : ");
if(configData->memDisplay)
{
printf("On\n");
}
else
{
printf("Off\n");
}
printf("Memory Available : %d\n", configData->memAvailable);
printf("Process Cycle Rate : %d\n", configData->procCycleRate);
printf("I/O Cycle Rate : %d\n", configData->ioCycleRate);
configCodeToString(configData->logToCode, displayString);
printf("Log to Selection : %s\n", displayString);
printf("Log File Name : %s\n\n", configData->logToFileName);
// 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: copyString, fopen, getStringToDelimiter, compareString, fclose,
malloc, free, stripTrailingSpaces, getDataLineCode, fscanf,
strToLowerCase, valueInRange, getCpuSchedCode, getLogToCode
*/
bool getConfigData(const char *fileName,
ConfigDataType **configData, char *endStateMsg)
{
// initialize function and variables
// set constant number of data lines
const int NUM_DATA_LINES = 10;
// set read only constant
const char READ_ONLY_FLAG[] = "r";
// create pointer for data input
ConfigDataType *tempData;
// declare other variables
FILE *fileAccessPtr;
char dataBuffer[MAX_STR_LEN], lowerCaseDataBuffer[MAX_STR_LEN];
int intData, dataLineCode, lineCtr = 0;
double doubleData;
// set endStateMsg to success
// fct: copyString
char testMsg[] = "Configuration file upload successful";
copyString(endStateMsg, testMsg);
// initialize config data pointer in case of return error
*configData = NULL;
// open file
// fct: fopen
fileAccessPtr = fopen(fileName, READ_ONLY_FLAG);
// check for file open failure
if(fileAccessPtr == NULL)
{
// set end state message to config file access error
// fct: copyString
char testMsg[] = "Configuration file access error";
copyString(endStateMsg, testMsg);
// return file access error
return false;
}
// get first line, check for failure
// fct: getStringToDelimiter, compareString
if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer)
|| compareString(dataBuffer, "Start Simulator Configuration File") != 0)
{
// close file access
// fct: fclose
fclose(fileAccessPtr);
// set end state message to corrupt leader line error
// fct: copyString
copyString(endStateMsg, "Corrupt configuration leader line error");
// return corrupt file data
return false;
}
// create temporary pointer to configuration data structure
// fct: malloc
tempData = (ConfigDataType *) malloc(sizeof(ConfigDataType));
// loop to end of config data items
while(lineCtr < NUM_DATA_LINES)
{
// get line leader, check for failure
// fct: getStringToDelimiter
if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer))
{
// free temp struct memory
// fct: free
free(tempData);
// close file access
// fct: fclose
fclose(fileAccessPtr);
// set end state message to line capture failure
// fct: copyString
copyString(endStateMsg,
"Configuration data leader line capture error");
// return incomplete file error
return false;
}
// strip trailing spaces of config leader lines
// for use in other fcts
// fct: stripTrailingSpaces
stripTrailingSpaces(dataBuffer);
// find correct data line code number from string
// fct: getDataLineCode
dataLineCode = getDataLineCode(dataBuffer);
// check for data line found
if(dataLineCode != CFG_CORRUPT_PROMPT_ERR)
{
// get data value
// check for version number (double value)
if(dataLineCode == CFG_VERSION_CODE)
{
// get version number
// fct: fscanf
fscanf(fileAccessPtr, "%lf", &doubleData);
}
// otherwise, check for metaData, fileNames,
// CPU Scheduling names, or memory display setting (strings)
else if(dataLineCode == CFG_MD_FILE_NAME_CODE ||
dataLineCode == CFG_LOG_FILE_NAME_CODE ||
dataLineCode == CFG_CPU_SCHED_CODE ||
dataLineCode == CFG_LOG_TO_CODE ||
dataLineCode == CFG_MEM_DISPLAY_CODE)
{
// get string input
// fct: fscanf
fscanf(fileAccessPtr, "%s", dataBuffer);
// set string to lower case for testing in valueInRange
// fct: strToLowerCase
strToLowerCase(lowerCaseDataBuffer, dataBuffer);
}
// otherwise, assume integer data
else
{
// get integer input
// fct: fscanf
fscanf(fileAccessPtr, "%d", &intData);
}
// check for data value in range
// fct: valueInRange
if(valueInRange(dataLineCode, intData,
doubleData, lowerCaseDataBuffer))
{
// assign to data pointer depending on config item
// (all config line possibilities)
// fct: copyString, getCpuSchedCode,
// compareString, getLogToCode, as needed
switch(dataLineCode)
{
case CFG_VERSION_CODE:
tempData->version = doubleData;
break;
case CFG_MD_FILE_NAME_CODE:
copyString(tempData->metaDataFileName, dataBuffer);
break;
case CFG_CPU_SCHED_CODE:
tempData->cpuSchedCode =
getCpuSchedCode(lowerCaseDataBuffer);
break;
case CFG_QUANT_CYCLES_CODE:
tempData->quantumCycles = intData;
break;
case CFG_MEM_DISPLAY_CODE:
tempData->memDisplay =
compareString(lowerCaseDataBuffer, "on") == 0;
break;
case CFG_MEM_AVAILABLE_CODE:
tempData->memAvailable = intData;
break;
case CFG_PROC_CYCLES_CODE:
tempData->procCycleRate = intData;
break;
case CFG_IO_CYCLES_CODE:
tempData->ioCycleRate = intData;
break;
case CFG_LOG_TO_CODE:
tempData->logToCode = getLogToCode(lowerCaseDataBuffer);
break;
case CFG_LOG_FILE_NAME_CODE:
copyString(tempData->logToFileName, dataBuffer);
break;
}
}
// otherwise, assume data value not in range
else
{
// free temp struct memory
// fct: free
free(tempData);
// close file access
// fct: fclose
fclose(fileAccessPtr);
// set end state message to configuration data out of range
// fct: copyString
copyString(endStateMsg, "Configuration item out of range");
// return data out of range
return false;
}
}
// otherwise, check for data line not found
else
{
// free temp struct memory
// fct: free
free(tempData);
// close file access
// fct: fclose
fclose(fileAccessPtr);
// set end state message to configuration corrupt prompt error
// fct: copyString
copyString(endStateMsg, "Corrupted configuration prompt");
// return corrupt config file code
return false;
}
// increment line counter
lineCtr = lineCtr + 1;
}
// end loop to end of config data items
// acquire end of sim config string
// fct: getStringToDelimiter, compareString
if(!getStringToDelimiter(fileAccessPtr, PERIOD, dataBuffer) ||
compareString(dataBuffer, "End Simulator Configuration File") != 0)
{
// free temp struct memory
// fct: free
free(tempData);
// close file access
// fct: fclose
fclose(fileAccessPtr);
// set end state message to corrupt configuration end line
// fct: copyString
copyString(endStateMsg, "Configuration end line capture error");
// return corrupt file data
return false;
}
// test for "file only" output so memory diagnostics do not display
tempData->memDisplay = tempData->memDisplay &&
tempData->logToCode != LOGTO_FILE_CODE;
// assign temp ptr to parameter return ptr
*configData = tempData;
// close file access
// fct: fclose
fclose(fileAccessPtr);
// return no error code
return true;
}
/*
Name: getCpuSchedCode
Process: converts cpu schedule string to code (all scheduling possibilities)
Function Input/Parameters: lower case code string (const char *)
Function Output/Parameters: none
Function Output/Returned: cpu schedule code (ConfigDataCodes)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
ConfigDataCodes getCpuSchedCode(const char *lowerCaseCodeStr)
{
// iniitalize function and variables
// set default return to FCFS-N
ConfigDataCodes returnVal = CPU_SCHED_FCFS_N_CODE;
// check for SJF-N
// fct: compareString
if(compareString(lowerCaseCodeStr, "sjf-n") == 0)
{
// set SJF-N code
returnVal = CPU_SCHED_SJF_N_CODE;
}
// check for SRTF-P
// fct: compareString
if(compareString(lowerCaseCodeStr, "srtf-p") == 0)
{
// set SRTF-P code
returnVal = CPU_SCHED_SRTF_P_CODE;
}
// check for FCFS-P
// fct: compareString
if(compareString(lowerCaseCodeStr, "fcfs-p") == 0)
{
// set FCFS-P code
returnVal = CPU_SCHED_FCFS_P_CODE;
}
// check for RR-P
// fct: compareString
if(compareString(lowerCaseCodeStr, "rr-p") == 0)
{
// set RR-P code
returnVal = CPU_SCHED_RR_P_CODE;
}
return returnVal;
}
/*
Name: getDataLineCode
Process: converts leader line string to configuration code value
(processes all config file leader lines)
Function Input/Parameters: config leader line string (const char *)
Function Output/Parameters: none
Function Output/Returned: configuration code value (ConfigCodeMessages)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
ConfigCodeMessages getDataLineCode(const char *dataBuffer)
{
// iniitalize function and variables
// return appropriate code depending on prompt string provided
// fct: compareString
if(compareString(dataBuffer, "Version/Phase") == 0)
{
return CFG_VERSION_CODE;
}
if(compareString(dataBuffer, "File Path") == 0)
{
return CFG_MD_FILE_NAME_CODE;
}
if(compareString(dataBuffer, "CPU Scheduling Code") == 0)
{
return CFG_CPU_SCHED_CODE;
}
if(compareString(dataBuffer, "Quantum Time (cycles)") == 0)
{
return CFG_QUANT_CYCLES_CODE;
}
if(compareString(dataBuffer, "Memory Display (On/Off)") == 0)
{
return CFG_MEM_DISPLAY_CODE;
}
if(compareString(dataBuffer, "Memory Available (KB)") == 0)
{
return CFG_MEM_AVAILABLE_CODE;
}
if(compareString(dataBuffer, "Processor Cycle Time (msec)") == 0)
{
return CFG_PROC_CYCLES_CODE;
}
if(compareString(dataBuffer, "I/O Cycle Time (msec)") == 0)
{
return CFG_IO_CYCLES_CODE;
}
if(compareString(dataBuffer, "Log To") == 0)
{
return CFG_LOG_TO_CODE;
}
if(compareString(dataBuffer, "Log File Path") == 0)
{
return CFG_LOG_FILE_NAME_CODE;
}
// return corrupt leader line error code
return CFG_CORRUPT_PROMPT_ERR;
}
/*
Name: getLogToCode
Process: converts "log to" text to
configuration data code (three log to strings)
Function Input/Parameters: lower case log to string (const char *)
Function Output/Parameters: none
Function Output/Returned: configuration data code value
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
ConfigDataCodes getLogToCode(const char *lowerCaseLogToStr)
{
// initialize function and variables
// set default to log to monitor
ConfigDataCodes returnVal = LOGTO_MONITOR_CODE;
// check for BOTH
// fct: compareString
if(compareString(lowerCaseLogToStr, "both") == 0)
{
// set return value to both code
returnVal = LOGTO_BOTH_CODE;
}
// check for FILE
// fct: compareString
if(compareString(lowerCaseLogToStr, "file") == 0)
{
// set return value to file code
returnVal = LOGTO_FILE_CODE;
}
// return selected code
return returnVal;
}
/*
Name: stripTrailingSpaces
Process: removes trailing spaces from input config leader lines
Function Input/Parameters: config leader line string (char *)
Function Output/Parameters: updates config leader line string (char *)
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: getStringLength
*/
void stripTrailingSpaces(char *str)
{
// initialize index to length of string - 1 to get highest array index
int index = getStringLength(str) - 1;
// loop while space is found at the end of string
while(str[index] == SPACE)
{
// set element to NULL_CHAR
str[index] = NULL_CHAR;
// decrement index
index = index - 1;
}
// end loop from end of string
// void function, no return.
}
/*
Name: valueInRange
Process: checks for config data values in range, including str values
Function Input/Parameters: line code number for specific config value (int),
integer value, as needed (int),
double value, as needed (double),
string value, as needed (const char *)
Function Output/Parameters: none
Function Output/Returned: Boolean result of the range test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
bool valueInRange(int lineCode, int intVal, double doubleVal,
const char *lowerCaseStringVal)
{
// initialize function and variables
// set result to true, all tests are to find false
bool result = true;
// use line code to identify prompt line
switch(lineCode)
{
// for version code
case CFG_VERSION_CODE:
// check if limits of version code are exceeded
if(doubleVal < 0.00 || doubleVal > 10.00)
{
// set bool to false
result = false;
}
// break
break;
// for cpu scheduling code
case CFG_CPU_SCHED_CODE:
// check for not finding one of the scheduling strings
// fct: compareString
if(compareString(lowerCaseStringVal, "fcfs-n") != 0 &&
compareString(lowerCaseStringVal, "sjf-n") != 0 &&
compareString(lowerCaseStringVal, "srtf-p") != 0 &&
compareString(lowerCaseStringVal, "fcfs-p") != 0 &&
compareString(lowerCaseStringVal, "rr-p") != 0)
{
// set bool to false
result = false;
}
// break
break;
// for quantum cycles
case CFG_QUANT_CYCLES_CODE:
// check for quantum cycles limits exceeded
if(intVal < 0 || intVal > 100)
{
// set bool to false
result = false;
}
// break
break;
// for memory display
case CFG_MEM_DISPLAY_CODE:
// check for not finding either on or off
// fct: compareString
if(compareString(lowerCaseStringVal, "on") != 0 &&
compareString(lowerCaseStringVal, "off") != 0)
{
// set bool to false
result = false;
}
// break
break;
// for memory available
case CFG_MEM_AVAILABLE_CODE:
// check for memory limits exceeded
if(intVal < 1024 || intVal > 102400)
{
// set bool to false
result = false;
}
// break
break;
// check for process cycles
case CFG_PROC_CYCLES_CODE:
// check for process cycles limits exceeded
if(intVal < 1 || intVal > 100)
{
// set bool to false
result = false;
}
// break
break;
// check for process cycles
case CFG_IO_CYCLES_CODE:
// check for process cycles limits exceeded
if(intVal < 1 || intVal > 1000)
{
// set bool to false
result = false;
}
// break
break;
// check for log to operation
case CFG_LOG_TO_CODE:
// check for not finding one of the log to strings
// fct: compareString
if(compareString(lowerCaseStringVal, "both") != 0 &&
compareString(lowerCaseStringVal, "monitor") != 0 &&
compareString(lowerCaseStringVal, "file") != 0)
{
// set bool to false
result = false;
}
// break
break;
}
// return result of limits analysis
return result;
}

168
Sim04/configops.h Normal file
View file

@ -0,0 +1,168 @@
#ifndef CONFIGOPS
#define CONFIGOPS
#include "StandardConstants.h"
#include "StringUtils.h"
typedef enum {CFG_FILE_ACCESS_ERR,
CFG_CORRUPT_DESCRIPTOR_ERR,
CFG_DATA_OUT_OF_RANGE_ERR,
CFG_CORRUPT_PROMPT_ERR,
CFG_VERSION_CODE,
CFG_MD_FILE_NAME_CODE,
CFG_CPU_SCHED_CODE,
CFG_QUANT_CYCLES_CODE,
CFG_MEM_DISPLAY_CODE,
CFG_MEM_AVAILABLE_CODE,
CFG_PROC_CYCLES_CODE,
CFG_IO_CYCLES_CODE,
CFG_LOG_TO_CODE,
CFG_LOG_FILE_NAME_CODE
} ConfigCodeMessages;
typedef enum {CPU_SCHED_SJF_N_CODE,
CPU_SCHED_SRTF_P_CODE,
CPU_SCHED_FCFS_P_CODE,
CPU_SCHED_RR_P_CODE,
CPU_SCHED_FCFS_N_CODE,
LOGTO_MONITOR_CODE,
LOGTO_FILE_CODE,
LOGTO_BOTH_CODE,
NON_PREEMPTIVE_CODE,
PREEMPTIVE_CODE
} ConfigDataCodes;
typedef struct ConfigDataTypeStruct
{
double version;
char metaDataFileName[MAX_STR_LEN];
int cpuSchedCode;
int quantumCycles;
bool memDisplay;
int memAvailable;
int procCycleRate;
int ioCycleRate;
int logToCode;
char logToFileName[MAX_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: configCodeToString
Process: utility fct converts configuration code numbers to string they represent
Function Input/Parameters: configuration code (int)
Function Output/Parameters: resulting output string (char *)
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: copyString
*/
void configCodeToString(int code, char *outString);
/*
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: copyString, fopen, getStringToDelimiter, compareString, fclose,
malloc, free, stripTrailingSpaces, getDataLineCode, fscanf,
setStrToLowerCase, valueInRange, getCpuSchedCode, getLogToCode
*/
bool getConfigData(const char *fileName,
ConfigDataType **configData, char *endStateMsg);
/*
Name: getCpuSchedCode
Process: converts cpu schedule string to code (all scheduling possibilities)
Function Input/Parameters: lower case code string (const char *)
Function Output/Parameters: none
Function Output/Returned: cpu schedule code (ConfigDataCodes)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
ConfigDataCodes getCpuSchedCode(const char *lowerCaseCodeStr);
/*
Name: getDataLineCode
Process: converts leader line string to configuration code value
(processes all config file leader lines)
Function Input/Parameters: config leader line string (const char *)
Function Output/Parameters: none
Function Output/Returned: configuration code value (ConfigCodeMessages)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
ConfigCodeMessages getDataLineCode(const char *dataBuffer);
/*
Name: getLogToCode
Process: converts "log to" text to
configuration data code (three log to strings)
Function Input/Parameters: lower case log to string (const char *)
Function Output/Parameters: none
Function Output/Returned: configuration data code value
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
ConfigDataCodes getLogToCode(const char *lowerCaseLogToStr);
/*
Name: stripTrailingSpaces
Process: removes trailing spaces from input config leader lines
Function Input/Parameters: config leader line string (char *)
Function Output/Parameters: updates config leader line string (char *)
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: getStringLength
*/
void stripTrailingSpaces(char *str);
/*
Name: valueInRange
Process: checks for config data values in range, including str values
Function Input/Parameters: line code number for specific config value (int),
integer value, as needed (int),
double value, as needed (double),
string value, as needed (const char *)
Function Output/Parameters: none
Function Output/Returned: Boolean result of the range test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
bool valueInRange(int lineCode, int intVal, double doubleVal,
const char *lowerCaseStringVal);
#endif // CONFIGOPS

0
Sim04/logfile_1.lgf Normal file
View file

75
Sim04/metadata5.mdf Normal file
View file

@ -0,0 +1,75 @@
Start Program Meta-Data Code:
sys start
app start, 0
dev in, serial, 28
dev out, video signal, 42
dev in, sound signal, 40
dev out, hard drive, 15
mem allocate, 4000, 2000
dev in, keyboard, 80
dev in, serial, 28
cpu process, 10
cpu process, 8
cpu process, 6
dev out, video signal, 49
app end
app start, 0
dev in, serial, 20
cpu process, 6
cpu process, 8
dev out, monitor, 70
cpu process, 6
cpu process, 9
mem allocate, 1000, 3000
dev out, sound signal, 45
dev out, hard drive, 15
dev in, video signal, 49
dev out, serial, 20
mem access, 2000, 1000
app end
app start, 0
dev in, hard drive, 18
dev out, video signal, 49
dev out, usb, 14
dev out, monitor, 70
cpu process, 7
mem allocate, 1500, 2000
cpu process, 9
dev in, keyboard, 70
dev in, video signal, 42
mem access, 2800, 1000
cpu process, 5
cpu process, 6
app end
app start, 0
dev in, hard drive, 21
dev out, sound signal, 30
cpu process, 7
mem allocate, 2500, 3000
dev in, keyboard, 80
dev in, hard drive, 30
dev out, video signal, 63
mem access, 2600, 1500
dev in, serial, 28
dev out, sound signal, 25
cpu process, 9
mem allocate, 2500, 1000
dev out, sound signal, 45
app end
app start, 0
dev in, serial, 24
dev out, video signal, 42
mem allocate, 3000, 3000
cpu process, 5
dev in, usb, 10
cpu process, 8
cpu process, 9
mem access, 3500, 2000
cpu process, 6
dev out, hard drive, 18
dev out, hard drive, 24
dev out, hard drive, 21
app end
sys end
End Program Meta-Data Code.

729
Sim04/metadataops.c Normal file
View file

@ -0,0 +1,729 @@
#include "metadataops.h"
#include "StandardConstants.h"
#include "StringUtils.h"
/*
Name: addNode
Process: adds metadata node to linked list recursively, handles empty list
Function Input/Parameters: ptr to head or next linked node (OpCodeType *),
ptr to new node (OpCodeType *)
Function Output/Parameters: none
Function Output/Returned: pointer to previous node, or head node (OpCodeType *)
Device Input/Device: none
Device Output/Device: none
Dependencies: malloc, copyString
*/
OpCodeType *addNode(OpCodeType *localPtr, OpCodeType *newNode)
{
// initialize function and variables
// check for local pointer assigned to null
if(localPtr == NULL)
{
// access memory for new link/node
// fct: malloc
localPtr = (OpCodeType *) malloc(sizeof(OpCodeType));
// assign all three values to newly created node
// assign next pointer to null
// fct: copyString
localPtr->pid = newNode->pid;
copyString(localPtr->command, newNode->command);
copyString(localPtr->inOutArg, newNode->inOutArg);
copyString(localPtr->strArg1, newNode->strArg1);
localPtr->intArg2 = newNode->intArg2;
localPtr->intArg3 = newNode->intArg3;
localPtr->opEndTime = newNode->opEndTime;
localPtr->nextNode = NULL;
// return current local pointer
return localPtr;
}
// assume end of list not found
// assign recursive fct to current node's next link
// fct: addNode
localPtr->nextNode = addNode(localPtr->nextNode, newNode);
// return current local ptr
return localPtr;
}
/*
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)
{
// initialize function and variables
// check for local pointer not set to null (list not empty)
if(localPtr != NULL)
{
// call recursive function with next pointer
// fct: clearMetaDataList
clearMetaDataList(localPtr->nextNode);
// after recursive call, release mem to OS
// fct: free
free(localPtr);
// set given pointer to NULL
localPtr = NULL;
}
// return NULL to calling fct
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: calculated time (int)
Device Input/Device: none
Device Output/Device: none
Dependencies: printf, compareString
*/
void displayMetaData(const OpCodeType *localPtr)
{
// initialize function and variables
// display title, with underline
// fct: printf
printf("Metadata File Display\n");
printf("---------------------\n\n");
// loop to end of linked list
while(localPtr != NULL)
{
// print leader
// fct: printf
printf("Opcode: ");
// print opcode pid
// fct: printf
printf("/pid: %d", localPtr->pid);
// print opcode command
// fct: printf
printf("/cmd: %s", localPtr->command);
// check for dev op
if(compareString(localPtr->command, "dev") == 0)
{
// print in/out parameter
// fct: printf
printf("/io: %s", localPtr->inOutArg);
}
// otherwise, assume other than dev
else
{
// print NA
// fct: printf
printf("/io: NA");
}
// print first string argument
// fct: printf
printf("\n\t/arg 1: %s", localPtr->strArg1);
// print first int argument
// fct: printf
printf("/arg 2: %d", localPtr->intArg2);
// print second int argument
// fct: printf
printf("/arg 3: %d", localPtr->intArg3);
// print op end time
printf("/op end time: %8.6f", localPtr->opEndTime);
// endline print
// fct: printf
printf("\n\n");
// assign local pointer to next node
localPtr = localPtr->nextNode;
}
// void function, no return.
}
/*
Name: getCommand
Process: parses thre letter command part of opcode str
Function Input/Parameters: input opcode str (const char *),
starting index (int)
Function Output/Parameters: parsed command (char *)
Function Output/Returned: updated starting index for use by calling fct (int)
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
int getCommand(char *cmd, const char *inputStr, int index)
{
// initialize function and variables
int lengthOfCommand = 3;
// loop across command length
while(index < lengthOfCommand)
{
// assign character from input string to buffer string
cmd[index] = inputStr[index];
// increment index
index = index + 1;
// set next character to null character
cmd[index] = NULL_CHAR;
}
// return current index
return index;
}
/*
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)
{
// initialize function and variables
// iniitialize read only constant
const char READ_ONLY_FLAG[] = "r";
// initialize variables
int accessResult, startCount = 0, endCount = 0;
char dataBuffer[MAX_STR_LEN];
bool returnState = true;
OpCodeType *newNodePtr;
OpCodeType *localHeadPtr = NULL;
FILE *fileAccessPtr;
// initialize opcode data pointer in case of return error
*opCodeDataHead = NULL;
// initialize end state message
// fct: copyString
copyString(endStateMsg, "Metadata file upload successful");
// open file for reading
// fct: fopen
fileAccessPtr = fopen(fileName, READ_ONLY_FLAG);
// check for file open failure
if(fileAccessPtr == NULL)
{
// set end state message
// fct: copyString
copyString(endStateMsg, "Metadata file access error");
// return file access error
return false;
}
// check first line for correct leader
// fct: getStringToDelimiter, compareString
if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer) ||
compareString(dataBuffer, "Start Program Meta-Data Code") != 0)
{
// close file
// fct: fclose
fclose(fileAccessPtr);
// set end state message
// fct: copyString
copyString(endStateMsg, "Corrupt metadata leader line error");
// return corrupt descriptor error
return false;
}
// allocate memory for the temporary data structure
// fct: malloc
newNodePtr = (OpCodeType *) malloc(sizeof(OpCodeType));
// get the first op command
// fct: getOpCommand
accessResult = getOpCommand(fileAccessPtr, newNodePtr);
// get start and end counts for later comparison
// fct: updateStartCount, updateEndCount
startCount = updateStartCount(startCount, newNodePtr->strArg1);
endCount = updateEndCount(endCount, newNodePtr->strArg1);
// check for failure of first complete op command
if(accessResult != COMPLETE_OPCMD_FOUND_MSG)
{
// close file
// fct: fclose
fclose(fileAccessPtr);
// clear data from the structure list
// fct: clearMetaDataList
*opCodeDataHead = clearMetaDataList(localHeadPtr);
// free temporary structure memory
// fct: free
free(newNodePtr);
// set end state message
// fct: copyString
copyString(endStateMsg, "Metadata incomplete first op command found");
// return result of operation
return false;
}
// loop across all remaining op commands
// (while complete op commands are found)
while(accessResult == COMPLETE_OPCMD_FOUND_MSG)
{
// add the new op command to the linked list
// fct: addNode
localHeadPtr = addNode(localHeadPtr, newNodePtr);
// get a new op command
// fct: getOpCommand
accessResult = getOpCommand(fileAccessPtr, newNodePtr);
// update start and end counts for later comparison
// fct: updateStartCount, updateEndCount
startCount = updateStartCount(startCount, newNodePtr->strArg1);
endCount = updateEndCount(endCount, newNodePtr->strArg1);
}
// end loop across all remaining op commands
// check for last op command found
if(accessResult == LAST_OPCMD_FOUND_MSG)
{
// check for start and end opcode counts equal
if(startCount == endCount)
{
// add the last node to the linked list
// fct: addNode
localHeadPtr = addNode(localHeadPtr, newNodePtr);
// set access result to no error for later operation
accessResult = NO_ACCESS_ERR;
// check last line for incorrect end descriptor
// fct: getStringToDelimiter, compareString
if(!getStringToDelimiter(fileAccessPtr, PERIOD, dataBuffer) ||
compareString(dataBuffer, "End Program Meta-Data Code") != 0)
{
// set access result to corrupted descriptor error
accessResult = MD_CORRUPT_DESCRIPTOR_ERR;
// set end state message
// fct: copyString
copyString(endStateMsg, "Metadata corrupted descriptor error");
}
}
// otherwise, assume start/end counts not equal
else
{
// close file
// fct: fclose
fclose(fileAccessPtr);
// clear data from the structure list
// fct: clearMetaDataList
*opCodeDataHead = clearMetaDataList(localHeadPtr);
// free temporary structure memory
// fct: free
free(newNodePtr);
// set access result to error
accessResult = UNBALANCED_START_END_ERR;
// set end state message
// fct: copyString
copyString(endStateMsg,
"Unbalanced start and end arguments in metadata");
// return result of operation
return false;
}
}
// otherwise, assume didn't find end
else
{
// set end state message
// fct: copyString
copyString(endStateMsg, "Corrupted metadata opcode");
// unset return state
returnState = false;
}
// check for any errors found (not no error)
if(accessResult != NO_ACCESS_ERR)
{
// clear the op command list
// fct: clearMetaDataList
localHeadPtr = clearMetaDataList(localHeadPtr);
}
// close access file
// fct: fclose
fclose(fileAccessPtr);
// release temporary structure memory
// fct: free
free(newNodePtr);
// assign temporary local head ptr to parameter return ptr
*opCodeDataHead = localHeadPtr;
// return access result
return returnState;
}
/*
Name: getOpCommand
Process: acquires one op command line from a previously opened file,
parses it, and sets various struct members according to the
three letter command
Function Input/Parameters: ptr to open file handle (FILE *)
Function Output/Parameters: ptr to one opcode struct (OpCodeType *)
Function Output/Returned: coded result of operation (OpCodeMessages)
Device Input/File: opcode line uploaded
Device Output/Device: none
Dependencies: getStringToDelimiter, getCommand, copyString, verifyValidCommand,
compareString, getStringArg, verifyFirstStringArg, getNumberArg
*/
OpCodeMessages getOpCommand(FILE *filePtr, OpCodeType *inData)
{
// initialize function and variables
// initialize local constants
const int MAX_CMD_LENGTH = 5;
const int MAX_ARG_STR_LENGTH = 15;
// initialize other variables
int numBuffer = 0;
char strBuffer[STD_STR_LEN];
char cmdBuffer[MAX_CMD_LENGTH];
char argStrBuffer[MAX_ARG_STR_LENGTH];
int runningStringIndex = 0;
bool arg2FailureFlag = false;
bool arg3FailureFlag = false;
// get whole op command as string, check for successful access
// fct: getStringToDelimiter
if(getStringToDelimiter(filePtr, SEMICOLON, strBuffer))
{
// get three-letter command
// fct: getCommand
runningStringIndex = getCommand(cmdBuffer,
strBuffer, runningStringIndex);
// assign op command to node
// fct: copyString
copyString(inData->command, cmdBuffer);
}
// otherwise, assume unsuccessful access
else
{
// set ptr to data structure to null
inData = NULL;
// return op command access failure
return OPCMD_ACCESS_ERR;
}
// verify op command
if(!verifyValidCommand(cmdBuffer))
{
// return op command error
return CORRUPT_OPCMD_ERR;
}
// set all struct values that may not be initialized to defaults
inData->pid = 0;
inData->inOutArg[0] = NULL_CHAR;
inData->intArg2 = 0;
inData->intArg3 = 0;
inData->opEndTime = 0.0;
inData->nextNode = NULL;
// check for device command
if(compareString(cmdBuffer, "dev") == 0)
{
// get in/out arg
runningStringIndex = getStringArg(argStrBuffer,
strBuffer, runningStringIndex);
// set device in/out arg
copyString(inData->inOutArg, argStrBuffer);
// check correct argument
if(compareString(argStrBuffer, "in") != 0 &&
compareString(argStrBuffer, "out") != 0)
{
// return argument error
return CORRUPT_OPCMD_ARG_ERR;
}
}
// get first string arg
runningStringIndex = getStringArg(argStrBuffer,
strBuffer, runningStringIndex);
// set device in/out arg
copyString(inData->strArg1, argStrBuffer);
// check for legit first string arg
if(!verifyFirstStringArg(argStrBuffer))
{
// return arg error
return CORRUPT_OPCMD_ARG_ERR;
}
// check for last op command found
if(compareString(inData->command, "sys") == 0 &&
compareString(inData->strArg1, "end") == 0)
{
// return last op command found message
return LAST_OPCMD_FOUND_MSG;
}
// check for app start seconds argument
if(compareString(inData->command, "app") == 0 &&
compareString(inData->strArg1, "start") == 0)
{
// get number argument
// fct: getNumberArg
runningStringIndex = getNumberArg(&numBuffer,
strBuffer, runningStringIndex);
// check for failed number access
if(numBuffer <= BAD_ARG_VAL)
{
// set failure flag
arg2FailureFlag = true;
}
// set first int argument to number
inData->intArg2 = numBuffer;
}
// check for cpu cycle time
else if(compareString(inData->command, "cpu") == 0)
{
// get number argument
// fct: getNumberArg
runningStringIndex = getNumberArg(&numBuffer,
strBuffer, runningStringIndex);
// check for failed number access
if(numBuffer <= BAD_ARG_VAL)
{
// set failure flag
arg2FailureFlag = true;
}
// set first int argument to number
inData->intArg2 = numBuffer;
}
// check for device cycle time
else if(compareString(inData->command, "dev") == 0)
{
// get number argument
// fct: getNumberArg
runningStringIndex = getNumberArg(&numBuffer,
strBuffer, runningStringIndex);
// check for failed number access
if(numBuffer <= BAD_ARG_VAL)
{
// set failure flag
arg2FailureFlag = true;
}
// set first int argument to number
inData->intArg2 = numBuffer;
}
// check for memory base and offset
else if(compareString(inData->command, "mem") == 0)
{
// get number argument
// fct: getNumberArg
runningStringIndex = getNumberArg(&numBuffer,
strBuffer, runningStringIndex);
// check for failed number access
if(numBuffer <= BAD_ARG_VAL)
{
// set failure flag
arg2FailureFlag = true;
}
// set first int argument to number
inData->intArg2 = numBuffer;
// get number argument for offset
// fct: getNumberArg
runningStringIndex = getNumberArg(&numBuffer,
strBuffer, runningStringIndex);
if(numBuffer <= BAD_ARG_VAL)
{
// set failure flag
arg3FailureFlag = true;
}
// set second int argument to number
inData->intArg3 = numBuffer;
}
// check int args for upload failure
if(arg2FailureFlag || arg3FailureFlag)
{
// return corrupt op command found message
return CORRUPT_OPCMD_ARG_ERR;
}
// return complete op command found message
return COMPLETE_OPCMD_FOUND_MSG;
}
/*
Name: getNumberArg
Process: starts at given index, captures
and assembles int arg, returns as parameter
Function Input/Parameters: input str (const char *), starting index (int)
Function Output/Parameters: pointer to captured integer value
Function Output/Returned: updated index for next function start
Device Input/Device: none
Device Output/Device: none
Dependencies: isDigit
*/
int getNumberArg(int *number, const char *inputStr, int index)
{
// initialize function and variables
bool foundDigit = false;
*number = 0;
int multiplier = 1;
// loop to skip whitespace
while(inputStr[index] <= SPACE || inputStr[index] == COMMA)
{
// increment the index
index = index + 1;
}
// loop across string length
while(isDigit(inputStr[index]) &&
inputStr[index] != NULL_CHAR)
{
// set digit found flag
foundDigit = true;
// assign digit to output
(*number) = (*number) * multiplier + (inputStr[index] - '0');
// increment index and multiplier
index = index + 1;
multiplier = 10;
}
// check for digit not found
if(!foundDigit)
{
// set number to BAD_ARG_VAL, use dereference for ptr
*number = BAD_ARG_VAL;
}
// return current index
return index;
}
/*
Name: getStringArg
Process: starts at given index, captures
and assembles str arg, returns as parameter
Function Input/Parameters: input str (const char *), starting index (int)
Function Output/Parameters: ptr to captured string argument (char *)
Function Output/Returned: updated index for next fct start
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
int getStringArg(char *strArg, const char *inputStr, int index)
{
// initialize function and variables
int localIndex = 0;
// loop to skip whitespace
while(inputStr[index] <= SPACE || inputStr[index] == COMMA)
{
// increment the index
index = index + 1;
}
// loop across string length
while(inputStr[index] != COMMA && inputStr[index] != NULL_CHAR)
{
// assign character from input string to buffer string
strArg[localIndex] = inputStr[index];
// increment index
index = index + 1;
localIndex = localIndex + 1;
// set next character to null character
strArg[localIndex] = NULL_CHAR;
}
// return current index
return index;
}
/*
Name: isDigit
Process: tests character parameter for digit,
returns true if is digit, false otherwise
Function Input/Parameters: test character (char)
Function Output/Parameters: none
Function Output/Returned: bool result of test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
bool isDigit(char testChar)
{
// check for test character between characters '0' - '9'
// return true
// otherwise, assume character if not digit, return false
return testChar >= '0' && testChar <= '9';
}
/*
Name: updateEndCount
Process: manages count of "end" arguments
to be compared at end of process input
Function Input/Parameters: initial count (int),
test string for "end" (const char *)
Function Output/Parameters: none
Function Output/Returned: updated count, if "end" string found,
otherwise no change
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
int updateEndCount(int count, const char *opString)
{
// check for "end" in op string
// fct: compareString
if(compareString(opString, "end") == 0)
{
// return incremented end count
return count + 1;
}
// return unchanged end count
return count;
}
/*
Name: updateStartCount
Process: manages count of "start" arguments
to be compared at start of process input
Function Input/Parameters: initial count (int),
test string for "start" (const char *)
Function Output/Parameters: none
Function Output/Returned: updated count, if "start" string found,
otherwise no change
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
int updateStartCount(int count, const char *opString)
{
// check for "start" in op string
// fct: compareString
if (compareString(opString, "start") == 0)
{
// return incremented start count
return count + 1;
}
// return unchanged start count
return count;
}
/*
Name: verifyFirstStringArg
Process: checks for all possibilities of first argument string of op command
Function Input/Parameters: test string (const char *)
Function Output/Parameters: none
Function Output/Returned: bool result of test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
bool verifyFirstStringArg(const char *strArg)
{
// check for string holding correct first argument
// fct: compareString
// return true
// otherwise, assume test fail, return false
return compareString(strArg, "access") == 0 ||
compareString(strArg, "allocate") == 0 ||
compareString(strArg, "end") == 0 ||
compareString(strArg, "ethernet") == 0 ||
compareString(strArg, "hard drive") == 0 ||
compareString(strArg, "keyboard") == 0 ||
compareString(strArg, "monitor") == 0 ||
compareString(strArg, "printer") == 0 ||
compareString(strArg, "process") == 0 ||
compareString(strArg, "serial") == 0 ||
compareString(strArg, "sound signal") == 0 ||
compareString(strArg, "start") == 0 ||
compareString(strArg, "usb") == 0 ||
compareString(strArg, "video signal") == 0;
}
/*
Name: verifyValidCommand
Process: checks for all possibilities of three-letter opcode command
Function Input/Parameters: test string for command (const char *)
Function Output/Parameters: none
Function Output/Returned: bool result of test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
bool verifyValidCommand(char *testCmd)
{
// check for string holding three-letter opcode command
// fct: compareString
// return true
// otherwise, assume test failure, return false
return compareString(testCmd, "sys") == 0 ||
compareString(testCmd, "app") == 0 ||
compareString(testCmd, "cpu") == 0 ||
compareString(testCmd, "mem") == 0 ||
compareString(testCmd, "dev") == 0;
}

207
Sim04/metadataops.h Normal file
View file

@ -0,0 +1,207 @@
#ifndef METADATAOPS
#define METADATAOPS
#include "StandardConstants.h"
#include "StringUtils.h"
typedef enum {BAD_ARG_VAL = -1,
NO_ACCESS_ERR,
MD_FILE_ACCESS_ERR,
MD_CORRUPT_DESCRIPTOR_ERR,
OPCMD_ACCESS_ERR,
CORRUPT_OPCMD_ERR,
CORRUPT_OPCMD_ARG_ERR,
UNBALANCED_START_END_ERR,
COMPLETE_OPCMD_FOUND_MSG,
LAST_OPCMD_FOUND_MSG
} OpCodeMessages;
typedef struct OpCodeTypeStruct
{
int pid;
char command[MAX_STR_LEN];
char inOutArg[MAX_STR_LEN];
char strArg1[MAX_STR_LEN];
int intArg2;
int intArg3;
double opEndTime;
struct OpCodeTypeStruct *nextNode;
} OpCodeType;
/*
Name: addNode
Process: adds metadata node to linked list recursively, handles empty list
Function Input/Parameters: ptr to head or next linked node (OpCodeType *),
ptr to new node (OpCodeType *)
Function Output/Parameters: none
Function Output/Returned: pointer to previous node, or head node (OpCodeType *)
Device Input/Device: none
Device Output/Device: none
Dependencies: malloc, copyString
*/
OpCodeType *addNode(OpCodeType *localPtr, OpCodeType *newNode);
/*
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: calculated time (int)
Device Input/Device: none
Device Output/Device: none
Dependencies: printf, compareString
*/
void displayMetaData(const OpCodeType *localPtr);
/*
Name: getCommand
Process: parses thre letter command part of opcode str
Function Input/Parameters: input opcode str (const char *),
starting index (int)
Function Output/Parameters: parsed command (char *)
Function Output/Returned: updated starting index for use by calling fct (int)
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
int getCommand(char *cmd, const char *inputStr, int index);
/*
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);
/*
Name: getOpCommand
Process: acquires one op command line from a previously opened file,
parses it, and sets various struct members according to the
three letter command
Function Input/Parameters: ptr to open file handle (FILE *)
Function Output/Parameters: ptr to one opcode struct (OpCodeType *)
Function Output/Returned: coded result of operation (OpCodeMessages)
Device Input/File: opcode line uploaded
Device Output/Device: none
Dependencies: getStringToDelimiter, getCommand, copyString, verifyValidCommand,
compareString, getStringArg, verifyFirstStringArg, getNumberArg
*/
OpCodeMessages getOpCommand(FILE *filePtr, OpCodeType *inData);
/*
Name: getNumberArg
Process: starts at given index, captures
and assembles int arg, returns as parameter
Function Input/Parameters: input str (const char *), starting index (int)
Function Output/Parameters: pointer to captured integer value
Function Output/Returned: updated index for next function start
Device Input/Device: none
Device Output/Device: none
Dependencies: isDigit
*/
int getNumberArg(int *number, const char *inputStr, int index);
/*
Name: getStringArg
Process: starts at given index, captures
and assembles str arg, returns as parameter
Function Input/Parameters: input str (const char *), starting index (int)
Function Output/Parameters: ptr to captured string argument (char *)
Function Output/Returned: updated index for next fct start
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
int getStringArg(char *strArg, const char *inputStr, int index);
/*
Name: isDigit
Process: tests character parameter for digit,
returns true if is digit, false otherwise
Function Input/Parameters: test character (char)
Function Output/Parameters: none
Function Output/Returned: bool result of test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
bool isDigit(char testChar);
/*
Name: updateEndCount
Process: manages count of "end" arguments
to be compared at end of process input
Function Input/Parameters: initial count (int),
test string for "end" (const char *)
Function Output/Parameters: none
Function Output/Returned: updated count, if "end" string found,
otherwise no change
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
int updateEndCount(int count, const char *opString);
/*
Name: updateStartCount
Process: manages count of "start" arguments
to be compared at start of process input
Function Input/Parameters: initial count (int),
test string for "start" (const char *)
Function Output/Parameters: none
Function Output/Returned: updated count, if "start" string found,
otherwise no change
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
int updateStartCount(int count, const char *opString);
/*
Name: verifyFirstStringArg
Process: checks for all possibilities of first argument string of op command
Function Input/Parameters: test string (const char *)
Function Output/Parameters: none
Function Output/Returned: bool result of test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
bool verifyFirstStringArg(const char *strArg);
/*
Name: verifyValidCommand
Process: checks for all possibilities of three-letter opcode command
Function Input/Parameters: test string for command (const char *)
Function Output/Parameters: none
Function Output/Returned: bool result of test (bool)
Device Input/Device: none
Device Output/Device: none
Dependencies: compareString
*/
bool verifyValidCommand(char *testCmd);
#endif // METADATAOPS

BIN
Sim04/sim03 Executable file

Binary file not shown.

32
Sim04/sim03_mf Normal file
View file

@ -0,0 +1,32 @@
CC = gcc -Wall -std=c99 -pedantic -g
SOURCES = StringUtils.c simulator.c metadataops.c configops.c OS_SimDriver.c simtimer.c
OBJECTS = OS_SimDriver.o simulator.o metadataops.o configops.o StringUtils.o simtimer.o
all: Simulator
Simulator: $(OBJECTS)
$(CC) $(OBJECTS) -o sim03
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
simtimer.o: simtimer.c
$(CC) -c simtimer.c -o simtimer.o
clean:
rm -f $(OBJECTS) sim03 sim03.out
clean_objects:
rm -f $(OBJECTS)

270
Sim04/simtimer.c Normal file
View file

@ -0,0 +1,270 @@
// Program Information ////////////////////////////////////////////////////////
/**
* @file SimpleTimer.c
*
* @brief Implementation file for using a timer with micro-second precision
*
* @author Michael Leverington
*
* @details Implements member methods for timing
*
* @version 3.00 (02 February 2017) Update to simulator timer
2.00 (13 January 2017) Update to C language
* 1.00 (11 September 2015)
*
* @Note Requires SimpleTimer.h.
*
*/
// Precompiler directives /////////////////////////////////////////////////////
#ifndef SIMTIMER_C
#define SIMTIMER_C
// Header files ///////////////////////////////////////////////////////////////
#include "simtimer.h"
// Constants /////////////////////////////////////////////////////////////////
const char RADIX_POINT = '.';
const char SPACED = ' ';
void *runTimer( void *mSecVoidPtr )
{
struct timeval startTime, endTime;
int startSec, startUSec, endSec, endUSec;
int uSecDiff, mSecDiff, secDiff, timeDiff;
int *mSecPtr = (int *)mSecVoidPtr;
int milliSeconds = *mSecPtr;
gettimeofday( &startTime, NULL );
startSec = startTime.tv_sec;
startUSec = startTime.tv_usec;
timeDiff = 0;
while( timeDiff < milliSeconds )
{
gettimeofday( &endTime, NULL );
endSec = endTime.tv_sec;
endUSec = endTime.tv_usec;
uSecDiff = endUSec - startUSec;
if( uSecDiff < 0 )
{
uSecDiff = uSecDiff + 1000000;
endSec = endSec - 1;
}
mSecDiff = uSecDiff / 1000;
secDiff = ( endSec - startSec ) * 1000;
timeDiff = secDiff + mSecDiff;
}
return NULL;
}
// void runTimer(int milliSeconds)
// {
// struct timeval startTime, endTime;
// int startSec, startUSec, endSec, endUSec;
// int uSecDiff, mSecDiff, secDiff, timeDiff;
// gettimeofday(&startTime, NULL);
// startSec = startTime.tv_sec;
// startUSec = startTime.tv_usec;
// timeDiff = 0;
// while (timeDiff < milliSeconds)
// {
// gettimeofday(&endTime, NULL);
// endSec = endTime.tv_sec;
// endUSec = endTime.tv_usec;
// uSecDiff = endUSec - startUSec;
// if (uSecDiff < 0)
// {
// uSecDiff = uSecDiff + 1000000;
// endSec = endSec - 1;
// }
// mSecDiff = uSecDiff / 1000;
// secDiff = (endSec - startSec) * 1000;
// timeDiff = secDiff + mSecDiff;
// }
// // return NULL;
// }
double accessTimer( int controlCode, char *timeStr )
{
static bool running = false;
static int startSec = 0, endSec = 0, startUSec = 0, endUSec = 0;
static int lapSec = 0, lapUSec = 0;
struct timeval startData, lapData, endData;
double fpTime = 0.0;
switch( controlCode )
{
case ZERO_TIMER:
gettimeofday( &startData, NULL );
running = true;
startSec = startData.tv_sec;
startUSec = startData.tv_usec;
fpTime = 0.000000000;
lapSec = 0.000000000;
lapUSec = 0.000000000;
timeToString( lapSec, lapUSec, timeStr );
break;
case LAP_TIMER:
if( running == true )
{
gettimeofday( &lapData, NULL );
lapSec = lapData.tv_sec;
lapUSec = lapData.tv_usec;
fpTime = processTime( startSec, lapSec,
startUSec, lapUSec, timeStr );
}
else
{
fpTime = 0.000000000;
}
break;
case STOP_TIMER:
if( running == true )
{
gettimeofday( &endData, NULL );
running = false;
endSec = endData.tv_sec;
endUSec = endData.tv_usec;
fpTime = processTime( startSec, endSec,
startUSec, endUSec, timeStr );
}
// assume timer not running
else
{
fpTime = 0.000000000;
}
break;
}
return fpTime;
}
double processTime( double startSec, double endSec,
double startUSec, double endUSec, char *timeStr )
{
double secDiff = endSec - startSec;
double uSecDiff = endUSec - startUSec;
double fpTime;
fpTime = (double) secDiff + (double) uSecDiff / 1000000;
if( uSecDiff < 0 )
{
uSecDiff = uSecDiff + 1000000;
secDiff = secDiff - 1;
}
timeToString( secDiff, uSecDiff, timeStr );
return fpTime;
}
/* This is a bit of a drawn-out function, but it is written
to force the time result to always be in the form x.xxxxxxx
when printed as a string; this will not always be the case
if the time is presented as a floating point number
*/
void timeToString( int secTime, int uSecTime, char *timeStr )
{
int low, high, index = 0;
char temp;
while( uSecTime > 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

49
Sim04/simtimer.h Normal file
View file

@ -0,0 +1,49 @@
// 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 <sys/time.h>
#include <string.h>
#include <math.h>
#include "OS_SimDriver.h"
// Global Constants //////////////////////////////////////////////////////////
enum TIMER_CTRL_CODES { ZERO_TIMER, LAP_TIMER, STOP_TIMER };
extern const char RADIX_POINT;
extern const char SPACED;
// Function Prototyp /////////////////////////////////////////////////////////
void *runTimer(void *mSecVoidPtr);
// will run a timer for the amount of ms specified
double accessTimer( int controlCode, char *timeStr );
// returns the actual time as a double AND as a time string
// no more access needed beyond this point (supporting functions)
double processTime( double startSec, double endSec,
double startUSec, double endUSec, char *timeStr );
void timeToString( int secTime, int uSecTime, char *timeStr );
#endif // ifndef SIMTIMER_H

1021
Sim04/simulator.c Normal file

File diff suppressed because it is too large Load diff

234
Sim04/simulator.h Normal file
View file

@ -0,0 +1,234 @@
#ifndef SIMULATORX
#define SIMULATORX
#include "StandardConstants.h"
#include "configops.h"
#include "metadataops.h"
#include "simtimer.h"
#include <pthread.h>
// data structures
typedef enum{
PROCESS_STATE_NEW = 0,
PROCESS_STATE_READY,
PROCESS_STATE_RUNNING,
PROCESS_STATE_BLOCKED,
PROCESS_STATE_TERMINATED
} PROCESS_STATES;
typedef enum{
MEMORY_INITIALIZE = 0,
MEMORY_ACCESS,
MEMORY_ALLOCATE,
MEMORY_CLEAR,
MEMORY_DEALLOCATE
} MEMORY_SIGNALS;
typedef struct ProcessControlBlockStruct
{
int uniquePid;
PROCESS_STATES process_state;
// need a process start ptr for where the process starts.
// this will be a mini loop within the master loop that goes until it
// hits the app end command.
// it may hold the next opcode, since you don't need to traverse backward
OpCodeType *nextOpCode;
// have an IO cycle count here
int ioCycles;
// have a CPU cycle count here
int cpuCycles;
// maybe have a total cycle count here
int totalCycles;
// time left could be calculated from these.
// potentially could change the cycles or have a 'left' variable to
// see how many are left.
// also need a time left state here?
double timeLeft;
// allocated memory array (stores the offsets)
int *allocatedMemOffsets;
// allocated memory array sizes (stores the sizes for each offset)
int *allocatedMemSizes;
// size of memory array
int memArraySize;
// connect to the next process control block here
struct ProcessControlBlockStruct *nextPtr;
} ProcessControlBlock;
typedef struct ProcessControlBlockLLStruct
{
// holds the head ptr for PCBs
ProcessControlBlock *headPtr;
} ProcessControlBlockLL;
/*
Name: ???
Process: ???
Function Input/Parameters: ???
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
/*
Name: ???
Process: ???
Function Input/Parameters: ???
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
/*
Name: addProcess
Process: allocates the memory for the pcb, grabs the data from the created PCB,
dumps the data so that the node can be linked correctly.
Function Input/Parameters: source PCB (ProcessControlBlock)
Function Output/Parameters: none
Function Output/Returned: filled PCB (ProcessControlBlock *)
Device Input/Device: none
Device Output/Device: none
Dependencies: malloc, sizeof, ???
*/
ProcessControlBlock *addProcess(const ProcessControlBlock source);
/*
Name: createProcessList
Process: initializes head pointer to the PCBs
Function Input/Parameters: none
Function Output/Parameters: none
Function Output/Returned: head pointer to the PCBs
Device Input/Device: none
Device Output/Device: none
Dependencies: malloc, sizeof, ???
*/
ProcessControlBlockLL *createProcessList();
/*
Name: destroyProcessList
Process: deallocates memory used for the linked list struct
Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *)
Function Output/Parameters: none
Function Output/Returned: NULL
Device Input/Device: none
Device Output/Device: none
Dependencies: free, destroyProcessListHelper, ???
*/
ProcessControlBlockLL *destroyProcessList(ProcessControlBlockLL *linkedListPtr);
/*
Name: destroyProcessListHelper
Process: recursively clears the PCB linked list struct, freeing the struct
Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *)
Function Output/Parameters: none
Function Output/Returned: NULL
Device Input/Device: none
Device Output/Device: none
Dependencies: free, destroyProcessListHelper(recursively), ???
*/
ProcessControlBlock *destroyProcessListHelper(ProcessControlBlock *nodePtr);
/*
Name: fillProcessList
Process: iterates through the metadata LL, fills out each process as needed.
Function Input/Parameters: metadata (OpCodeType *),
headPointer (ProcessControlBlockLL *)
Function Output/Parameters: none
Function Output/Returned: pointer to filled PCB (ProcessControlBlockLL *)
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *metadataPtr, ProcessControlBlockLL *headPointer);
/*
Name: findMin
Process: compares two values, returns the smaller of the two.
Function Input/Parameters: two integer values (int)
Function Output/Parameters: none
Function Output/Returned: minimum of the two input integer values (int)
Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
int findMin(int one, int another);
/*
Name: logOutput
Process: Takes in a string, and then outputs it to monitor AND/OR file
Function Input/Parameters: string (char *), file pointer (FILE *),
configuration data (ConfigDataType *),
end of simulator (bool)
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: sprintf, ???
*/
void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd);
/*
Name: runCPU
Process: runs the CPU operations for however long it takes
Function Input/Parameters: ???
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId);
/*
Name: runIO
Process: runs the IO operations for however long it takes
Function Input/Parameters: ???
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId);
/*
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);
/*
Name: scheduleProcess
Process: takes in the scheduling data, and then returns which process is to be ran
Function Input/Parameters: head pointer of PCB List (ProcessControlBlockLL *)
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr);
/*
Name: simThread
Process: wrapper functions for threading in the simulator
Function Input/Parameters: milliseconds (int)
Function Output/Parameters: none
Function Output/Returned: none
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
// void *simThread(int milSec);
#endif // SIMULATORX

86
Sim04/testfile-dnw.mdf Normal file
View file

@ -0,0 +1,86 @@
Start Program Meta-Data Code:
# starting the master loop
sys start
# process 0 start
app start, 0
# process 0 I/O (run HDD for 18 cycles)
dev in, hard drive, 18
# process 0 CPU (run CPU for 9 cycles 3 times)
cpu process, 9
cpu process, 9
cpu process, 9
# process 0 I/O (run monitor for 60 cycles)
dev out, monitor, 60
# process 0 end
app end
# P0 total cycles ran: 105
# process 1 start
app start, 0
# process 1 I/O (run sound for 40 cycles, HDD for 30 cycles, sound for 25 cycles)
dev in, sound signal, 40
dev in, hard drive, 30
dev in, sound signal, 25
# process 1 CPU (run CPU for 6 cycles)
cpu process, 6
# process 1 I/O (run USB for 10 cycles)
dev out, usb, 10
# process 1 end
app end
# P1 total cycles ran: 111
# process 2 start
app start, 0
# process 2 I/O (run video for 70 cycles)
dev in, video signal, 70
# process 2 CPU (run CPU for 10 cycles)
cpu process, 10
# process 2 I/O (run monitor for 70 cycles, HDD for 18 cycles)
dev out, monitor, 70
dev in, hard drive, 18
# process 2 CPU (run CPU for 9 cycles)
cpu process, 9
# process 2 end
app end
# P2 total cycles ran: 177
# process 3 start
app start, 0
# process 3 I/O (run sound for 35 cycles, monitor for 100 cycles, keyboard for 50 cycles)
dev in, sound signal, 35
dev out, monitor, 100
dev in, keyboard, 50
# process 3 CPU (run CPU for 9 cycles)
cpu process, 9
# process 3 I/O (run video for 49 cycles)
dev out, video signal, 49
# process 3 end
app end
# P3 total cycles ran: 243
# process 4 start
app start, 0
# process 4 I/O (run keyboard for 90 cycles, sound for 40 cycles, serial for 32 cycles)
dev in, keyboard, 90
dev out, sound signal, 40
dev out, serial, 32
# process 4 CPU (run CPU for 10 cycles)
cpu process, 10
# process 4 I/O (run HDD for 15 cycles)
dev in, hard drive, 15
# process 4 end
app end
# P4 total cycles ran: 187
# master loop ends
sys end
End Program Meta-Data Code.

12
Sim04/testfile.cnf Normal file
View file

@ -0,0 +1,12 @@
Start Simulator Configuration File:
Version/Phase : 1.00
File Path : testfile.mdf
CPU Scheduling Code : FCFS-N
Quantum Time (cycles) : 55
Memory Available (KB) : 12000
Memory Display (On/Off) : On
Processor Cycle Time (msec) : 10
I/O Cycle Time (msec) : 20
Log To : Monitor
Log File Path : logfile_1.lgf
End Simulator Configuration File.

40
Sim04/testfile.mdf Normal file
View file

@ -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.