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