Esempio n. 1
0
/*-
 * MainParseArgs --
 *	Parse a given argument vector. Called from main() and from
 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
 *
 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	Various global and local flags will be set depending on the flags
 *	given
 */
static void
MainParseArgs(int argc, char **argv)
{
	char *p;
	int c = '?';
	int arginc;
	char *argvalue;
	const char *getopt_def;
	char *optscan;
	Boolean inOption, dashDash = FALSE;
	char found_path[MAXPATHLEN + 1];	/* for searching for sys.mk */

#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw"
/* Can't actually use getopt(3) because rescanning is not portable */

	getopt_def = OPTFLAGS;
rearg:	
	inOption = FALSE;
	optscan = NULL;
	while(argc > 1) {
		char *getopt_spec;
		if(!inOption)
			optscan = argv[1];
		c = *optscan++;
		arginc = 0;
		if(inOption) {
			if(c == '\0') {
				++argv;
				--argc;
				inOption = FALSE;
				continue;
			}
		} else {
			if (c != '-' || dashDash)
				break;
			inOption = TRUE;
			c = *optscan++;
		}
		/* '-' found at some earlier point */
		getopt_spec = strchr(getopt_def, c);
		if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
			/* -<something> found, and <something> should have an arg */
			inOption = FALSE;
			arginc = 1;
			argvalue = optscan;
			if(*argvalue == '\0') {
				if (argc < 3)
					goto noarg;
				argvalue = argv[2];
				arginc = 2;
			}
		} else {
			argvalue = NULL; 
		}
		switch(c) {
		case '\0':
			arginc = 1;
			inOption = FALSE;
			break;
		case 'B':
			compatMake = TRUE;
			Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
			Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0);
			break;
		case 'C':
			if (chdir(argvalue) == -1) {
				(void)fprintf(stderr,
					      "%s: chdir %s: %s\n",
					      progname, argvalue,
					      strerror(errno));
				exit(1);
			}
			if (getcwd(curdir, MAXPATHLEN) == NULL) {
				(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
				exit(2);
			}
			ignorePWD = TRUE;
			break;
		case 'D':
			if (argvalue == NULL || argvalue[0] == 0) goto noarg;
			Var_Set(argvalue, "1", VAR_GLOBAL, 0);
			Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'I':
			if (argvalue == NULL) goto noarg;
			Parse_AddIncludeDir(argvalue);
			Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'J':
			if (argvalue == NULL) goto noarg;
			if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
			    (void)fprintf(stderr,
				"%s: internal error -- J option malformed (%s)\n",
				progname, argvalue);
				usage();
			}
			if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
			    (fcntl(jp_1, F_GETFD, 0) < 0)) {
#if 0
			    (void)fprintf(stderr,
				"%s: ###### warning -- J descriptors were closed!\n",
				progname);
			    exit(2);
#endif
			    jp_0 = -1;
			    jp_1 = -1;
			    compatMake = TRUE;
			} else {
			    Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
			    Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			    jobServer = TRUE;
			}
			break;
		case 'N':
			noExecute = TRUE;
			noRecursiveExecute = TRUE;
			Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
			break;
		case 'S':
			keepgoing = FALSE;
			Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
			break;
		case 'T':
			if (argvalue == NULL) goto noarg;
			tracefile = bmake_strdup(argvalue);
			Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'V':
			if (argvalue == NULL) goto noarg;
			printVars = TRUE;
			(void)Lst_AtEnd(variables, argvalue);
			Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'W':
			parseWarnFatal = TRUE;
			break;
		case 'X':
			varNoExportEnv = TRUE;
			Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
			break;
		case 'd':
			if (argvalue == NULL) goto noarg;
			/* If '-d-opts' don't pass to children */
			if (argvalue[0] == '-')
			    argvalue++;
			else {
			    Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
			    Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			}
			parse_debug_options(argvalue);
			break;
		case 'e':
			checkEnvFirst = TRUE;
			Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
			break;
		case 'f':
			if (argvalue == NULL) goto noarg;
			(void)Lst_AtEnd(makefiles, argvalue);
			break;
		case 'i':
			ignoreErrors = TRUE;
			Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
			break;
		case 'j':
			if (argvalue == NULL) goto noarg;
			forceJobs = TRUE;
			maxJobs = strtol(argvalue, &p, 0);
			if (*p != '\0' || maxJobs < 1) {
				(void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
				    progname);
				exit(1);
			}
			Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0);
			maxJobTokens = maxJobs;
			break;
		case 'k':
			keepgoing = TRUE;
			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
			break;
		case 'm':
			if (argvalue == NULL) goto noarg;
			/* look for magic parent directory search string */
			if (strncmp(".../", argvalue, 4) == 0) {
				if (!Dir_FindHereOrAbove(curdir, argvalue+4,
				    found_path, sizeof(found_path)))
					break;		/* nothing doing */
				(void)Dir_AddDir(sysIncPath, found_path);
			} else {
				(void)Dir_AddDir(sysIncPath, argvalue);
			}
			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'n':
			noExecute = TRUE;
			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
			break;
		case 'q':
			queryFlag = TRUE;
			/* Kind of nonsensical, wot? */
			Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
			break;
		case 'r':
			noBuiltins = TRUE;
			Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
			break;
		case 's':
			beSilent = TRUE;
			Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
			break;
		case 't':
			touchFlag = TRUE;
			Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
			break;
		case 'w':
			enterFlag = TRUE;
			Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
			break;
		case '-':
			dashDash = TRUE;
			break;
		default:
		case '?':
