void PPError (const char* Format, ...) /* Print an error message. For use within the preprocessor. */ { va_list ap; va_start (ap, Format); IntError (GetCurrentFile(), GetCurrentLine(), Format, ap); va_end (ap); }
void Error (const char* Format, ...) /* Print an error message */ { va_list ap; va_start (ap, Format); IntError (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap); va_end (ap); }
void LIError (const LineInfo* LI, const char* Format, ...) /* Print an error message with the line info given explicitly */ { va_list ap; va_start (ap, Format); IntError (GetInputName (LI), GetInputLine (LI), Format, ap); va_end (ap); }
/*** RemoveFile - free up all resources attached to a particular file * * Purpose: * * To free all memory used to keep track of a file. If the file still * appears in some instance lists, it is removed from them. * * Input: * * pFileRem - File in question * * Output: * * Returns TRUE. * * Exceptions: * * Notes: * *************************************************************************/ void RemoveFile ( PFILE pFileRem ) { PFILE pFilePrev = (PFILE) &pFileHead; PFILE pFileTmp = pFileHead; if (pFileRem->refCount > 0) { RemoveInstances (pFileRem); } while (pFileTmp != pFileRem) { pFilePrev = pFileTmp; pFileTmp = pFileTmp->pFileNext; if (pFileTmp == NULL) { IntError ("RemoveFile can't find file"); } } /* * It's important that pFileNext be the first field in a pfile, and we assert * that here. This allows us to not special case pFileHead, but adjust it by * treating it as the pFileNext of a non-existant structure. */ assert ((void *)&(pFilePrev->pFileNext) == (void *)pFilePrev); pFilePrev->pFileNext = pFileTmp->pFileNext; FreeFileVM (pFileTmp); FREE (pFileTmp->pName); #if DEBUG pFileTmp->id = 0; #endif FREE ((char *) pFileTmp); if (pFileTmp == pFileIni) { pFileIni = NULL; } }
/* mGetCmd returns the next command from the current macro, popping state * * The command-reader code (cmd) calls mGetCmd when a macro is in progress. * We are expected to return either a pointer to the function (cmdDesc) for * the next function to execute or NULL if there the current macro is finished. * We will adjust the state of the interpreter when a macro finishes. Any * errors detected result in ALL macros being terminated. * * For infinite looping inside a macro, we will look for ^C too. * * returns NULL if current macro finishes * pointer to function descriptor for next function to execute */ PCMD mGetCmd ( void ) { buffer mname; PCMD pFunc; struct macroInstanceType *pmi; if (cMacUse == 0) { IntError ("mGetCmd called with no macros in effect"); } pmi = &mi[cMacUse-1]; while ( pmi->text && *pmi->text != '\0') { // Use heuristic to see if infinite loop // if (fCtrlc) { goto mGetCmdAbort; } if (TESTFLAG (fParseMacro (pmi, mname), GRAPH)) { pFunc = &cmdGraphic; pFunc->arg = mname[0]; return pFunc; } /* * if end of macro, exit */ if (!mname[0]) { break; } _strlwr (mname); pFunc = NameToFunc (mname); // found an editor function / macro // if (pFunc != NULL) { return pFunc; } if (mname[1] != '>' || (mname[0] != '=' && mname[0] != ':' && mname[0] != '+' && mname[0] != '-')) { printerror ("unknown function %s", mname); goto mGetCmdAbort; } /* see if goto is to be taken */ if (mname[0] == '=' || (fRetVal && mname[0] == '+') || (!fRetVal && mname[0] == '-')) { /* if exit from current macro, then exit scanning loop */ if (mname[2] == '\0') { break; } /* find label */ if (!fFindLabel (pmi, mname)) { printerror ("Cannot find label %s", mname+2); mGetCmdAbort: resetarg (); DoCancel (); mPopToTop (); break; } } } /* we have exhausted the current macro. If it was entered via EXEC * we must signal TopLoop that the party's over */ fBreak = (flagType)(TESTFLAG (mi[cMacUse-1].flags, EXEC)); if ( cMacUse > 0 ) { cMacUse--; } return NULL; }