shithub: choc

Download patch

ref: 0fceea019eb22150b79dfe789c0b0dd2192bb7a3
parent: fa32d12bfa647565cce1b2f9e25ad7d7b0a1d4fc
author: Simon Howard <[email protected]>
date: Thu Jun 29 05:05:54 EDT 2006

Hugely refactor the response file loading code. Allow arguments to be
enclosed in quotes; this allows long filenames with spaces in to be
specified with -file in response files.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 563

--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: d_main.c 531 2006-05-25 22:39:57Z fraggle $
+// $Id: d_main.c 563 2006-06-29 09:05:54Z fraggle $
 //
 // Copyright(C) 1993-1996 Id Software, Inc.
 // Copyright(C) 2005 Simon Howard
@@ -184,7 +184,7 @@
 //-----------------------------------------------------------------------------
 
 
-static const char rcsid[] = "$Id: d_main.c 531 2006-05-25 22:39:57Z fraggle $";
+static const char rcsid[] = "$Id: d_main.c 563 2006-06-29 09:05:54Z fraggle $";
 
 #define	BGCOLOR		7
 #define	FGCOLOR		8
@@ -1083,6 +1083,149 @@
     }
 }
 
+#define MAXARGVS        100
+	
+static void LoadResponseFile(int argv_index)
+{
+    FILE *handle;
+    int size;
+    char *infile;
+    char *file;
+    char *response_filename;
+    char **newargv;
+    int newargc;
+    int i, k;
+
+    response_filename = myargv[argv_index] + 1;
+		
+    // READ THE RESPONSE FILE INTO MEMORY
+    handle = fopen(response_filename, "r");
+
+    if (handle == NULL)
+    {
+        printf ("\nNo such response file!");
+        exit(1);
+    }
+
+    printf("Found response file %s!\n", response_filename);
+
+    // Find size of file
+
+    fseek(handle, 0, SEEK_END);
+    size = ftell(handle);
+    fseek(handle, 0, SEEK_SET);
+
+    // Read in the entire file
+    // Allocate one byte extra - this is incase there is an argument
+    // at the end of the response file, in which case a '\0' will be 
+    // needed.
+
+    file = malloc(size + 1);
+    fread(file, size, 1, handle);
+    fclose(handle);
+
+    // Create new arguments list array
+
+    newargv = malloc(sizeof(char *) * MAXARGVS);
+    newargc = 0;
+    memset(newargv, 0, sizeof(char *) * MAXARGVS);
+
+    // Copy all the arguments in the list up to the response file
+
+    for (i=0; i<argv_index; ++i)
+    {
+        newargv[i] = myargv[i];
+        ++newargc;
+    }
+    
+    infile = file;
+    k = 0;
+
+    while(k < size)
+    {
+        // Skip past space characters to the next argument
+
+        while(k < size && isspace(infile[k]))
+        {
+            ++k;
+        } 
+
+        if (k >= size)
+        {
+            break;
+        }
+
+        // If the next argument is enclosed in quote marks, treat
+        // the contents as a single argument.  This allows long filenames
+        // to be specified.
+
+        if (infile[k] == '\"') 
+        {
+            // Skip the first character(")
+            ++k;
+
+            newargv[newargc++] = &infile[k];
+
+            // Read all characters between quotes
+
+            while (k < size && infile[k] != '\"' && infile[k] != '\n')
+            {
+                ++k;
+            }
+
+            if (k >= size || infile[k] == '\n') 
+            {
+                I_Error("Quotes unclosed in response file '%s'", 
+                        response_filename);
+            }
+
+            // Cut off the string at the closing quote
+
+            infile[k] = '\0';
+            ++k;
+        }
+        else
+        {
+            // Read in the next argument until a space is reached
+
+            newargv[newargc++] = &infile[k];
+
+            while(k < size && !isspace(infile[k]))
+            {
+                ++k;
+            }
+
+            // Cut off the end of the argument at the first space
+
+            infile[k] = '\0';
+
+            printf("added arg: '%s'\n", newargv[newargc - 1]);
+
+            ++k;
+        }
+    } 
+
+    // Add arguments following the response file argument
+
+    for (i=argv_index + 1; i<myargc; ++i)
+    {
+        newargv[newargc] = myargv[i];
+        ++newargc;
+    }
+
+    myargv = newargv;
+    myargc = newargc;
+
+    // Display arguments
+
+    printf("%d command-line args:\n", myargc);
+
+    for (k=1; k<myargc; k++)
+    {
+        printf("'%s'\n", myargv[k]);
+    }
+}
+
 //
 // Find a Response File
 //
@@ -1089,71 +1232,14 @@
 void FindResponseFile (void)
 {
     int             i;
-#define MAXARGVS        100
-	
-    for (i = 1;i < myargc;i++)
-	if (myargv[i][0] == '@')
-	{
-	    FILE *          handle;
-	    int             size;
-	    int             k;
-	    int             index;
-	    int             indexinfile;
-	    char    *infile;
-	    char    *file;
-	    char    *moreargs[20];
-	    char    *firstargv;
-			
-	    // READ THE RESPONSE FILE INTO MEMORY
-	    handle = fopen (&myargv[i][1],"rb");
-	    if (!handle)
-	    {
-		printf ("\nNo such response file!");
-		exit(1);
-	    }
-	    printf("Found response file %s!\n",&myargv[i][1]);
-	    fseek (handle,0,SEEK_END);
-	    size = ftell(handle);
-	    fseek (handle,0,SEEK_SET);
-	    file = malloc (size);
-	    fread (file,size,1,handle);
-	    fclose (handle);
-			
-	    // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
-	    for (index = 0,k = i+1; k < myargc; k++)
-		moreargs[index++] = myargv[k];
-			
-	    firstargv = myargv[0];
-	    myargv = malloc(sizeof(char *)*MAXARGVS);
-	    memset(myargv,0,sizeof(char *)*MAXARGVS);
-	    myargv[0] = firstargv;
-			
-	    infile = file;
-	    indexinfile = k = 0;
-	    indexinfile++;  // SKIP PAST ARGV[0] (KEEP IT)
-	    do
-	    {
-		myargv[indexinfile++] = infile+k;
-		while(k < size &&
-		      ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
-		    k++;
-		*(infile+k) = 0;
-		while(k < size &&
-		      ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
-		    k++;
-	    } while(k < size);
-			
-	    for (k = 0;k < index;k++)
-		myargv[indexinfile++] = moreargs[k];
-	    myargc = indexinfile;
-	
-	    // DISPLAY ARGS
-	    printf("%d command-line args:\n",myargc);
-	    for (k=1;k<myargc;k++)
-		printf("%s\n",myargv[k]);
 
-	    break;
-	}
+    for (i = 1; i < myargc; i++)
+    {
+        if (myargv[i][0] == '@')
+        {
+            LoadResponseFile(i);
+        }
+    }
 }
 
 // Startup banner