From 59913db1ff6af4a4903457334b3a156f3bb7f5d8 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Sat, 24 Apr 2021 16:15:43 -0400 Subject: [PATCH] Cleanup the implementation and split things into separate files a bit. --- md2teach.xcodeproj/project.pbxproj | 14 + md2teach/io.c | 177 ++++++ md2teach/io.h | 25 + md2teach/main.c | 853 +---------------------------- md2teach/main.h | 18 + md2teach/make/createDiskImage | 45 +- md2teach/translate.h | 18 + 7 files changed, 294 insertions(+), 856 deletions(-) create mode 100644 md2teach/io.c create mode 100644 md2teach/io.h create mode 100644 md2teach/main.h create mode 100644 md2teach/translate.h diff --git a/md2teach.xcodeproj/project.pbxproj b/md2teach.xcodeproj/project.pbxproj index 8ca75ea..4c42463 100644 --- a/md2teach.xcodeproj/project.pbxproj +++ b/md2teach.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 9D6532FA2626240800105D50 /* tail.mk in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9D6532F92626240800105D50 /* tail.mk */; }; 9D6532FD2626240800105D50 /* md2teach.xcscheme in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9D6532FC2626240800105D50 /* md2teach.xcscheme */; }; 9D65330D2626246700105D50 /* md4c.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D65330C2626246700105D50 /* md4c.c */; }; + 9D8125DD2634A584002F05F5 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D8125DC2634A584002F05F5 /* io.c */; }; + 9D8125E42634AC4A002F05F5 /* translate.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D8125E32634AC4A002F05F5 /* translate.c */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -49,6 +51,11 @@ 9D6532FC2626240800105D50 /* md2teach.xcscheme */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = md2teach.xcscheme; path = ../../md2teach.xcodeproj/xcshareddata/xcschemes/md2teach.xcscheme; sourceTree = ""; }; 9D65330B2626246700105D50 /* md4c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md4c.h; sourceTree = ""; }; 9D65330C2626246700105D50 /* md4c.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md4c.c; sourceTree = ""; }; + 9D8125DA2634A539002F05F5 /* main.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = ""; }; + 9D8125DB2634A584002F05F5 /* io.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; + 9D8125DC2634A584002F05F5 /* io.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = ""; }; + 9D8125E22634AC4A002F05F5 /* translate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = translate.h; sourceTree = ""; }; + 9D8125E32634AC4A002F05F5 /* translate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = translate.c; sourceTree = ""; }; 9DDFC7B026269D23006D6E71 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 9DDFC7B126269D3F006D6E71 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 9DDFC7B42627E081006D6E71 /* test.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = test.md; sourceTree = ""; }; @@ -94,6 +101,11 @@ isa = PBXGroup; children = ( 9D6532EC2626240800105D50 /* main.c */, + 9D8125DA2634A539002F05F5 /* main.h */, + 9D8125DB2634A584002F05F5 /* io.h */, + 9D8125DC2634A584002F05F5 /* io.c */, + 9D8125E22634AC4A002F05F5 /* translate.h */, + 9D8125E32634AC4A002F05F5 /* translate.c */, 9D65330C2626246700105D50 /* md4c.c */, 9D65330B2626246700105D50 /* md4c.h */, 9D6532EE2626240800105D50 /* Makefile */, @@ -224,7 +236,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9D8125E42634AC4A002F05F5 /* translate.c in Sources */, 9D6532EF2626240800105D50 /* Makefile in Sources */, + 9D8125DD2634A584002F05F5 /* io.c in Sources */, 9D6532ED2626240800105D50 /* main.c in Sources */, 9D65330D2626246700105D50 /* md4c.c in Sources */, ); diff --git a/md2teach/io.c b/md2teach/io.c new file mode 100644 index 0000000..0e57b17 --- /dev/null +++ b/md2teach/io.c @@ -0,0 +1,177 @@ +/* + * io.c + * md2teach + * + * Created by Jeremy Rand on 2021-04-24. + * + */ + +#include +#include +#include +#include + +#include + +#include "io.h" +#include "main.h" + + +// Globals + +static IORecGS writeRec; +static char writeBuffer[4096]; +static int32_t writeBufferOffset = 0; + + +// Implementation + +static void flushBuffer(void) +{ + writeRec.requestCount = writeBufferOffset; + WriteGS(&writeRec); + if (toolerror()) { + fprintf(stderr, "%s: Error writing to output file\n", commandName); + exit(1); + } + writeBufferOffset = 0; +} + + +int openOutputFile(const char * filename) +{ + GSString255 outputFileName; + CreateRecGS createRec; + NameRecGS destroyRec; + OpenRecGS openRec; + + outputFileName.length = strlen(filename); + if (outputFileName.length >= sizeof(outputFileName.text)) { + fprintf(stderr, "%s: Output file path too long, %s\n", commandName, outputFileName); + return 1; + } + strcpy(outputFileName.text, filename); + + destroyRec.pCount = 1; + destroyRec.pathname = &outputFileName; + DestroyGS(&destroyRec); + + createRec.pCount = 5; + createRec.pathname = &outputFileName; + createRec.access = destroyEnable | renameEnable | readWriteEnable; + createRec.fileType = 0x50; // Type for Teach file + createRec.auxType = 0x5445; // Aux type for Teach file + createRec.storageType = extendedFile; + CreateGS(&createRec); + if (toolerror()) { + fprintf(stderr, "%s: Unable to create output file %s\n", commandName, outputFileName.text); + return 1; + } + + openRec.pCount = 3; + openRec.refNum = 0; + openRec.pathname = &outputFileName; + openRec.requestAccess = writeEnable; + OpenGS(&openRec); + if (toolerror()) { + fprintf(stderr, "%s: Unable to open output file %s\n", commandName, outputFileName.text); + return 1; + } + + writeRec.pCount = 4; + writeRec.refNum = openRec.refNum; + writeRec.dataBuffer = writeBuffer; + return 0; +} + + +void writeChar(MD_CHAR ch) +{ + if (writeBufferOffset == sizeof(writeBuffer)) + flushBuffer(); + + if (ch == '\n') + ch = '\r'; + writeBuffer[writeBufferOffset] = ch; + writeBufferOffset++; +} + + +void writeString(const MD_CHAR * str, MD_SIZE size) +{ + MD_SIZE i; + + for (i = 0; i < size; i++) + writeChar(str[i]); +} + + +void closeOutputFile(void) +{ + RefNumRecGS closeRec; + + if (writeBufferOffset > 0) + flushBuffer(); + closeRec.pCount = 1; + closeRec.refNum = writeRec.refNum; + CloseGS(&closeRec); +} + + +const MD_CHAR * readInputFile(const char * filename, MD_SIZE * bufferSize) +{ + FILE * inputFile; + MD_CHAR * inputBuffer; + MD_SIZE inputFileLen; + + inputFile = fopen(filename, "r"); + if (inputFile == NULL) { + fprintf(stderr, "%s: Unable to open input file %s, %s\n", commandName, filename, strerror(errno)); + return NULL; + } + + if (fseek(inputFile, 0l, SEEK_END) != 0) { + fprintf(stderr, "%s: Unable to seek to the end of file %s, %s\n", commandName, filename, strerror(errno)); + fclose(inputFile); + return NULL; + } + + inputFileLen = ftell(inputFile); + if (inputFileLen < 0) { + fprintf(stderr, "%s: Unable to get size of file %s, %s\n", commandName, filename, strerror(errno)); + fclose(inputFile); + return NULL; + } + + inputBuffer = malloc(inputFileLen); + if (inputBuffer == NULL) { + fprintf(stderr, "%s: Unable to allocate %ld bytes for input buffer\n", commandName, inputFileLen); + fclose(inputFile); + return NULL; + } + + if (fseek(inputFile, 0l, SEEK_SET) != 0) { + fprintf(stderr, "%s: Unable to seek to the beginning of file %s, %s\n", commandName, filename, strerror(errno)); + free(inputBuffer); + fclose(inputFile); + return NULL; + } + + if (fread(inputBuffer, 1, inputFileLen, inputFile) != inputFileLen) { + fprintf(stderr, "%s: Unable to read all of file %s, %s\n", commandName, filename, strerror(errno)); + free(inputBuffer); + fclose(inputFile); + return NULL; + } + + fclose(inputFile); + + *bufferSize = inputFileLen; + return inputBuffer; +} + + +void releaseInputBuffer(const MD_CHAR * inputBuffer) +{ + free(inputBuffer); +} diff --git a/md2teach/io.h b/md2teach/io.h new file mode 100644 index 0000000..18562fc --- /dev/null +++ b/md2teach/io.h @@ -0,0 +1,25 @@ +/* + * io.h + * md2teach + * + * Created by Jeremy Rand on 2021-04-24. + * + */ + +#ifndef _GUARD_PROJECTmd2teach_FILEio_ +#define _GUARD_PROJECTmd2teach_FILEio_ + + +#include "md4c.h" + + +extern int openOutputFile(const char * filename); +extern void writeChar(MD_CHAR ch); +extern void writeString(const MD_CHAR * str, MD_SIZE size); +extern void closeOutputFile(void); + +extern const MD_CHAR * readInputFile(const char * filename, MD_SIZE * bufferSize); +extern void releaseInputBuffer(const MD_CHAR * inputBuffer); + + +#endif /* define _GUARD_PROJECTmd2teach_FILEio_ */ diff --git a/md2teach/main.c b/md2teach/main.c index d2c2c5f..cc1b66d 100644 --- a/md2teach/main.c +++ b/md2teach/main.c @@ -8,20 +8,19 @@ */ -#include #include #include #include #include -#include #include #include +#include "io.h" +#include "main.h" +#include "translate.h" #include "md4c.h" -#pragma memorymodel 1 - // GS_TODO - How big does the stack need to be? In looking over the code, // I don't see massive stack frames due to large globals (other than the // context which I made static). But I do see lots of arguments and if @@ -52,27 +51,6 @@ // Typedefs -typedef struct tBlockListItem -{ - MD_BLOCKTYPE type; - union { - MD_BLOCK_UL_DETAIL ulDetail; - MD_BLOCK_OL_DETAIL olDetail; - MD_BLOCK_H_DETAIL hDetail; - MD_BLOCK_CODE_DETAIL codeDetail; - } u; - int numTabs; - - struct tBlockListItem * next; -} tBlockListItem; - -typedef struct tEntity -{ - const char * entityString; - char entityChar; - uint32_t unicodeChar; -} tEntity; - typedef struct tWindowPos { int16_t height; @@ -116,41 +94,12 @@ typedef struct tFormat //typedef struct tStyle -// Forward declarations - -static int enterBlockHook(MD_BLOCKTYPE type, void * detail, void * userdata); -static int leaveBlockHook(MD_BLOCKTYPE type, void * detail, void * userdata); -static int enterSpanHook(MD_SPANTYPE type, void * detail, void * userdata); -static int leaveSpanHook(MD_SPANTYPE type, void * detail, void * userdata); -static int textHook(MD_TEXTTYPE type, const MD_CHAR * text, MD_SIZE size, void * userdata); -static void debugLogHook(const char * message, void * userdata); - // Globals -MD_PARSER parser = { - 0, // abi_version - MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS, // flags - enterBlockHook, - leaveBlockHook, - enterSpanHook, - leaveSpanHook, - textHook, - debugLogHook, - NULL // syntax -}; - void * lowestStackSeen; char * commandName; -int debugIndentLevel = 0; int debugEnabled = 0; -int isFirstNonDocumentBlock = 1; - -tBlockListItem * blockList = NULL; - -IORecGS writeRec; -char writeBuffer[4096]; -int writeBufferOffset = 0; tWindowPos windowPos = { 0xad, // height @@ -178,702 +127,23 @@ uint8_t headerFontSizes[NUM_HEADER_SIZES] = { tFormat * formatPtr = NULL; -tEntity entities[] = { - { " ", 0x9, 0x9 }, - { " ", 0x13, 0x10 }, - { "!", 0x21, 0x21 }, - { """, 0x22, 0x22 }, - { """, 0x22, 0x22 }, - { "#", 0x23, 0x23 }, - { "$", 0x24, 0x24 }, - { "%", 0x25, 0x25 }, - { "&", 0x26, 0x26 }, - { "'", 0x27, 0x27 }, - { "(", 0x28, 0x28 }, - { ")", 0x29, 0x29 }, - { "*", 0x2a, 0x2a }, - { "*", 0x2a, 0x2a }, - { "+", 0x2b, 0x2b }, - { ",", 0x2c, 0x2c }, - { ".", 0x2e, 0x2e }, - { "/", 0x2f, 0x2f }, - { ":", 0x3a, 0x3a }, - { ";", 0x3b, 0x3b }, - { "<", 0x3c, 0x3c }, - { "<", 0x3c, 0x3c }, - { "=", 0x3d, 0x3d }, - { ">", 0x3e, 0x3e }, - { ">", 0x3e, 0x3e }, - { "?", 0x3f, 0x3f }, - { "@", 0x40, 0x40 }, - { "[", 0x5b, 0x5b }, - { "[", 0x5b, 0x5b }, - { "\", 0x5c, 0x5c }, - { "]", 0x5d, 0x5d }, - { "]", 0x5d, 0x5d }, - { "^", 0x5e, 0x5e }, - { "_", 0x5f, 0x5f }, - { "`", 0x60, 0x60 }, - { "`", 0x60, 0x60 }, - { "{", 0x7b, 0x7b }, - { "{", 0x7b, 0x7b }, - { "|", 0x7c, 0x7c }, - { "|", 0x7c, 0x7c }, - { "|", 0x7c, 0x7c }, - { "}", 0x7d, 0x7d }, - { "}", 0x7d, 0x7d }, - { " ", 0xca, 0xa0 }, - { " ", 0xca, 0xa0 }, - { "¡", 0xc1, 0xa1 }, - { "¢", 0xa2, 0xa2 }, - { "£", 0xa3, 0xa3 }, - { "¤", 0xdb, 0xa4 }, - { "¥", 0xb4, 0xa5 }, - { "§", 0xa4, 0xa7 }, - { "¨", 0xac, 0xa8 }, - { "¨", 0xac, 0xa8 }, - { "¨", 0xac, 0xa8 }, - { "¨", 0xac, 0xa8 }, - { "©", 0xa9, 0xa9 }, - { "©", 0xa9, 0xa9 }, - { "ª", 0xbb, 0xaa }, - { "«", 0xc7, 0xab }, - { "¬", 0xc2, 0xac }, - { "®", 0xa8, 0xae }, - { "&circleR;", 0xa8, 0xae }, - { "®", 0xa8, 0xae }, - { "¯", 0xf8, 0xaf }, - { "‾", 0xf8, 0xaf }, - { "¯", 0xf8, 0xaf }, - { "°", 0xa1, 0xb0 }, - { "±", 0xb1, 0xb1 }, - { "±", 0xb1, 0xb1 }, - { "±", 0xb1, 0xb1 }, - { "´", 0xab, 0xb4 }, - { "´", 0xab, 0xb4 }, - { "µ", 0xb5, 0xb5 }, - { "¶", 0xa6, 0xb6 }, - { "·", 0xe1, 0xb7 }, - { "·", 0xe1, 0xb7 }, - { "·", 0xe1, 0xb7 }, - { "¸", 0xfc, 0xb8 }, - { "¸", 0xfc, 0xb8 }, - { "º", 0xbc, 0xba }, - { "»", 0xc8, 0xbb }, - { "¿", 0xc0, 0xbf }, - { "À", 0xcb, 0xc0 }, - { "Á", 0xe7, 0xc1 }, - { "Â", 0xe5, 0xc2 }, - { "Ã", 0xcc, 0xc3 }, - { "Ä", 0x80, 0xc4 }, - { "Å", 0x81, 0xc5 }, - { "Æ", 0xae, 0xc6 }, - { "Ç", 0x82, 0xc7 }, - { "È", 0xe9, 0xc8 }, - { "É", 0x83, 0xc9 }, - { "Ê", 0xe6, 0xca }, - { "Ë", 0xe8, 0xcb }, - { "Ì", 0xed, 0xcc }, - { "Í", 0xea, 0xcd }, - { "Î", 0xeb, 0xce }, - { "Ï", 0xec, 0xcf }, - { "Ñ", 0x84, 0xd1 }, - { "Ò", 0xf1, 0xd2 }, - { "Ó", 0xee, 0xd3 }, - { "Ô", 0xef, 0xd4 }, - { "Õ", 0xcd, 0xd5 }, - { "Ö", 0x85, 0xd6 }, - { "Ø", 0xaf, 0xd8 }, - { "Ù", 0xf4, 0xd9 }, - { "Ú", 0xf2, 0xda }, - { "Û", 0xf3, 0xdb }, - { "Ü", 0x86, 0xdc }, - { "ß", 0xa7, 0xdf }, - { "à", 0x88, 0xe0 }, - { "á", 0x87, 0xe1 }, - { "â", 0x89, 0xe2 }, - { "ã", 0x8b, 0xe3 }, - { "ä", 0x8a, 0xe4 }, - { "å", 0x8c, 0xe5 }, - { "æ", 0xbe, 0xe6 }, - { "ç", 0x8d, 0xe7 }, - { "è", 0x8f, 0xe8 }, - { "é", 0x8e, 0xe9 }, - { "ê", 0x90, 0xea }, - { "ë", 0x91, 0xeb }, - { "ì", 0x93, 0xec }, - { "í", 0x92, 0xed }, - { "î", 0x94, 0xee }, - { "ï", 0x95, 0xef }, - { "ñ", 0x96, 0xf1 }, - { "ò", 0x98, 0xf2 }, - { "ó", 0x97, 0xf3 }, - { "ô", 0x99, 0xf4 }, - { "õ", 0x9b, 0xf5 }, - { "ö", 0x9a, 0xf6 }, - { "÷", 0xd6, 0xf7 }, - { "÷", 0xd6, 0xf7 }, - { "ø", 0xbf, 0xf8 }, - { "ù", 0x9d, 0xf9 }, - { "ú", 0x9c, 0xfa }, - { "û", 0x9e, 0xfb }, - { "ü", 0x9f, 0xfc }, - { "ÿ", 0xd8, 0xff }, - { "†", 0xa0, 0x2020 }, - { "•", 0xa5, 0x2022 }, - { "•", 0xa5, 0x2022 }, - { "™", 0xaa, 0x2122 }, - { "™", 0xaa, 0x2122 }, - { "≠", 0xad, 0x2260 }, - { "≠", 0xad, 0x2260 }, - { "∞", 0xb0, 0x221e }, - { "≤", 0xb2, 0x2264 }, - { "≤", 0xb2, 0x2264 }, - { "&LessEqual;", 0xb2, 0x2264 }, - { "≥", 0xb3, 0x2265 }, - { "≥", 0xb3, 0x2265 }, - { "≥", 0xb3, 0x2265 }, - { "∂", 0xb6, 0x2202 }, - { "∂", 0xb6, 0x2202 }, - { "∑", 0xb7, 0x2211 }, - { "∑", 0xb7, 0x2211 }, - { "∏", 0xb8, 0x220f }, - { "∏", 0xb8, 0x220f }, - { "π", 0xb9, 0x3c0 }, - { "∫", 0xba, 0x222b }, - { "∫", 0xba, 0x222b }, - { "Ω", 0xbd, 0x3a9 }, - { "√", 0xc3, 0x221a }, - { "√", 0xc3, 0x221a }, - { "ƒ", 0xc4, 0x192 }, - { "≈", 0xc5, 0x2248 }, - { "≈", 0xc5, 0x2248 }, - { "≈", 0xc5, 0x2248 }, - { "≈", 0xc5, 0x2248 }, - { "≈", 0xc5, 0x2248 }, - { "≈", 0xc5, 0x2248 }, - { "Δ", 0xc6, 0x394 }, - { "…", 0xc9, 0x2026 }, - { "…", 0xc9, 0x2026 }, - { "Œ", 0xce, 0x152 }, - { "œ", 0xcf, 0x153 }, - { "–", 0xd0, 0x2013 }, - { "—", 0xd1, 0x2014 }, - { "“", 0xd2, 0x201c }, - { "“", 0xd2, 0x201c }, - { "”", 0xd3, 0x201d }, - { "”", 0xd3, 0x201d }, - { "”", 0xd3, 0x201d }, - { "‘", 0xd4, 0x2018 }, - { "‘", 0xd4, 0x2018 }, - { "’", 0xd5, 0x2019 }, - { "’", 0xd5, 0x2019 }, - { "’", 0xd5, 0x2019 }, - { "◊", 0xd7, 0x25ca }, - { "◊", 0xd7, 0x25ca }, - { "Ÿ", 0xd9, 0x178 }, - { "⁄", 0xda, 0x2044 }, - { "‹", 0xdc, 0x2039 }, - { "›", 0xdd, 0x203a }, - { "fi", 0xde, 0xfb01 }, - { "fl", 0xdf, 0xfb02 }, - { "‡", 0xe0, 0x2021 }, - { "‡", 0xe0, 0x2021 }, - { "‚", 0xe2, 0x201a }, - { "‚", 0xe2, 0x201a }, - { "„", 0xe3, 0x201e }, - { "„", 0xe3, 0x201e }, - { "‰", 0xe4, 0x2030 }, - { "", 0xf0, 0xf8ff }, - { "ı", 0xf5, 0x131 }, - { "ı", 0xf5, 0x131 }, - { "ˆ", 0xf6, 0x2c6 }, - { "˜", 0xf7, 0x2dc }, - { "˜", 0xf7, 0x2dc }, - { "˘", 0xf9, 0x2d8 }, - { "˘", 0xf9, 0x2d8 }, - { "˙", 0xfa, 0x2d9 }, - { "˙", 0xfa, 0x2d9 }, - { "˚", 0xfb, 0x2da }, - { "˝", 0xfd, 0x2dd }, - { "˝", 0xfd, 0x2dd }, - { "˛", 0xfe, 0x2db }, - { "ˇ", 0xff, 0x2c7 }, - { "ˇ", 0xff, 0x2c7 }, - - // GS_TODO - Test each of these entities. -}; - // Implementation -void flushBuffer(void) -{ - writeRec.requestCount = writeBufferOffset; - WriteGS(&writeRec); - if (toolerror()) { - fprintf(stderr, "%s: Error writing to output file\n", commandName); - exit(1); - } - writeBufferOffset = 0; -} - -void writeChar(MD_CHAR ch) -{ - if (writeBufferOffset == sizeof(writeBuffer)) - flushBuffer(); - - if (ch == '\n') - ch = '\r'; - writeBuffer[writeBufferOffset] = ch; - writeBufferOffset++; -} - -void writeString(MD_CHAR * str, MD_SIZE size) -{ - MD_SIZE i; - - for (i = 0; i < size; i++) - writeChar(str[i]); -} - -static int enterBlockHook(MD_BLOCKTYPE type, void * detail, void * userdata) -{ - tBlockListItem * newBlock = malloc(sizeof(tBlockListItem)); - - if (newBlock == NULL) { - fprintf(stderr, "%s: Out of memory", commandName); - return 1; - } - - newBlock->type = type; - if (blockList == NULL) - newBlock->numTabs = 0; - else - newBlock->numTabs = blockList->numTabs; - newBlock->next = blockList; - blockList = newBlock; - - if ((detail != NULL) && - (detail < lowestStackSeen)) - lowestStackSeen = detail; - - switch (type) { - case MD_BLOCK_DOC: - if (debugEnabled) - fprintf(stderr, "%*sDOC {\n", debugIndentLevel, ""); - break; - - case MD_BLOCK_QUOTE: - if (debugEnabled) - fprintf(stderr, "%*sQUOTE {\n", debugIndentLevel, ""); - - break; - - case MD_BLOCK_UL: { - MD_BLOCK_UL_DETAIL * ulDetail = (MD_BLOCK_UL_DETAIL *)detail; - if (debugEnabled) - fprintf(stderr, "%*sUL (is_tight=%d, mark=%c) {\n", debugIndentLevel, "", ulDetail->is_tight, ulDetail->mark); - - memcpy(&(newBlock->u.ulDetail), ulDetail, sizeof(*ulDetail)); - newBlock->numTabs++; - - if (!isFirstNonDocumentBlock) - writeChar('\r'); - break; - } - - case MD_BLOCK_OL: { - MD_BLOCK_OL_DETAIL * olDetail = (MD_BLOCK_OL_DETAIL *)detail; - if (debugEnabled) - fprintf(stderr, "%*sOL (start=%u, is_tight=%d, mark_delimiter=%c) {\n", debugIndentLevel, "", olDetail->start, olDetail->is_tight, olDetail->mark_delimiter); - - memcpy(&(newBlock->u.olDetail), olDetail, sizeof(*olDetail)); - newBlock->numTabs++; - - if (!isFirstNonDocumentBlock) - writeChar('\r'); - break; - } - - case MD_BLOCK_LI: { - int i; - tBlockListItem * enclosingBlock = newBlock->next; - int isNumbered = 0; - static char str[16]; - - if (debugEnabled) - fprintf(stderr, "%*sLI {\n", debugIndentLevel, ""); - - if (enclosingBlock == NULL) { - fprintf(stderr, "%s: Got a list item block without an enclosing block\n", commandName); - return 1; - } - - if (enclosingBlock->type == MD_BLOCK_OL) { - isNumbered = 1; - if ((!enclosingBlock->u.olDetail.is_tight) && - (!isFirstNonDocumentBlock)) - writeChar('\r'); - } else if (enclosingBlock->type == MD_BLOCK_UL) { - if ((!enclosingBlock->u.ulDetail.is_tight) && - (!isFirstNonDocumentBlock)) - writeChar('\r'); - } - - for (i = 0; i < newBlock->numTabs; i++) - writeChar('\t'); - - if (isNumbered) { - sprintf(str, "%u%c ", enclosingBlock->u.olDetail.start, enclosingBlock->u.olDetail.mark_delimiter); - enclosingBlock->u.olDetail.start++; - } else { - sprintf(str, "%c ", 0xa5); // 0xa5 is a bullet character - } - writeString(str, strlen(str)); - - break; - } - - case MD_BLOCK_HR: { - int i; - - if (debugEnabled) - fprintf(stderr, "%*sHR {\n", debugIndentLevel, ""); - - if (!isFirstNonDocumentBlock) - writeChar('\r'); - - for (i = 0; i < 30; i++) - writeChar('_'); - break; - } - - case MD_BLOCK_H: { - MD_BLOCK_H_DETAIL * hDetail = (MD_BLOCK_H_DETAIL *)detail; - if (debugEnabled) - fprintf(stderr, "%*sH (level=%u) {\n", debugIndentLevel, "", hDetail->level); - - memcpy(&(newBlock->u.hDetail), hDetail, sizeof(*hDetail)); - - if (!isFirstNonDocumentBlock) - writeChar('\r'); - break; - } - - case MD_BLOCK_CODE: { - MD_BLOCK_CODE_DETAIL * codeDetail = (MD_BLOCK_CODE_DETAIL *)detail; - if (debugEnabled) { - fprintf(stderr, "%*sCODE ", debugIndentLevel, ""); - if (codeDetail->fence_char != '\0') { - fprintf(stderr, "(fence_char=%c) ", codeDetail->fence_char); - } - fprintf(stderr, "{\n"); - } - - memcpy(&(newBlock->u.codeDetail), codeDetail, sizeof(*codeDetail)); - - if (!isFirstNonDocumentBlock) - writeChar('\r'); - break; - } - - case MD_BLOCK_P: - if (debugEnabled) - fprintf(stderr, "%*sP {\n", debugIndentLevel, ""); - - if (!isFirstNonDocumentBlock) - writeChar('\r'); - break; - - default: - fprintf(stderr, "%s: Invalid block type (%d)\n", commandName, (int)type); - return 1; - break; - } - - - if (type != MD_BLOCK_DOC) - isFirstNonDocumentBlock = 0; - - debugIndentLevel+=2; - return 0; -} - - -static int leaveBlockHook(MD_BLOCKTYPE type, void * detail, void * userdata) -{ - tBlockListItem * oldBlock = blockList; - - if (oldBlock == NULL) { - fprintf(stderr, "%s: Block list is empty but leaving block of type %d\n", commandName, (int)type); - return 1; - } - - if (oldBlock->type != type) { - fprintf(stderr, "%s: Expected to leave block of type %d but got type %d\n", commandName, (int)oldBlock->type, (int)type); - return 1; - } - - blockList = oldBlock->next; - free(oldBlock); - - if ((detail != NULL) && - (detail < lowestStackSeen)) - lowestStackSeen = detail; - - switch (type) { - case MD_BLOCK_DOC: - break; - - case MD_BLOCK_QUOTE: - break; - - case MD_BLOCK_UL: - writeChar('\r'); - break; - - case MD_BLOCK_OL: - writeChar('\r'); - break; - - case MD_BLOCK_LI: - writeChar('\r'); - break; - - case MD_BLOCK_HR: - writeChar('\r'); - break; - - case MD_BLOCK_H: - writeChar('\r'); - break; - - case MD_BLOCK_CODE: - writeChar('\r'); - break; - - case MD_BLOCK_P: - writeChar('\r'); - break; - - default: - fprintf(stderr, "%s: Invalid block type (%d)\n", commandName, (int)type); - return 1; - break; - } - - debugIndentLevel-=2; - if (debugEnabled) - fprintf(stderr, "%*s}\n", debugIndentLevel, ""); - - return 0; -} - - -static int enterSpanHook(MD_SPANTYPE type, void * detail, void * userdata) -{ - if ((detail != NULL) && - (detail < lowestStackSeen)) - lowestStackSeen = detail; - - switch (type) { - case MD_SPAN_EM: - if (debugEnabled) - fprintf(stderr, "%*sEM {\n", debugIndentLevel, ""); - break; - - case MD_SPAN_STRONG: - if (debugEnabled) - fprintf(stderr, "%*sSTRONG {\n", debugIndentLevel, ""); - break; - - case MD_SPAN_A: - if (debugEnabled) - fprintf(stderr, "%*sA {\n", debugIndentLevel, ""); - break; - - case MD_SPAN_IMG: - if (debugEnabled) - fprintf(stderr, "%*sIMG {\n", debugIndentLevel, ""); - break; - - case MD_SPAN_CODE: - if (debugEnabled) - fprintf(stderr, "%*sCODE {\n", debugIndentLevel, ""); - break; - - default: - fprintf(stderr, "%s: Invalid span type (%d)\n", commandName, (int)type); - return 1; - break; - } - - debugIndentLevel+=2; - return 0; -} - - -static int leaveSpanHook(MD_SPANTYPE type, void * detail, void * userdata) -{ - if ((detail != NULL) && - (detail < lowestStackSeen)) - lowestStackSeen = detail; - - switch (type) { - case MD_SPAN_EM: - break; - - case MD_SPAN_STRONG: - break; - - case MD_SPAN_A: - break; - - case MD_SPAN_IMG: - break; - - case MD_SPAN_CODE: - break; - - default: - fprintf(stderr, "%s: Invalid span type (%d)\n", commandName, (int)type); - return 1; - break; - } - - debugIndentLevel-=2; - if (debugEnabled) - fprintf(stderr, "%*s}\n", debugIndentLevel, ""); - - return 0; -} - -static void printEntity(const MD_CHAR * text, MD_SIZE size) -{ - int entityNum; - uint32_t unicodeChar = 0; - - if (size < 4) - return; - - if (text[0] != '&') - return; - - if (text[size - 1] != ';') - return; - - if (text[1] == '#') { - char * end; - unicodeChar = strtoul(text + 2, &end, 10); - if (end != text + size - 1) - unicodeChar = 0; - if ((unicodeChar > 0) && - (unicodeChar < 128)) { - writeChar(unicodeChar); - return; - } - } - - if (text[1] == 'x') { - char * end; - unicodeChar = strtoul(text + 2, &end, 16); - if (end != text + size - 1) - unicodeChar = 0; - if ((unicodeChar > 0) && - (unicodeChar < 128)) { - writeChar(unicodeChar); - return; - } - } - - for (entityNum = 0; entityNum < (sizeof(entities) / sizeof(entities[0])); entityNum++) { - if ((unicodeChar == entities[entityNum].unicodeChar) || - (strncmp(entities[entityNum].entityString, text, size) == 0)) { - writeChar(entities[entityNum].entityChar); - return; - } - } -} - -static int textHook(MD_TEXTTYPE type, const MD_CHAR * text, MD_SIZE size, void * userdata) -{ - switch (type) { - case MD_TEXT_NORMAL: - if (debugEnabled) - fprintf(stderr, "%*sText: \"", debugIndentLevel, ""); - break; - - case MD_TEXT_NULLCHAR: - fprintf(stderr, "%s: Null character encountered on input\n", commandName); - return 1; - - case MD_TEXT_BR: - if (debugEnabled) - fprintf(stderr, "%*sBR\n", debugIndentLevel, ""); - putchar('\n'); - return 0; - - case MD_TEXT_SOFTBR: - if (debugEnabled) - fprintf(stderr, "%*sSOFT BR\n", debugIndentLevel, ""); - return 0; - - case MD_TEXT_ENTITY: - if (debugEnabled) { - fprintf(stderr, "%*sEntity: \"", debugIndentLevel, ""); - fwrite(text, sizeof(MD_CHAR), size, stderr); - } - - printEntity(text, size); - text = ""; - size = 0; - break; - - case MD_TEXT_CODE: - if (debugEnabled) - fprintf(stderr, "%*sCode: \"", debugIndentLevel, ""); - break; - - default: - fprintf(stderr, "%s: Invalid text type (%d)\n", commandName, (int)type); - return 1; - break; - } - - if (debugEnabled) { - fwrite(text, sizeof(MD_CHAR), size, stderr); - fprintf(stderr, "\"\n"); - } - - if (size > 0) - writeString(text, size); - - return 0; -} - - -static void debugLogHook(const char * message, void * userdata) -{ - if (debugEnabled) - fprintf(stderr, "DEBUG: %s\n", message); -} - static void printUsage(void) { fprintf(stderr, "USAGE: %s [ -d ] inputfile outputfile\n", commandName); - exit(1); } static int parseArgs(int argc, char * argv[]) { - commandName = argv[0]; - static int index; static int charOffset; static int optionLen; + commandName = argv[0]; + for (index = 1; index < argc; index++) { if (argv[index][0] != '-') break; @@ -887,6 +157,7 @@ static int parseArgs(int argc, char * argv[]) default: printUsage(); + return -1; break; } } @@ -894,6 +165,7 @@ static int parseArgs(int argc, char * argv[]) if (index + 2 != argc) { printUsage(); + return -1; } return index; @@ -903,118 +175,39 @@ static int parseArgs(int argc, char * argv[]) int main(int argc, char * argv[]) { int result; - - static char * inputFileName; - static FILE * inputFile; - static long inputFileLen; - static char * inputBuffer; - - static GSString255 outputFileName; - static CreateRecGS createRec; - static NameRecGS destroyRec; - static OpenRecGS openRec; - static RefNumRecGS closeRec; - - static int index; + MD_SIZE inputFileLen; + MD_CHAR * inputBuffer; + int index; lowestStackSeen = &result; index = parseArgs(argc, argv); - inputFileName = argv[index]; - - outputFileName.length = strlen(argv[index + 1]); - if (outputFileName.length >= sizeof(outputFileName.text)) { - fprintf(stderr, "%s: Output file path too long, %s\n", commandName, outputFileName); + if (index < 0) exit(1); - } - strcpy(outputFileName.text, argv[index + 1]); - destroyRec.pCount = 1; - destroyRec.pathname = &outputFileName; - DestroyGS(&destroyRec); + inputBuffer = readInputFile(argv[index], &inputFileLen); + if (inputBuffer == NULL) + exit(1); - createRec.pCount = 7; - createRec.pathname = &outputFileName; - createRec.access = destroyEnable | renameEnable | readWriteEnable; - createRec.fileType = 0x50; // Type for Teach file - createRec.auxType = 0x5445; // Aux type for Teach file - createRec.storageType = extendedFile; - CreateGS(&createRec); - if (toolerror()) { - fprintf(stderr, "%s: Unable to create output file %s\n", commandName, outputFileName.text); + if (openOutputFile(argv[index + 1]) != 0) { + releaseInputBuffer(inputBuffer); exit(1); } - openRec.pCount = 3; - openRec.refNum = 0; - openRec.pathname = &outputFileName; - openRec.requestAccess = writeEnable; - OpenGS(&openRec); - if (toolerror()) { - fprintf(stderr, "%s: Unable to open output file %s\n", commandName, outputFileName.text); - exit(1); - } + result = parse(inputBuffer, inputFileLen); - writeRec.pCount = 4; - writeRec.refNum = openRec.refNum; - writeRec.dataBuffer = writeBuffer; - - inputFile = fopen(inputFileName, "r"); - if (inputFile == NULL) { - fprintf(stderr, "%s: Unable to open input file %s, %s\n", commandName, inputFileName, strerror(errno)); - exit(1); - } - - if (fseek(inputFile, 0l, SEEK_END) != 0) { - fprintf(stderr, "%s: Unable to seek to the end of file %s, %s\n", commandName, inputFileName, strerror(errno)); - fclose(inputFile); - exit(1); - } - - inputFileLen = ftell(inputFile); - if (inputFileLen < 0) { - fprintf(stderr, "%s: Unable to get size of file %s, %s\n", commandName, inputFileName, strerror(errno)); - fclose(inputFile); - exit(1); - } - - inputBuffer = malloc(inputFileLen); - if (inputBuffer == NULL) { - fprintf(stderr, "%s: Unable to allocate %ld bytes for input buffer\n", commandName, inputFileLen); - fclose(inputFile); - exit(1); - } - - if (fseek(inputFile, 0l, SEEK_SET) != 0) { - fprintf(stderr, "%s: Unable to seek to the beginning of file %s, %s\n", commandName, inputFileName, strerror(errno)); - free(inputBuffer); - fclose(inputFile); - exit(1); - } - - if (fread(inputBuffer, 1, inputFileLen, inputFile) != inputFileLen) { - fprintf(stderr, "%s: Unable to read all of file %s, %s\n", commandName, inputFileName, strerror(errno)); - free(inputBuffer); - fclose(inputFile); - exit(1); - } - - result = md_parse(inputBuffer, inputFileLen, &parser, NULL); - - if (writeBufferOffset > 0) - flushBuffer(); - closeRec.pCount = 1; - closeRec.refNum = openRec.refNum; - CloseGS(&closeRec); + closeOutputFile(); + releaseInputBuffer(inputBuffer); putchar('\n'); - fclose(inputFile); - if (debugEnabled) { fprintf(stderr, "Parser result: %d\n", result); fprintf(stderr, "Most stack used: %lu\n", ((unsigned long)&result) - ((unsigned long)lowestStackSeen)); } - return 0; + if (result != 0) + fprintf(stderr, "%s: Parser failed (%d)\n", commandName, result); + + return result; } diff --git a/md2teach/main.h b/md2teach/main.h new file mode 100644 index 0000000..585131b --- /dev/null +++ b/md2teach/main.h @@ -0,0 +1,18 @@ +// +// main.h +// md2teach +// +// Created by Jeremy Rand on 2021-04-24. +// + +#ifndef main_h +#define main_h + +#pragma memorymodel 1 + +extern char * commandName; +extern void * lowestStackSeen; +extern int debugEnabled; + + +#endif /* main_h */ diff --git a/md2teach/make/createDiskImage b/md2teach/make/createDiskImage index 4931040..4f55a7b 100755 --- a/md2teach/make/createDiskImage +++ b/md2teach/make/createDiskImage @@ -1,6 +1,5 @@ #!/bin/sh -set - if [ $# -lt 3 ] then echo USAGE: $0 diskimage bootimage file [bootdest] @@ -42,9 +41,25 @@ else CPARGS="--preserve=xattr" fi +unmount() +{ + RETRIES=0 + while [ $RETRIES -lt 5 ] + do + umount "$1" + if [ $? -eq 0 ] + then + break + fi + + RETRIES=`expr $RETRIES + 1` + sleep 1 + done +} + cleanupAndExit() { - umount "$MOUNTDIR" 2> /dev/null + unmount "$MOUNTDIR" 2> /dev/null rm -f "$TMPDISKIMAGE" 2> /dev/null rm -f "$TMPBOOTIMAGE" 2> /dev/null rm -f "$TMPARCHIVE" 2> /dev/null @@ -128,18 +143,7 @@ then cd "$OLDDIR" done - RETRIES=0 - while [ $RETRIES -lt 5 ] - do - umount "$MOUNTDIR" - if [ $? -eq 0 ] - then - break - fi - - RETRIES=`expr $RETRIES + 1` - sleep 1 - done + unmount "$MOUNTDIR" if [ $RETRIES -ge 5 ] then @@ -201,18 +205,7 @@ then fi cd "$OLDDIR" -RETRIES=0 -while [ $RETRIES -lt 5 ] -do - umount "$MOUNTDIR" - if [ $? -eq 0 ] - then - break - fi - - RETRIES=`expr $RETRIES + 1` - sleep 1 -done +unmount "$MOUNTDIR" if [ $RETRIES -ge 5 ] then diff --git a/md2teach/translate.h b/md2teach/translate.h new file mode 100644 index 0000000..52189e3 --- /dev/null +++ b/md2teach/translate.h @@ -0,0 +1,18 @@ +/* + * translate.h + * md2teach + * + * Created by Jeremy Rand on 2021-04-24. + * + */ + +#ifndef _GUARD_PROJECTmd2teach_FILEtranslate_ +#define _GUARD_PROJECTmd2teach_FILEtranslate_ + +#include "md4c.h" + + +extern int parse(const MD_CHAR* text, MD_SIZE size); + + +#endif /* define _GUARD_PROJECTmd2teach_FILEtranslate_ */