m_argv.c
  1  //
  2  // Copyright(C) 1993-1996 Id Software, Inc.
  3  // Copyright(C) 2005-2014 Simon Howard
  4  //
  5  // This program is free software; you can redistribute it and/or
  6  // modify it under the terms of the GNU General Public License
  7  // as published by the Free Software Foundation; either version 2
  8  // of the License, or (at your option) any later version.
  9  //
 10  // This program is distributed in the hope that it will be useful,
 11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  // GNU General Public License for more details.
 14  //
 15  // DESCRIPTION:
 16  //
 17  
 18  
 19  #include <ctype.h>
 20  #include <stdio.h>
 21  #include <stdlib.h>
 22  #include <string.h>
 23  
 24  #include "doomtype.h"
 25  #include "i_system.h"
 26  #include "m_misc.h"
 27  #include "m_argv.h"  // haleyjd 20110212: warning fix
 28  
 29  int		myargc;
 30  char**		myargv;
 31  
 32  
 33  
 34  
 35  //
 36  // M_CheckParm
 37  // Checks for the given parameter
 38  // in the program's command line arguments.
 39  // Returns the argument number (1 to argc-1)
 40  // or 0 if not present
 41  //
 42  
 43  int M_CheckParmWithArgs(char *check, int num_args)
 44  {
 45      int i;
 46  
 47      for (i = 1; i < myargc - num_args; i++)
 48      {
 49  	if (!strcasecmp(check, myargv[i]))
 50  	    return i;
 51      }
 52  
 53      return 0;
 54  }
 55  
 56  //
 57  // M_ParmExists
 58  //
 59  // Returns true if the given parameter exists in the program's command
 60  // line arguments, false if not.
 61  //
 62  
 63  boolean M_ParmExists(char *check)
 64  {
 65      return M_CheckParm(check) != 0;
 66  }
 67  
 68  int M_CheckParm(char *check)
 69  {
 70      return M_CheckParmWithArgs(check, 0);
 71  }
 72  
 73  #define MAXARGVS        100
 74  
 75  static void LoadResponseFile(int argv_index)
 76  {
 77  #if ORIGCODE
 78      FILE *handle;
 79      int size;
 80      char *infile;
 81      char *file;
 82      char *response_filename;
 83      char **newargv;
 84      int newargc;
 85      int i, k;
 86  
 87      response_filename = myargv[argv_index] + 1;
 88  
 89      // Read the response file into memory
 90      handle = fopen(response_filename, "rb");
 91  
 92      if (handle == NULL)
 93      {
 94          printf ("\nNo such response file!");
 95  #if ORIGCODE
 96          exit(1);
 97  #endif
 98      }
 99  
100      printf("Found response file %s!\n", response_filename);
101  
102      size = M_FileLength(handle);
103  
104      // Read in the entire file
105      // Allocate one byte extra - this is in case there is an argument
106      // at the end of the response file, in which case a '\0' will be
107      // needed.
108  
109      file = malloc(size + 1);
110  
111      i = 0;
112  
113      while (i < size)
114      {
115          k = fread(file + i, 1, size - i, handle);
116  
117          if (k < 0)
118          {
119              I_Error("Failed to read full contents of '%s'", response_filename);
120          }
121  
122          i += k;
123      }
124  
125      fclose(handle);
126  
127      // Create new arguments list array
128  
129      newargv = malloc(sizeof(char *) * MAXARGVS);
130      newargc = 0;
131      memset(newargv, 0, sizeof(char *) * MAXARGVS);
132  
133      // Copy all the arguments in the list up to the response file
134  
135      for (i=0; i<argv_index; ++i)
136      {
137          newargv[i] = myargv[i];
138          ++newargc;
139      }
140  
141      infile = file;
142      k = 0;
143  
144      while(k < size)
145      {
146          // Skip past space characters to the next argument
147  
148          while(k < size && isspace((int)infile[k]))
149          {
150              ++k;
151          }
152  
153          if (k >= size)
154          {
155              break;
156          }
157  
158          // If the next argument is enclosed in quote marks, treat
159          // the contents as a single argument.  This allows long filenames
160          // to be specified.
161  
162          if (infile[k] == '\"')
163          {
164              // Skip the first character(")
165              ++k;
166  
167              newargv[newargc++] = &infile[k];
168  
169              // Read all characters between quotes
170  
171              while (k < size && infile[k] != '\"' && infile[k] != '\n')
172              {
173                  ++k;
174              }
175  
176              if (k >= size || infile[k] == '\n')
177              {
178                  I_Error("Quotes unclosed in response file '%s'",
179                          response_filename);
180              }
181  
182              // Cut off the string at the closing quote
183  
184              infile[k] = '\0';
185              ++k;
186          }
187          else
188          {
189              // Read in the next argument until a space is reached
190  
191              newargv[newargc++] = &infile[k];
192  
193              while(k < size && !isspace((int)infile[k]))
194              {
195                  ++k;
196              }
197  
198              // Cut off the end of the argument at the first space
199  
200              infile[k] = '\0';
201  
202              ++k;
203          }
204      }
205  
206      // Add arguments following the response file argument
207  
208      for (i=argv_index + 1; i<myargc; ++i)
209      {
210          newargv[newargc] = myargv[i];
211          ++newargc;
212      }
213  
214      myargv = newargv;
215      myargc = newargc;
216  
217  #if 0
218      // Disabled - Vanilla Doom does not do this.
219      // Display arguments
220  
221      printf("%d command-line args:\n", myargc);
222  
223      for (k=1; k<myargc; k++)
224      {
225          printf("'%s'\n", myargv[k]);
226      }
227  #endif
228  #endif
229  }
230  
231  //
232  // Find a Response File
233  //
234  
235  void M_FindResponseFile(void)
236  {
237      int             i;
238  
239      for (i = 1; i < myargc; i++)
240      {
241          if (myargv[i][0] == '@')
242          {
243              LoadResponseFile(i);
244          }
245      }
246  }
247  
248  // Return the name of the executable used to start the program:
249  
250  char *M_GetExecutableName(void)
251  {
252      char *sep;
253  
254      sep = strrchr(myargv[0], DIR_SEPARATOR);
255  
256      if (sep == NULL)
257      {
258          return myargv[0];
259      }
260      else
261      {
262          return sep + 1;
263      }
264  }
265