⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	    free(res);	}	if (freeCmd) {	    free(args[2]);	}    } else {	/*	 * Normal assignment -- just do it.	 */	Var_Set (line, cp, ctxt);    }}/*- * ParseAddCmd  -- *	Lst_ForEach function to add a command line to all targets * * Results: *	Always 0 * * Side Effects: *	A new element is added to the commands list of the node. */static intParseAddCmd(gn, cmd)	GNode *gn;	/* the node to which the command is to be added */	char *cmd;	/* the command to add */{	/* if target already supplied, ignore commands */	if (!(gn->type & OP_HAS_COMMANDS))		(void)Lst_AtEnd(gn->commands, (ClientData)cmd);	return(0);}/*- *----------------------------------------------------------------------- * ParseHasCommands -- *	Callback procedure for Parse_File when destroying the list of *	targets on the last dependency line. Marks a target as already *	having commands if it does, to keep from having shell commands *	on multiple dependency lines. * * Results: *	Always 0. * * Side Effects: *	OP_HAS_COMMANDS may be set for the target. * *----------------------------------------------------------------------- */static intParseHasCommands(gn)    GNode   	  *gn;	    /* Node to examine */{    if (!Lst_IsEmpty(gn->commands)) {	gn->type |= OP_HAS_COMMANDS;    }    return(0);}/*- *----------------------------------------------------------------------- * Parse_AddIncludeDir -- *	Add a directory to the path searched for included makefiles *	bracketed by double-quotes. Used by functions in main.c * * Results: *	None. * * Side Effects: *	The directory is appended to the list. * *----------------------------------------------------------------------- */voidParse_AddIncludeDir (dir)    char    	  *dir;	    /* The name of the directory to add */{    Dir_AddDir (parseIncPath, dir);}/*- *--------------------------------------------------------------------- * ParseDoInclude  -- *	Push to another file. *	 *	The input is the line minus the #include. A file spec is a string *	enclosed in <> or "". The former is looked for only in sysIncPath. *	The latter in . and the directories specified by -I command line *	options * * Results: *	None * * Side Effects: *	A structure is added to the includes Lst and readProc, lineno, *	fname and curFILE are altered for the new file *--------------------------------------------------------------------- */static voidParseDoInclude (file)    char          *file;	/* file specification */{    char          *fullname;	/* full pathname of file */    IFile         *oldFile;	/* state associated with current file */    char          endc;	    	/* the character which ends the file spec */    char          *cp;		/* current position in file spec */    Boolean 	  isSystem; 	/* TRUE if makefile is a system makefile */    /*     * Skip to delimiter character so we know where to look     */    while ((*file == ' ') || (*file == '\t')) {	file++;    }    if ((*file != '"') && (*file != '<')) {	Parse_Error (PARSE_FATAL,	    ".include filename must be delimited by '\"' or '<'");	return;    }    /*     * Set the search path on which to find the include file based on the     * characters which bracket its name. Angle-brackets imply it's     * a system Makefile while double-quotes imply it's a user makefile     */    if (*file == '<') {	isSystem = TRUE;	endc = '>';    } else {	isSystem = FALSE;	endc = '"';    }    /*     * Skip to matching delimiter     */    for (cp = ++file; *cp && *cp != endc; cp++) {	continue;    }    if (*cp != endc) {	Parse_Error (PARSE_FATAL,		     "Unclosed %cinclude filename. '%c' expected",		     '.', endc);	return;    }    *cp = '\0';    /*     * Substitute for any variables in the file name before trying to     * find the thing.     */    file = Var_Subst (NULL, file, VAR_CMD, FALSE);    /*     * Now we know the file's name and its search path, we attempt to     * find the durn thing. A return of NULL indicates the file don't     * exist.     */    if (!isSystem) {	/*	 * Include files contained in double-quotes are first searched for	 * relative to the including file's location. We don't want to	 * cd there, of course, so we just tack on the old file's	 * leading path components and call Dir_FindFile to see if	 * we can locate the beast.	 */	char	  *prefEnd;	prefEnd = strrchr (fname, '/');	if (prefEnd != (char *)NULL) {	    char  	*newName;	    	    *prefEnd = '\0';	    newName = str_concat (fname, file, STR_ADDSLASH);	    fullname = Dir_FindFile (newName, parseIncPath);	    if (fullname == (char *)NULL) {		fullname = Dir_FindFile(newName, dirSearchPath);	    }	    free (newName);	    *prefEnd = '/';	} else {	    fullname = (char *)NULL;	}    } else {	fullname = (char *)NULL;    }    if (fullname == (char *)NULL) {	/*	 * System makefile or makefile wasn't found in same directory as	 * included makefile. Search for it first on the -I search path,	 * then on the .PATH search path, if not found in a -I directory.	 * XXX: Suffix specific?	 */	fullname = Dir_FindFile (file, parseIncPath);	if (fullname == (char *)NULL) {	    fullname = Dir_FindFile(file, dirSearchPath);	}    }    if (fullname == (char *)NULL) {	/*	 * Still haven't found the makefile. Look for it on the system	 * path as a last resort.	 */	fullname = Dir_FindFile(file, sysIncPath);    }    if (fullname == (char *) NULL) {	*cp = endc;	Parse_Error (PARSE_FATAL, "Could not find %s", file);	return;    }    /*     * Once we find the absolute path to the file, we get to save all the     * state from the current file before we can start reading this     * include file. The state is stored in an IFile structure which     * is placed on a list with other IFile structures. The list makes     * a very nice stack to track how we got here...     */    oldFile = (IFile *) emalloc (sizeof (IFile));    oldFile->fname = fname;    oldFile->F = curFILE;    oldFile->p = curPTR;    oldFile->lineno = lineno;    (void) Lst_AtFront (includes, (ClientData)oldFile);    /*     * Once the previous state has been saved, we can get down to reading     * the new file. We set up the name of the file to be the absolute     * name of the include file so error messages refer to the right     * place. Naturally enough, we start reading at line number 0.     */    fname = fullname;    lineno = 0;    curFILE = fopen (fullname, "r");    curPTR = NULL;    if (curFILE == (FILE * ) NULL) {	Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);	/*	 * Pop to previous file	 */	(void) ParseEOF(0);    }}/*- *--------------------------------------------------------------------- * Parse_FromString  -- *	Start Parsing from the given string *	 * Results: *	None * * Side Effects: *	A structure is added to the includes Lst and readProc, lineno, *	fname and curFILE are altered for the new file *--------------------------------------------------------------------- */voidParse_FromString(str)    char *str;{    IFile         *oldFile;	/* state associated with this file */    if (DEBUG(FOR))	(void) fprintf(stderr, "%s\n----\n", str);    oldFile = (IFile *) emalloc (sizeof (IFile));    oldFile->lineno = lineno;    oldFile->fname = fname;    oldFile->F = curFILE;    oldFile->p = curPTR;        (void) Lst_AtFront (includes, (ClientData)oldFile);    curFILE = NULL;    curPTR = (PTR *) emalloc (sizeof (PTR));    curPTR->str = curPTR->ptr = str;    lineno = 0;    fname = strdup(fname);}#ifdef SYSVINCLUDE/*- *--------------------------------------------------------------------- * ParseTraditionalInclude  -- *	Push to another file. *	 *	The input is the line minus the "include".  The file name is *	the string following the "include". * * Results: *	None * * Side Effects: *	A structure is added to the includes Lst and readProc, lineno, *	fname and curFILE are altered for the new file *--------------------------------------------------------------------- */static voidParseTraditionalInclude (file)    char          *file;	/* file specification */{    char          *fullname;	/* full pathname of file */    IFile         *oldFile;	/* state associated with current file */    char          *cp;		/* current position in file spec */    char	  *prefEnd;    /*     * Skip over whitespace     */    while ((*file == ' ') || (*file == '\t')) {	file++;    }    if (*file == '\0') {	Parse_Error (PARSE_FATAL,		     "Filename missing from \"include\"");	return;    }    /*     * Skip to end of line or next whitespace     */    for (cp = file; *cp && *cp != '\n' && *cp != '\t' && *cp != ' '; cp++) {	continue;    }    *cp = '\0';    /*     * Substitute for any variables in the file name before trying to     * find the thing.     */    file = Var_Subst (NULL, file, VAR_CMD, FALSE);    /*     * Now we know the file's name, we attempt to find the durn thing.     * A return of NULL indicates the file don't exist.     *     * Include files are first searched for relative to the including     * file's location. We don't want to cd there, of course, so we     * just tack on the old file's leading path components and call     * Dir_FindFile to see if we can locate the beast.     * XXX - this *does* search in the current directory, right?     */    prefEnd = strrchr (fname, '/');    if (prefEnd != (char *)NULL) {	char  	*newName;	    	*prefEnd = '\0';	newName = str_concat (fname, file, STR_ADDSLASH);	fullname = Dir_FindFile (newName, parseIncPath);	if (fullname == (char *)NULL) {	    fullname = Dir_FindFile(newName, dirSearchPath);	}	free (newName);	*prefEnd = '/';    } else {	fullname = (char *)NULL;    }    if (fullname == (char *)NULL) {	/*	 * System makefile or makefile wasn't found in same directory as	 * included makefile. Search for it first on the -I search path,	 * then on the .PATH search path, if not found in a -I directory.	 * XXX: Suffix specific?	 */	fullname = Dir_FindFile (file, parseIncPath);	if (fullname == (char *)NULL) {	    fullname = Dir_FindFile(file, dirSearchPath);	}    }    if (fullname == (char *)NULL) {	/*	 * Still haven't found the makefile. Look for it on the system	 * path as a last resort.	 */	fullname = Dir_FindFile(file, sysIncPath);    }    if (fullname == (char *) NULL) {	Parse_Error (PARSE_FATAL, "Could not find %s", file);	return;    }    /*     * Once we find the absolute path to the file, we get to save all the     * state from the current file before we can start reading this     * include file. The state is stored in an IFile structure which     * is placed on a list with other IFile structures. The list makes     * a very nice stack to track how we got here...     */    oldFile = (IFile *) emalloc (sizeof (IFile));    oldFile->fname = fname;    oldFile->F = curFILE;    oldFile->p = curPTR;    oldFile->lineno = lineno;    (void) Lst_AtFront (includes, (ClientData)oldFile);    /*     * Once the previous state has been saved, we can get down to reading     * the new file. We set up the name of the file to be the absolute     * name of the include file so error messages refer to the right     * place. Naturally enough, we start reading at line number 0.     */    fname = fullname;    lineno = 0;    curFILE = fopen (fullname, "r");    curPTR = NULL;    if (curFILE == (FILE * ) NULL) {	Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);	/*	 * Pop to previous file	 */	(void) ParseEOF(1);    }}#endif/*- *--------------------------------------------------------------------- * ParseEOF  -- *	Called when EOF is reached in the current file. If we were reading *	an include file, the includes stack is popped and things set up *	to go back to reading the previous file at the previous location. * * Results: *	CONTINUE if there's more to do. DONE if not. * * Side Effects: *	The old curFILE, is closed. The includes list is shortened. *	lineno, curFILE, and fname are changed if CONTINUE is returned. *--------------------------------------------------------------------- */static intParseEOF (opened)    int opened;{    IFile     *ifile;	/* the state on the top of the includes stack */    if (Lst_IsEmpty (includes)) {	return (DONE);    }    ifile = (IFile *) Lst_DeQueue (includes);    free ((Address) fname);    fname = ifile->fname;    lineno = ifile->lineno;    if (opened && curFILE)	(void) fclose (curFILE);    if (curPTR) {	free((Address) curPTR->str);	free((Address) curPTR);    }    curFILE = ifile->F;    curPTR = ifile->p;    free ((Address)ifile);    return (CONTINUE);}/*- *--------------------------------------------------------------------- * ParseReadc  -- *	Read a character from the current file  * * Results: *	The character that was read *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -