Completed Sim01 afaik

+- configops.c/h
+- metadataops.c/h
+- StandardConstants.h
This commit is contained in:
Charles Descamps 2024-01-31 02:33:40 -07:00
parent e19542c060
commit 7b837ddf86
5 changed files with 723 additions and 87 deletions

View file

@ -17,17 +17,31 @@ 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 NULL;
return localPtr;
}
/*
@ -44,11 +58,17 @@ 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;
}
@ -69,29 +89,51 @@ 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 /arg1: %s", localPtr->strArg1);
// print first int argument
// fct: printf
printf("/arg2: %d", localPtr->intArg2);
// print second int argument
// fct: printf
printf("/arg3: %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.
}
@ -109,12 +151,19 @@ 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 0;
return index;
}
/*
@ -136,81 +185,160 @@ bool getMetaData(const char *fileName,
{
// 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
// close file
// fct: fclose
// set end state message
// fct: copyString
// return corrupt descriptor error
// allocate memory for the temporary data structure
// fct: malloc
// get the first op command
// fct: getOpCommand
// get start and end counts for later comparison
// fct: updateStartCount, updateEndCount
// check for failure of first complete op command
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(startCount, 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
// set access result to corrupted descriptor error
// set end state message
// fct: copyString
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 false;
return returnState;
}
/*
@ -230,63 +358,167 @@ 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
// return last op command found message
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
// set first int argument to number
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
// set first int argument to number
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
// set first int argument to number
arg2FailureFlag = true;
}
// set first int argument to number
inData->intArg2 = numBuffer;
}
// check for memory base and offset
// get number argument for base
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
// set first int argument to number
arg2FailureFlag = true;
}
// set first int argument to number
inData->intArg2 = numBuffer;
// get number argument for offset
// fct: getNumberArg
// check for failed number access
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 0;
return COMPLETE_OPCMD_FOUND_MSG;
}
/*
@ -303,16 +535,35 @@ 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
// check for digit not founf
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 0;
return index;
}
/*
@ -329,14 +580,26 @@ Dependencies: none
int getStringArg(char *strArg, const char *inputStr, int index)
{
// initialize function and variables
int localIndex = 0;
// loop to skip whitespace
// increment index
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 0;
return index;
}
/*
@ -355,7 +618,7 @@ bool isDigit(char testChar)
// check for test character between characters '0' - '9'
// return true
// otherwise, assume character if not digit, return false
return false;
return testChar >= '0' && testChar <= '9';
}
/*
@ -375,9 +638,13 @@ 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 0;
return count;
}
/*
@ -397,9 +664,13 @@ int updateStartCount(int count, const char *opString)
{
// check for "start" in op string
// fct: compareString
// return incremented start count
if (compareString(opString, "start") == 0)
{
// return incremented start count
return count + 1;
}
// return unchanged start count
return 0;
return count;
}
/*
@ -418,7 +689,20 @@ bool verifyFirstStringArg(const char *strArg)
// fct: compareString
// return true
// otherwise, assume test fail, return false
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;
}
/*
@ -437,5 +721,9 @@ bool verifyValidCommand(char *testCmd)
// fct: compareString
// return true
// otherwise, assume test failure, return false
return false;
return compareString(testCmd, "sys") == 0 ||
compareString(testCmd, "app") == 0 ||
compareString(testCmd, "cpu") == 0 ||
compareString(testCmd, "mem") == 0 ||
compareString(testCmd, "dev") == 0;
}