make/main.c getopt() fix

Max Okumoto okumoto at ucsd.edu
Thu Apr 7 00:46:50 PDT 2005


Hi Harti,

Matt has layed down a release tag so I can begin work again :-)
This patch fixes how make uses getopt().  Make should set optreset
to one before it calls getopt() with a new set of args.
				Max

# main.c
#       o Removed unnessisary forward declaration for MainParseArgs()
#
#       o Use optreset global variable to inform getopt() that we are
#         parsing another arg list.
#
#       o Cleanup handling of remaining arguments after getopt()
#         completes parsing arguments.  There is no reason to restart
#         getopt() for single dash case, just ignore it.  And update
#         comment to reflect code.
#
#       o Removed missleading comments.
diff -ru  fbsd-src/make/main.c dfly-src/make/main.c
--- fbsd-src/make/main.c	Wed Apr  6 02:52:28 2005
+++ dfly-src/make/main.c	Wed Apr  6 14:28:25 2005
@@ -126,7 +126,6 @@
 
 Boolean		jobsRunning;	/* TRUE if the jobs might be running */
 
-static void	MainParseArgs(int, char **);
 char		*chdir_verify_path(const char *, char *);
 static int	ReadMakefile(const char *);
 static void	usage(void);
@@ -174,9 +173,11 @@
 {
 	int c;
 
+rearg:
 	optind = 1;	/* since we're called more than once */
+	optreset = 1;
 #define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstv"
-rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
+	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
 		switch(c) {
 
 		case 'A':
@@ -337,34 +338,54 @@
 			usage();
 		}
 	}
+	argv += optind;
+	argc -= optind;
 
 	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.
+	 * Parse the rest of the arguments.
+	 *	o Check for variable assignments and perform them if so.
+	 *	o Check for more flags and restart getopt if so.
+	 *      o Anything else is taken to be a target and added
+	 *	  to the end of the "create" list.
 	 */
-	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
+	for (; *argv != NULL; ++argv, --argc) {
 		if (Parse_IsVar(*argv)) {
 			char *ptr = MAKEFLAGS_quote(*argv);
 
 			Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
+			Parse_DoVar(*argv, VAR_CMD);
 			free(ptr);
 
-			Parse_DoVar(*argv, VAR_CMD);
-		} else {
-			if (!**argv)
-				Punt("illegal (null) argument.");
-			if (**argv == '-') {
-				if ((*argv)[1])
-					optind = 0;     /* -flag... */
-				else
-					optind = 1;     /* - */
+		} else if ((*argv)[0] == '-') {
+			if ((*argv)[1] == '\0') {
+				/*
+				 * (*argv) is a single dash, so we
+				 * just ignore it.
+				 */
+			} else {
+				/*
+				 * (*argv) is a -flag, so backup argv
+				 *  and argc, since getopt() expects
+				 * options to start in the 2nd position.
+				 */
+				argc++;
+				argv--;
 				goto rearg;
 			}
+
+		} else if ((*argv)[0] == '\0') {
+			/*
+			 * XXX Is this check nessisary, who could pass
+			 * XXX an empty string as an argument?
+			 */
+			Punt("illegal (null) argument.");
+
+		} else {
 			Lst_AtEnd(&create, estrdup(*argv));
 		}
+	}
 }
 
 /**
@@ -609,9 +630,8 @@
 #endif
 
 	/*
-	 * First snag any flags out of the MAKE environment variable.
-	 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
-	 * in a different format).
+	 * First snag things out of the MAKEFLAGS environment
+	 * variable.  Then parse the command line arguments.
 	 */
 	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
 
@@ -619,8 +639,6 @@
 
 	/*
 	 * Find where we are...
-	 * All this code is so that we know where we are when we start up
-	 * on a different machine with pmake.
 	 */
 	curdir = cdpath;
 	if (getcwd(curdir, MAXPATHLEN) == NULL)




More information about the Commits mailing list