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 
M_CheckParmWithArgs(char * check,int num_args)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 
M_ParmExists(char * check)63 boolean M_ParmExists(char *check)
64 {
65     return M_CheckParm(check) != 0;
66 }
67 
M_CheckParm(char * check)68 int M_CheckParm(char *check)
69 {
70     return M_CheckParmWithArgs(check, 0);
71 }
72 
73 #define MAXARGVS        100
74 
LoadResponseFile(int argv_index)75 static void LoadResponseFile(int argv_index)
76 {
77     FILE *handle;
78     int size;
79     char *infile;
80     char *file;
81     char *response_filename;
82     char **newargv;
83     int newargc;
84     int i, k;
85 
86     response_filename = myargv[argv_index] + 1;
87 
88     // Read the response file into memory
89     handle = fopen(response_filename, "rb");
90 
91     if (handle == NULL)
92     {
93         printf ("\nNo such response file!");
94         exit(1);
95     }
96 
97     printf("Found response file %s!\n", response_filename);
98 
99     size = M_FileLength(handle);
100 
101     // Read in the entire file
102     // Allocate one byte extra - this is in case there is an argument
103     // at the end of the response file, in which case a '\0' will be
104     // needed.
105 
106     file = malloc(size + 1);
107 
108     i = 0;
109 
110     while (i < size)
111     {
112         k = fread(file + i, 1, size - i, handle);
113 
114         if (k < 0)
115         {
116             I_Error("Failed to read full contents of '%s'", response_filename);
117         }
118 
119         i += k;
120     }
121 
122     fclose(handle);
123 
124     // Create new arguments list array
125 
126     newargv = malloc(sizeof(char *) * MAXARGVS);
127     newargc = 0;
128     memset(newargv, 0, sizeof(char *) * MAXARGVS);
129 
130     // Copy all the arguments in the list up to the response file
131 
132     for (i=0; i<argv_index; ++i)
133     {
134         newargv[i] = myargv[i];
135         ++newargc;
136     }
137 
138     infile = file;
139     k = 0;
140 
141     while(k < size)
142     {
143         // Skip past space characters to the next argument
144 
145         while(k < size && isspace(infile[k]))
146         {
147             ++k;
148         }
149 
150         if (k >= size)
151         {
152             break;
153         }
154 
155         // If the next argument is enclosed in quote marks, treat
156         // the contents as a single argument.  This allows long filenames
157         // to be specified.
158 
159         if (infile[k] == '\"')
160         {
161             // Skip the first character(")
162             ++k;
163 
164             newargv[newargc++] = &infile[k];
165 
166             // Read all characters between quotes
167 
168             while (k < size && infile[k] != '\"' && infile[k] != '\n')
169             {
170                 ++k;
171             }
172 
173             if (k >= size || infile[k] == '\n')
174             {
175                 I_Error("Quotes unclosed in response file '%s'",
176                         response_filename);
177             }
178 
179             // Cut off the string at the closing quote
180 
181             infile[k] = '\0';
182             ++k;
183         }
184         else
185         {
186             // Read in the next argument until a space is reached
187 
188             newargv[newargc++] = &infile[k];
189 
190             while(k < size && !isspace(infile[k]))
191             {
192                 ++k;
193             }
194 
195             // Cut off the end of the argument at the first space
196 
197             infile[k] = '\0';
198 
199             ++k;
200         }
201     }
202 
203     // Add arguments following the response file argument
204 
205     for (i=argv_index + 1; i<myargc; ++i)
206     {
207         newargv[newargc] = myargv[i];
208         ++newargc;
209     }
210 
211     myargv = newargv;
212     myargc = newargc;
213 
214 #if 0
215     // Disabled - Vanilla Doom does not do this.
216     // Display arguments
217 
218     printf("%d command-line args:\n", myargc);
219 
220     for (k=1; k<myargc; k++)
221     {
222         printf("'%s'\n", myargv[k]);
223     }
224 #endif
225 }
226 
227 //
228 // Find a Response File
229 //
230 
M_FindResponseFile(void)231 void M_FindResponseFile(void)
232 {
233     int             i;
234 
235     for (i = 1; i < myargc; i++)
236     {
237         if (myargv[i][0] == '@')
238         {
239             LoadResponseFile(i);
240         }
241     }
242 }
243 
244 // Return the name of the executable used to start the program:
245 
M_GetExecutableName(void)246 char *M_GetExecutableName(void)
247 {
248     char *sep;
249 
250     sep = strrchr(myargv[0], DIR_SEPARATOR);
251 
252     if (sep == NULL)
253     {
254         return myargv[0];
255     }
256     else
257     {
258         return sep + 1;
259     }
260 }
261 
262