void appendPseudoTargetList( STRINGLIST **pseudo, STRINGLIST *list ) { STRINGLIST *p, *q, *r; char *t, *u; while ((p = list)) { if (!_tcschr(p->text, '$')) { list = list->next; p->next = NULL; appendItem(pseudo, p); } else { r = macros; t = expandMacros(p->text, ¯os); while (r != macros) { q = r->next; FREE_STRINGLIST(r); r = q; } for (u = _tcstok(t, " \t"); u; u = _tcstok(NULL, " \t")) { q = makeNewStrListElement(); q->text = makeString(u); appendItem(pseudo, q); } FREE(t); FREE(p->text); list = list->next; FREE_STRINGLIST(p); } } }
void addItemToList() { STRINGLIST *p; // from lexer STRINGLIST *NewList; if (name) { SET(actionFlags, A_TARGET); startNameList(); name = NULL; } if (ON(actionFlags, A_TARGET)) { if (isRule(buf)) { if (ON(actionFlags, A_RULE)) makeError(currentLine, TOO_MANY_RULE_NAMES); makeError(currentLine, MIXED_RULES); } } p = makeNewStrListElement(); if (ON(actionFlags, A_STRING)) { // we collect macros p->text = string; // for dependents & string = NULL; // build lines for } else // non-implicit rules p->text = makeString(buf); NewList = p; // build lines for if (OFF(actionFlags, A_RULE) // rules get expanded || ON(actionFlags, A_TARGET)) // after entire make- { findMacroValues(p->text, ¯os, NULL, NULL, 0, 0, 0); // file parsed } if (ON(actionFlags, A_TARGET)) { p = macros; expandFileNames("$", &NewList, ¯os); expandFileNames("*?", &NewList, NULL); while ((macros = p)) { p = p->next; FREE_STRINGLIST(macros); } } appendItem(&list, NewList); }
void startNameList() { STRINGLIST *p; currentFlags = flags; // set flags for cur target p = makeNewStrListElement(); p->text = name; list = p; // list contains name p = macros; expandFileNames("$", &list, ¯os); // expand macros in name expandFileNames("*?", &list, NULL); // expand wildcards while ((macros = p)) { // free macro list p = p->next; FREE_STRINGLIST(macros); } if (!list && OFF(actionFlags, A_TARGET)) makeError(line, TARGET_MACRO_IS_NULL, name); // target null & 1 target if (list && isRule(list->text)) SET(actionFlags, A_RULE); }
void __cdecl main( unsigned argc, char *argv[], char *envp[]) /* environment variables */ { extern unsigned saveBytes; extern char **envPtr; int status; /* returned by doMake */ extern char *makeStr; #ifdef OS2_SIGNALS PUSHORT prev; unsigned long _FAR *pfnsig; #endif InitializeEnv(); #if defined(FLAT) fRunningUnderTNT = FIsTNT(); #endif initCharmap(); initMacroTable(macroTable); #ifdef DEBUG_MEMORY //This puts 0xff in all free entries in the heap _heapset(0xff); #endif envPtr = envp; #ifdef DEBUG_COMMANDLINE { int iArg = argc; char **chchArg = argv; for (; iArg--; chchArg++) printf("'%s' ", *chchArg); printf("\n"); } #endif #ifdef TEST_RUNTIME //Tests RunTime error R6001 {char near *foo = NULL; *foo = '1';} #endif #ifdef DOS startupDir = getCurDir(); #endif #ifdef FLAT resultbuf_size = sizeof(struct _finddata_t); #ifdef NT ext_size = CCHMAXPATHCOMP; filename_size = CCHMAXPATHCOMP; filenameext_size = CCHMAXPATH; #endif #else /* If OS/2 1.2 and beyond then allowed max sizes vary */ if (_osmajor < 10 || _osmode == DOS_MODE) resultbuf_size = sizeof(struct find_t); else if (_osminor < 20) resultbuf_size = sizeof(struct FileFindBuf); else { ext_size = CCHMAXPATHCOMP; filename_size = CCHMAXPATHCOMP; filenameext_size = CCHMAXPATH; resultbuf_size = sizeof(struct _FILEFINDBUF); } #endif if (!makeStr) /* extract file name */ if (!filename(_ftcscpy(fileStr, _pgmptr), &makeStr)) makeStr = "NMAKE"; // Initialize the message file SetErrorFile("nmake.err", _pgmptr, 1); // 1=Search Exe Path #if defined(SELF_RECURSE) initSavPtr = (char *)allocate(saveBytes = (&endOfSave - &startOfSave)); memmove(initSavPtr, &startOfSave, saveBytes); #endif /* set up handler for .PRECIOUS the handler tries to remove the * current target when control-C'd, unless it is "precious" */ #ifdef OS2_SIGNALS This commented out part was trial for using OS/2 function calls It still has some problems DOSSETSIGHANDLER(chkPrecious, pfnsig, prev, SIGA_ACCEPT, SIG_CTRLC); if (_osmode == OS2_MODE) { DOSSETSIGHANDLER(chkPrecious, NULL, NULL, SIGA_ACCEPT, SIG_CTRLBREAK); DOSSETSIGHANDLER(chkPrecious, NULL, NULL, SIGA_ACCEPT, SIG_KILLPROCESS); } #endif signal(SIGINT, chkPrecious); signal(SIGTERM, chkPrecious); makeIdeMessage(0, 0); status = doMake(argc, argv, NULL); #ifndef NO_OPTION_Z /* If -Z is specified then NMAKE needs to have errorLevel check in the * batch file. So add the goto label for exit and print the Reverse batch * file */ if (ON(gFlags, F1_REVERSE_BATCH_FILE)) { STRINGLIST *revCmd; //Adds ':NMAKEEXIT' to jump to end when error occurs revCmd = makeNewStrListElement(); revCmd->text = nmakeExitLabelCmd; prependItem(&revList, revCmd); //'=c' means echo at current line revCmd = makeNewStrListElement(); revCmd->text = makeString("=c"); appendItem(&revList, revCmd); //'=d' turns echoing on (unless preceeded by @) revCmd = makeNewStrListElement(); revCmd->text = makeString("=d"); appendItem(&revList, revCmd); } #endif delScriptFiles(); #ifndef NO_OPTION_Z if (ON(gFlags, F1_REVERSE_BATCH_FILE)) printReverseFile(); #endif #ifdef MEMORY_DEBUG mem_status(); #endif #ifdef HEAP_DIAGNOSTICS printHeapDiagnostics(); #endif #ifdef NMK_DEBUG fprintf(stderr, "Exiting...\n"); #endif if (!fSlashKStatus) //error when slashK specified status = 1; #if !defined(NDEBUG) && !defined(NT_BUILD) printStats(); #endif exit(status); }
BOOL putMacro( char *name, char *value, UCHAR flags ) { MACRODEF *p; STRINGLIST *q; BOOL defined = FALSE; BOOL fSyntax = TRUE; // Convert path separators to the native path separator. // Do that with a copy of the original string so we don't change // the original. value = makeString(value); #if PLATFORM_UNIX char *tmp = value; while ((tmp = FindFirstPathSeparator(tmp))) { *tmp++ = PATH_SEPARATOR_CHAR; } #endif // PLATFORM_UNIX // Inherit macro definitions. Call removeMacros() to expand sub-macro // definitions. Must be done before macro is put in table, else // recursive definitions won't work. if (ON(flags, M_NON_RESETTABLE)) { if (*value) if ((putEnvStr(name,removeMacros(value)) == -1)) makeError(currentLine, OUT_OF_ENV_SPACE); } else if (fInheritUserEnv && OFF(gFlags, F1_USE_ENVIRON_VARS) && getenv(name) ) { if ((p = findMacro(name))) { // don't let user if (CANT_REDEFINE(p)) // redefine cmdline return(FALSE); // macros, MAKE, etc. } if ((putEnvStr(name,removeMacros(value)) == -1)) makeError(currentLine, OUT_OF_ENV_SPACE); } fInheritUserEnv = (BOOL)FALSE; if ((p = findMacro(name))) { // don't let user if (CANT_REDEFINE(p)) // redefine cmdline return(FALSE); // macros, MAKE, etc. } q = makeNewStrListElement(); q->text = value; if (!p) { p = makeNewMacro(); p->name = name; assert(p->flags == 0); assert(p->values == NULL); } else defined = TRUE; p->flags &= ~M_UNDEFINED; // Is no longer undefined p->flags |= flags; // Set flags to union of old and new prependItem((STRINGLIST**)&(p->values), (STRINGLIST*)q); if (!defined) insertMacro((STRINGLIST*)p); if (OFF(flags, M_LITERAL) && _tcschr(value, '$')) { // Check for cyclic Macro Definitions SET(p->flags, M_EXPANDING_THIS_ONE); // NULL -> don't build list fSyntax = findMacroValues(value, NULL, NULL, name, 1, 0, flags); CLEAR(p->flags, M_EXPANDING_THIS_ONE); } if (!fSyntax) { p->values = NULL; p->flags |= M_UNDEFINED; //return(FALSE); // return TRUE since p has been added to the macro table // Otherwise the caller may free name and value leaving // dangling pointers in the macro table. return(TRUE); } return(TRUE); }
void expandFileNames( char *string, STRINGLIST **sourceList, STRINGLIST **macroList ) { char *s, *t = NULL; STRINGLIST *p; // Main list pointer STRINGLIST *pNew, // Pointer to new list *pBack; // Pointer to one element back char *saveText = NULL; for (pBack = NULL, p = *sourceList; p;) { // If no expand-character is found, continue to next list element. if (!_tcspbrk(p->text, string)) { pBack = p; p = pBack->next; continue; } // Either expand macros or wildcards. if (*string == '$') { t = expandMacros(p->text, macroList); FREE(p->text); } else { // If the wildcard string does not expand to anything, go to // next list elment. Do not remove p from the original list // else we must check for null elsewhere. // -- do not attempt to expand wildcards that // occur in inference rules if (isRule(p->text) || (pNew = expandWildCards(p->text)) == NULL) { pBack = p; p = pBack->next; continue; } saveText = p->text; } // At this point we have a list of expanded names to replace p with. if (pBack) { pBack->next = p->next; FREE_STRINGLIST(p); p = pBack->next; } else { *sourceList = p->next; FREE_STRINGLIST(p); p = *sourceList; } if (*string == '$') { // if expanding macros char *str = t; if ((s = nextComponent(&str))) { do { // put expanded names pNew = makeNewStrListElement(); // at front of list pNew->text = makeString(s); // so we won't try to prependItem(sourceList, pNew); // re-expand them if (!pBack) pBack = pNew; } while ((s = nextComponent(&str))); } FREE(t); continue; } else if (pNew) { // if matches for * ? if (!pBack) for (pBack = pNew; pBack->next; pBack = pBack->next) ; appendItem(&pNew, *sourceList); // put at front of old list *sourceList = pNew; } FREE(saveText); } }