void makeTarget( char *s, BOOL firstTarg, BUILDBLOCK **block ) { BUILDLIST *build; MAKEOBJECT *object; if (!*block) *block = makeNewBuildBlock(); if (firstTarg) { build = makeNewBldListElement(); build->buildBlock = *block; } else build = makeBuildList(*block); if ((object = findTarget(s))) { if (ON(object->flags2, F2_DOUBLECOLON) != ON(currentFlags, F2_DOUBLECOLON)) makeError(currentLine, MIXED_SEPARATORS); appendItem((STRINGLIST**)&(object->buildList), (STRINGLIST*)build); FREE(s); } else { build->next = NULL; object = makeNewObject(); object->name = s; object->buildList = build; object->flags2 = currentFlags; prependItem((STRINGLIST**)targetTable+hash(s, MAXTARGET, (BOOL)TRUE), (STRINGLIST*)object); } }
void makeRule( STRINGLIST *rule, BOOL fBatch ) { RULELIST *rList; rList = makeNewRule(); rList->name = rule->text; #if PLATFORM_UNIX // Convert path separators to the native path separator. char *tmp = rList->name; while ((tmp = FindFirstPathSeparator(tmp))) { *tmp++ = PATH_SEPARATOR_CHAR; } #endif // PLATFORM_UNIX rList->fBatch = fBatch; prependItem((STRINGLIST**)&rules, (STRINGLIST*)rList); if (rList->next) rList->next->back = rList; }
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); } }