// ---------------------------------------------- // C Headers // ---------------------------------------------- #include #include #include #include #include #include // ---------------------------------------------- // Local Headers // ---------------------------------------------- #include "entity.h" #include "token.h" #include "cj.h" // ---------------------------------------------- // Platform dependent directory separator char // ---------------------------------------------- #ifdef _WIN32 # define SEPARATOR "\\" #else # define SEPARATOR "/" #endif // ---------------------------------------------- // cleanup - Close f, populate errMsgPtr // ---------------------------------------------- static bool cleanup(FILE *f, CJString *errMsgPtr, const char *fmt, ...) { if(f) fclose(f); va_list ap; va_start(ap, fmt); vsnprintf(errMsgPtr->mData, sizeof(errMsgPtr->mData), fmt, ap); return(false); } // ---------------------------------------------- // getFileContents - Grab the entirety of // 'fileName', store in *contentsPtr, true on // success false otherwise // ---------------------------------------------- static bool getFileContents( const char *fileName, char **contentsPtr, CJString *errMsgPtr ) { bool ok = true; FILE *f = NULL; #ifdef _MSC_VER errno_t e = fopen_s(&f, fileName, "rb"); if(e) ok = false; #else if((f = fopen(fileName, "rb")) == NULL) ok = false; #endif if(!ok) return(cleanup(NULL, errMsgPtr, "Could not open file: [%s]", fileName)); // Seek to the end, record the size (position), seek back // to the beginning, read in the whole file if(fseek(f, 0L, SEEK_END) != 0) return(cleanup(f, errMsgPtr, "Error calling fseek, file: [%s]", fileName)); long size = ftell(f); if(size == -1) return(cleanup(f, errMsgPtr, "Error calling ftell, file: [%s]", fileName)); if(fseek(f, 0L, SEEK_SET) != 0) return(cleanup(f, errMsgPtr, "Error calling fseek, file: [%s]", fileName)); if((*contentsPtr = malloc(size + 1)) == NULL) return(cleanup(f, errMsgPtr, "Error calling malloc (%ld bytes)", size + 1)); if(fread(*contentsPtr, size, 1, f) != 1) return(cleanup(f, errMsgPtr, "Error calling fread, file: [%s]", fileName)); (*contentsPtr)[size] = '\0'; fclose(f); return(true); } // ----------------------- // banner // ----------------------- static void banner(const char *message) { printf("==================================\n"); printf("%s\n", message); printf("==================================\n\n"); } // ----------------------- // cjTest // ----------------------- static bool cjTest(const char *input, CJString *errMsg) { // Turn 'input' into a list of tokens and // then display them TokenList list = makeTokenList(); if(!getTokens(input, &list, errMsg)) return(false); banner("input"); printf("%s\n\n", input); banner("tokens"); for(int i = 0; i < list.mCount; i++) printToken(&list.mTokens[i]); printf("\n"); // Now turn the tokens into placeholder Entities // and then into the final, top-level Entity object EntityArray array = makeEntityArray(); bool returnValue = false; if(tokensToEntities(&list, &array, errMsg)) { Entity theEntity = makeEntity(); if(getEntity(&array, &theEntity, errMsg)) { returnValue = true; banner("entity"); printEntity(&theEntity); printf("\n"); freeEntity(&theEntity); } } freeTokenList(&list); return(returnValue); } // ----------------------- // runTest // ----------------------- static void runTest(const char *fileName) { banner(fileName); CJString errMsg = makeCJString(); char *buffer = NULL; if(!getFileContents(fileName, &buffer, &errMsg)) { printf("%s\n", errMsg.mData); } else { if(!cjTest(buffer, &errMsg)) printf("%s\n\n", errMsg.mData); free(buffer); } } // ----------------------- // runAllTests // ----------------------- static void runAllTests() { runTest("files" SEPARATOR "input1.txt"); runTest("files" SEPARATOR "input2.txt"); runTest("files" SEPARATOR "input3.txt"); runTest("files" SEPARATOR "input4.txt"); runTest("files" SEPARATOR "input5.txt"); runTest("files" SEPARATOR "input6.txt"); runTest("files" SEPARATOR "input7.txt"); } // ------------------- // main // ------------------- int main() { runAllTests(); return(0); }