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