#ifndef MAKE_NATIVE
			fprintf(stderr, "getopt(%s) -> %d (%c)\n",
				OPTFLAGS, c, c);
#endif
			usage();
		}
		argv += arginc;
		argc -= arginc;
	}

	oldVars = TRUE;

	/*
	 * See if the rest of the arguments are variable assignments and
	 * perform them if so. Else take them to be targets and stuff them
	 * on the end of the "create" list.
	 */
	for (; argc > 1; ++argv, --argc)
		if (Parse_IsVar(argv[1])) {
			Parse_DoVar(argv[1], VAR_CMD);
		} else {
			if (!*argv[1])
				Punt("illegal (null) argument.");
			if (*argv[1] == '-' && !dashDash)
				goto rearg;
			(void)Lst_AtEnd(create, bmake_strdup(argv[1]));
		}

	return;
noarg:
	(void)fprintf(stderr, "%s: option requires an argument -- %c\n",
	    progname, c);
	usage();
}
Esempio n. 2
0
/*-
 * MainParseArgs --
 *	Parse a given argument vector. Called from main() and from
 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
 *
 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	Various global and local flags will be set depending on the flags
 *	given
 */
static void
MainParseArgs(int argc, char **argv)
{
	char *p;
	int c;
	int arginc;
	char *argvalue;
	const char *getopt_def;
	char *optscan;
	Boolean inOption, dashDash = FALSE;
	char found_path[MAXPATHLEN + 1];	/* for searching for sys.mk */

#ifdef REMOTE
# define OPTFLAGS "BD:I:J:L:NPST:V:WXd:ef:ij:km:nqrst"
#else
# define OPTFLAGS "BD:I:J:NPST:V:WXd:ef:ij:km:nqrst"
#endif
#undef optarg
#define optarg argvalue	
/* Can't actually use getopt(3) because rescanning is not portable */

	getopt_def = OPTFLAGS;
rearg:	
	inOption = FALSE;
	optscan = NULL;
	while(argc > 1) {
		char *getopt_spec;
		if(!inOption)
			optscan = argv[1];
		c = *optscan++;
		arginc = 0;
		if(inOption) {
			if(c == '\0') {
				++argv;
				--argc;
				inOption = FALSE;
				continue;
			}
		} else {
			if (c != '-' || dashDash)
				break;
			inOption = TRUE;
			c = *optscan++;
		}
		/* '-' found at some earlier point */
		getopt_spec = strchr(getopt_def, c);
		if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
			/* -<something> found, and <something> should have an arg */
			inOption = FALSE;
			arginc = 1;
			argvalue = optscan;
			if(*argvalue == '\0') {
				if (argc < 3) {
					(void)fprintf(stderr,
					    "%s: option requires "
					    "an argument -- %c\n",
					    progname, c);
					usage();
				}
				argvalue = argv[2];
				arginc = 2;
			}
		} else {
			argvalue = NULL; 
		}
		switch(c) {
		case '\0':
			arginc = 1;
			inOption = FALSE;
			break;
		case 'B':
			compatMake = TRUE;
			Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
			break;
		case 'D':
			Var_Set(optarg, "1", VAR_GLOBAL, 0);
			Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'I':
			Parse_AddIncludeDir(optarg);
			Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'J':
			if (sscanf(optarg, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) {
			    /* backslash to avoid trigraph ??) */
			    (void)fprintf(stderr,
				"%s: internal error -- J option malformed (%s?\?)\n",
				progname, optarg);
				usage();
			}
			if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) ||
			    (fcntl(job_pipe[1], F_GETFD, 0) < 0)) {
#if 0
			    (void)fprintf(stderr,
				"%s: warning -- J descriptors were closed!\n",
				progname);
#endif
			    job_pipe[0] = -1;
			    job_pipe[1] = -1;
			    compatMake = TRUE;
			} else {
			    Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
			    Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			    jobServer = TRUE;
			}
			break;
#ifdef REMOTE
		case 'L':
			maxLocal = strtol(optarg, &p, 0);
			if (*p != '\0' || maxLocal < 1) {
			    (void)fprintf(stderr, "%s: illegal argument to -L -- must be positive integer!\n",
				progname);
			    exit(1);
			}
			Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
#endif
		case 'N':
			noExecute = TRUE;
			noRecursiveExecute = TRUE;
			Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
			break;
		case 'P':
			usePipes = FALSE;
			Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
			break;
		case 'S':
			keepgoing = FALSE;
			Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
			break;
		case 'T':
			tracefile = estrdup(optarg);
			Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'V':
			printVars = TRUE;
			(void)Lst_AtEnd(variables, (ClientData)optarg);
			Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'W':
			parseWarnFatal = TRUE;
			break;
		case 'X':
			varNoExportEnv = TRUE;
			Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
			break;
		case 'd': {
			char *modules = optarg;

			for (; *modules; ++modules)
				switch (*modules) {
				case 'A':
					debug = ~0;
					break;
				case 'a':
					debug |= DEBUG_ARCH;
					break;
				case 'c':
					debug |= DEBUG_COND;
					break;
				case 'd':
					debug |= DEBUG_DIR;
					break;
				case 'e':
					debug |= DEBUG_ERROR;
					break;
				case 'f':
					debug |= DEBUG_FOR;
					break;
				case 'g':
					if (modules[1] == '1') {
						debug |= DEBUG_GRAPH1;
						++modules;
					}
					else if (modules[1] == '2') {
						debug |= DEBUG_GRAPH2;
						++modules;
					}
					else if (modules[1] == '3') {
						debug |= DEBUG_GRAPH3;
						++modules;
					}
					break;
				case 'j':
					debug |= DEBUG_JOB;
					break;
				case 'm':
					debug |= DEBUG_MAKE;
					break;
				case 'n':
					debug |= DEBUG_SCRIPT;
					break;
				case 's':
					debug |= DEBUG_SUFF;
					break;
				case 't':
					debug |= DEBUG_TARG;
					break;
				case 'v':
					debug |= DEBUG_VAR;
					break;
				case 'x':
					debug |= DEBUG_SHELL;
					break;
				default:
					(void)fprintf(stderr,
				"%s: illegal argument to d option -- %c\n",
					    progname, *modules);
					usage();
				}
			Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		}
		case 'e':
			checkEnvFirst = TRUE;
			Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
			break;
		case 'f':
			(void)Lst_AtEnd(makefiles, (ClientData)optarg);
			break;
		case 'i':
			ignoreErrors = TRUE;
			Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
			break;
		case 'j':
			forceJobs = TRUE;
			maxJobs = strtol(optarg, &p, 0);
			if (*p != '\0' || maxJobs < 1) {
				(void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
				    progname);
				exit(1);
			}
#ifndef REMOTE
			maxLocal = maxJobs;
#endif
			Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'k':
			keepgoing = TRUE;
			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
			break;
		case 'm':
			/* look for magic parent directory search string */
			if (strncmp(".../", optarg, 4) == 0) {
				if (!Dir_FindHereOrAbove(curdir, optarg+4,
				    found_path, sizeof(found_path)))
					break;		/* nothing doing */
				(void)Dir_AddDir(sysIncPath, found_path);
				
			} else {
				(void)Dir_AddDir(sysIncPath, optarg);
			}
			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'n':
			noExecute = TRUE;
			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
			break;
		case 'q':
			queryFlag = TRUE;
			/* Kind of nonsensical, wot? */
			Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
			break;
		case 'r':
			noBuiltins = TRUE;
			Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
			break;
		case 's':
			beSilent = TRUE;
			Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
			break;
		case 't':
			touchFlag = TRUE;
			Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
			break;
		case '-':
			dashDash = TRUE;
			break;
		default:
		case '?':
#ifndef MAKE_NATIVE
			fprintf(stderr, "getopt(%s) -> %d (%c)\n",
				OPTFLAGS, c, c);
#endif
			usage();
		}
		argv += arginc;
		argc -= arginc;
	}

	oldVars = TRUE;

	/*
	 * See if the rest of the arguments are variable assignments and
	 * perform them if so. Else take them to be targets and stuff them
	 * on the end of the "create" list.
	 */
	for (; argc > 1; ++argv, --argc)
		if (Parse_IsVar(argv[1])) {
			Parse_DoVar(argv[1], VAR_CMD);
		} else {
			if (!*argv[1])
				Punt("illegal (null) argument.");
			if (*argv[1] == '-' && !dashDash)
				goto rearg;
			(void)Lst_AtEnd(create, (ClientData)estrdup(argv[1]));
		}
}