Simulator 2 Initialization, changes some of the basics
++ Sim02 Files and Makefile
This commit is contained in:
parent
a2211ac942
commit
cb1bd64489
14 changed files with 2901 additions and 0 deletions
246
Sim02/OS_SimDriver.c
Normal file
246
Sim02/OS_SimDriver.c
Normal 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
Sim02/OS_SimDriver.h
Normal file
74
Sim02/OS_SimDriver.h
Normal 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
|
||||||
76
Sim02/StandardConstants.h
Normal file
76
Sim02/StandardConstants.h
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
// 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 '-'
|
||||||
|
|
||||||
|
// 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
Sim02/StringUtils.c
Normal file
454
Sim02/StringUtils.c
Normal 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
Sim02/StringUtils.h
Normal file
176
Sim02/StringUtils.h
Normal 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
|
||||||
608
Sim02/configops.c
Normal file
608
Sim02/configops.c
Normal 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
Sim02/configops.h
Normal file
168
Sim02/configops.h
Normal 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
|
||||||
729
Sim02/metadataops.c
Normal file
729
Sim02/metadataops.c
Normal 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]) == true &&
|
||||||
|
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 = multiplier + 1;
|
||||||
|
}
|
||||||
|
// 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
Sim02/metadataops.h
Normal file
207
Sim02/metadataops.h
Normal 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
|
||||||
29
Sim02/sim02_mf
Normal file
29
Sim02/sim02_mf
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
CC = gcc -Wall -std=c99 -pedantic -g
|
||||||
|
SOURCES = StringUtils.c simulator.c metadataops.c configops.c OS_SimDriver.c
|
||||||
|
OBJECTS = OS_SimDriver.o simulator.o metadataops.o configops.o StringUtils.o
|
||||||
|
|
||||||
|
all: Simulator
|
||||||
|
|
||||||
|
Simulator: $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) -o sim01
|
||||||
|
|
||||||
|
StringUtils.o: StringUtils.c
|
||||||
|
$(CC) -c StringUtils.c -o StringUtils.o
|
||||||
|
|
||||||
|
simulator.o: simulator.c
|
||||||
|
$(CC) -c simulator.c -o simulator.o
|
||||||
|
|
||||||
|
metadataops.o: metadataops.c
|
||||||
|
$(CC) -c metadataops.c -o metadataops.o
|
||||||
|
|
||||||
|
configops.o: configops.c
|
||||||
|
$(CC) -c configops.c -o configops.o
|
||||||
|
|
||||||
|
OS_SimDriver.o: OS_SimDriver.c
|
||||||
|
$(CC) -c OS_SimDriver.c -o OS_SimDriver.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJECTS) sim01 sim01.out
|
||||||
|
|
||||||
|
clean_objects:
|
||||||
|
rm -f $(OBJECTS)
|
||||||
20
Sim02/simulator.c
Normal file
20
Sim02/simulator.c
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "configops.h"
|
||||||
|
#include "metadataops.h"
|
||||||
|
#include "StandardConstants.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: runSim
|
||||||
|
Process: primary simulation driver
|
||||||
|
Function Input/Parameters: configuration data (ConfigDataType *),
|
||||||
|
metadata (OpCodeType *)
|
||||||
|
Function Output/Parameters: none
|
||||||
|
Function Output/Returned: none
|
||||||
|
Device Input/Device: none
|
||||||
|
Device Output/Device: none
|
||||||
|
Dependencies: ???
|
||||||
|
*/
|
||||||
|
void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
|
||||||
|
{
|
||||||
|
printf("runSim called here");
|
||||||
|
// void function, no return.
|
||||||
|
}
|
||||||
62
Sim02/simulator.h
Normal file
62
Sim02/simulator.h
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef SIMULATORX
|
||||||
|
#define SIMULATORX
|
||||||
|
|
||||||
|
#include "StandardConstants.h"
|
||||||
|
#include "configops.h"
|
||||||
|
#include "metadataops.h"
|
||||||
|
|
||||||
|
// data structures
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
PROCESS_STATE_NEW = 0,
|
||||||
|
PROCESS_STATE_READY,
|
||||||
|
PROCESS_STATE_RUNNING,
|
||||||
|
PROCESS_STATE_BLOCKED,
|
||||||
|
PROCESS_STATE_TERMINATED
|
||||||
|
} PROCESS_STATES;
|
||||||
|
|
||||||
|
typedef struct ProcessControlBlockStruct
|
||||||
|
{
|
||||||
|
int uniquePid;
|
||||||
|
PROCESS_STATES process_state;
|
||||||
|
//
|
||||||
|
} ProcessControlBlock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: ???
|
||||||
|
Process: ???
|
||||||
|
Function Input/Parameters: ???
|
||||||
|
Function Output/Parameters: none
|
||||||
|
Function Output/Returned: none
|
||||||
|
Device Input/Device: none
|
||||||
|
Device Output/Device: none
|
||||||
|
Dependencies: ???
|
||||||
|
*/
|
||||||
|
// need a function (or functions) to handle FILE I/O?
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: ???
|
||||||
|
Process: ???
|
||||||
|
// Function Input/Parameters: ???
|
||||||
|
Function Output/Parameters: none
|
||||||
|
Function Output/Returned: none
|
||||||
|
Device Input/Device: none
|
||||||
|
Device Output/Device: none
|
||||||
|
Dependencies: ???
|
||||||
|
*/
|
||||||
|
// need a function to ???
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: runSim
|
||||||
|
Process: primary simulation driver
|
||||||
|
Function Input/Parameters: configuration data (ConfigDataType *),
|
||||||
|
metadata (OpCodeType *)
|
||||||
|
Function Output/Parameters: none
|
||||||
|
Function Output/Returned: none
|
||||||
|
Device Input/Device: none
|
||||||
|
Device Output/Device: none
|
||||||
|
Dependencies: ???
|
||||||
|
*/
|
||||||
|
void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr);
|
||||||
|
|
||||||
|
#endif // SIMULATORX
|
||||||
12
Sim02/testfile.cnf
Normal file
12
Sim02/testfile.cnf
Normal 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
Sim02/testfile.mdf
Normal file
40
Sim02/testfile.mdf
Normal 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.
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue