cmdlib.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /* Copyright (C) 1996-1997 Id Software, Inc.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13. See file, 'COPYING', for details.
  14. */
  15. // cmdlib.c
  16. #include "cmdlib.h"
  17. #include <sys/time.h>
  18. #define PATHSEPERATOR '/'
  19. // set these before calling CheckParm
  20. int myargc;
  21. char **myargv;
  22. char com_token[1024];
  23. int com_eof;
  24. /*
  25. ================
  26. I_FloatTime
  27. ================
  28. */
  29. double I_FloatTime (void)
  30. {
  31. struct timeval tp;
  32. struct timezone tzp;
  33. static int secbase;
  34. gettimeofday(&tp, &tzp);
  35. if (!secbase)
  36. {
  37. secbase = tp.tv_sec;
  38. return tp.tv_usec/1000000.0;
  39. }
  40. return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
  41. }
  42. /*
  43. ==============
  44. COM_Parse
  45. Parse a token out of a string
  46. ==============
  47. */
  48. char *COM_Parse (char *data)
  49. {
  50. int c;
  51. int len;
  52. len = 0;
  53. com_token[0] = 0;
  54. if (!data)
  55. return NULL;
  56. // skip whitespace
  57. skipwhite:
  58. while ( (c = *data) <= ' ')
  59. {
  60. if (c == 0)
  61. {
  62. com_eof = true;
  63. return NULL; // end of file;
  64. }
  65. data++;
  66. }
  67. // skip // comments
  68. if (c=='/' && data[1] == '/')
  69. {
  70. while (*data && *data != '\n')
  71. data++;
  72. goto skipwhite;
  73. }
  74. // handle quoted strings specially
  75. if (c == '\"')
  76. {
  77. data++;
  78. do
  79. {
  80. c = *data++;
  81. if (c=='\"')
  82. {
  83. com_token[len] = 0;
  84. return data;
  85. }
  86. com_token[len] = c;
  87. len++;
  88. } while (1);
  89. }
  90. // parse single characters
  91. if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
  92. {
  93. com_token[len] = c;
  94. len++;
  95. com_token[len] = 0;
  96. return data+1;
  97. }
  98. // parse a regular word
  99. do
  100. {
  101. com_token[len] = c;
  102. data++;
  103. len++;
  104. c = *data;
  105. if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
  106. break;
  107. } while (c>32);
  108. com_token[len] = 0;
  109. return data;
  110. }
  111. /*
  112. ================
  113. filelength
  114. ================
  115. */
  116. int filelength (int handle)
  117. {
  118. struct stat fileinfo;
  119. if (fstat (handle,&fileinfo) == -1)
  120. {
  121. Error ("Error fstating");
  122. }
  123. return fileinfo.st_size;
  124. }
  125. int tell (int handle)
  126. {
  127. return lseek (handle, 0, SEEK_CUR);
  128. }
  129. char *strupr (char *start)
  130. {
  131. char *in;
  132. in = start;
  133. while (*in)
  134. {
  135. *in = toupper(*in);
  136. in++;
  137. }
  138. return start;
  139. }
  140. char *strlower (char *start)
  141. {
  142. char *in;
  143. in = start;
  144. while (*in)
  145. {
  146. *in = tolower(*in);
  147. in++;
  148. }
  149. return start;
  150. }
  151. /*
  152. =============================================================================
  153. MISC FUNCTIONS
  154. =============================================================================
  155. */
  156. /*
  157. =================
  158. Error
  159. For abnormal program terminations
  160. =================
  161. */
  162. void Error (char *error, ...)
  163. {
  164. va_list argptr;
  165. printf ("\n************ ERROR ************\n");
  166. va_start (argptr,error);
  167. vprintf (error,argptr);
  168. va_end (argptr);
  169. printf ("\n");
  170. exit (1);
  171. }
  172. /*
  173. =================
  174. CheckParm
  175. Checks for the given parameter in the program's command line arguments
  176. Returns the argument number (1 to argc-1) or 0 if not present
  177. =================
  178. */
  179. int CheckParm (char *check)
  180. {
  181. int i;
  182. for (i = 1;i<myargc;i++)
  183. {
  184. if ( !strcasecmp(check, myargv[i]) )
  185. return i;
  186. }
  187. return 0;
  188. }
  189. #ifndef O_BINARY
  190. #define O_BINARY 0
  191. #endif
  192. int SafeOpenWrite (char *filename)
  193. {
  194. int handle;
  195. umask (0);
  196. handle = open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY
  197. , 0666);
  198. if (handle == -1)
  199. Error ("Error opening %s: %s",filename,strerror(errno));
  200. return handle;
  201. }
  202. int SafeOpenRead (char *filename)
  203. {
  204. int handle;
  205. handle = open(filename,O_RDONLY | O_BINARY);
  206. if (handle == -1)
  207. Error ("Error opening %s: %s",filename,strerror(errno));
  208. return handle;
  209. }
  210. void SafeRead (int handle, void *buffer, long count)
  211. {
  212. if (read (handle,buffer,count) != count)
  213. Error ("File read failure");
  214. }
  215. void SafeWrite (int handle, void *buffer, long count)
  216. {
  217. if (write (handle,buffer,count) != count)
  218. Error ("File write failure");
  219. }
  220. void *SafeMalloc (long size)
  221. {
  222. void *ptr;
  223. ptr = malloc (size);
  224. if (!ptr)
  225. Error ("Malloc failure for %lu bytes",size);
  226. return ptr;
  227. }
  228. /*
  229. ==============
  230. LoadFile
  231. ==============
  232. */
  233. long LoadFile (char *filename, void **bufferptr)
  234. {
  235. int handle;
  236. long length;
  237. void *buffer;
  238. handle = SafeOpenRead (filename);
  239. length = filelength (handle);
  240. buffer = SafeMalloc (length+1);
  241. ((byte *)buffer)[length] = 0;
  242. SafeRead (handle, buffer, length);
  243. close (handle);
  244. *bufferptr = buffer;
  245. return length;
  246. }
  247. /*
  248. ==============
  249. SaveFile
  250. ==============
  251. */
  252. void SaveFile (char *filename, void *buffer, long count)
  253. {
  254. int handle;
  255. handle = SafeOpenWrite (filename);
  256. SafeWrite (handle, buffer, count);
  257. close (handle);
  258. }
  259. void DefaultExtension (char *path, char *extension)
  260. {
  261. char *src;
  262. //
  263. // if path doesn't have a .EXT, append extension
  264. // (extension should include the .)
  265. //
  266. src = path + strlen(path) - 1;
  267. while (*src != PATHSEPERATOR && src != path)
  268. {
  269. if (*src == '.')
  270. return; // it has an extension
  271. src--;
  272. }
  273. strcat (path, extension);
  274. }
  275. void DefaultPath (char *path, char *basepath)
  276. {
  277. char temp[128];
  278. if (path[0] == PATHSEPERATOR)
  279. return; // absolute path location
  280. strcpy (temp,path);
  281. strcpy (path,basepath);
  282. strcat (path,temp);
  283. }
  284. void StripFilename (char *path)
  285. {
  286. int length;
  287. length = strlen(path)-1;
  288. while (length > 0 && path[length] != PATHSEPERATOR)
  289. length--;
  290. path[length] = 0;
  291. }
  292. void StripExtension (char *path)
  293. {
  294. int length;
  295. length = strlen(path)-1;
  296. while (length > 0 && path[length] != '.')
  297. {
  298. length--;
  299. if (path[length] == '/')
  300. return; // no extension
  301. }
  302. if (length)
  303. path[length] = 0;
  304. }
  305. /*
  306. ====================
  307. Extract file parts
  308. ====================
  309. */
  310. void ExtractFilePath (char *path, char *dest)
  311. {
  312. char *src;
  313. src = path + strlen(path) - 1;
  314. //
  315. // back up until a \ or the start
  316. //
  317. while (src != path && *(src-1) != PATHSEPERATOR)
  318. src--;
  319. memcpy (dest, path, src-path);
  320. dest[src-path] = 0;
  321. }
  322. void ExtractFileBase (char *path, char *dest)
  323. {
  324. char *src;
  325. src = path + strlen(path) - 1;
  326. //
  327. // back up until a \ or the start
  328. //
  329. while (src != path && *(src-1) != PATHSEPERATOR)
  330. src--;
  331. while (*src && *src != '.')
  332. {
  333. *dest++ = *src++;
  334. }
  335. *dest = 0;
  336. }
  337. void ExtractFileExtension (char *path, char *dest)
  338. {
  339. char *src;
  340. src = path + strlen(path) - 1;
  341. //
  342. // back up until a . or the start
  343. //
  344. while (src != path && *(src-1) != '.')
  345. src--;
  346. if (src == path)
  347. {
  348. *dest = 0; // no extension
  349. return;
  350. }
  351. strcpy (dest,src);
  352. }
  353. /*
  354. ==============
  355. ParseNum / ParseHex
  356. ==============
  357. */
  358. long ParseHex (char *hex)
  359. {
  360. char *str;
  361. long num;
  362. num = 0;
  363. str = hex;
  364. while (*str)
  365. {
  366. num <<= 4;
  367. if (*str >= '0' && *str <= '9')
  368. num += *str-'0';
  369. else if (*str >= 'a' && *str <= 'f')
  370. num += 10 + *str-'a';
  371. else if (*str >= 'A' && *str <= 'F')
  372. num += 10 + *str-'A';
  373. else
  374. Error ("Bad hex number: %s",hex);
  375. str++;
  376. }
  377. return num;
  378. }
  379. long ParseNum (char *str)
  380. {
  381. if (str[0] == '$')
  382. return ParseHex (str+1);
  383. if (str[0] == '0' && str[1] == 'x')
  384. return ParseHex (str+2);
  385. return atol (str);
  386. }
  387. /*
  388. ============================================================================
  389. BYTE ORDER FUNCTIONS
  390. ============================================================================
  391. */
  392. #ifdef __BIG_ENDIAN__
  393. short LittleShort (short l)
  394. {
  395. byte b1,b2;
  396. b1 = l&255;
  397. b2 = (l>>8)&255;
  398. return (b1<<8) + b2;
  399. }
  400. short BigShort (short l)
  401. {
  402. return l;
  403. }
  404. long LittleLong (long l)
  405. {
  406. byte b1,b2,b3,b4;
  407. b1 = l&255;
  408. b2 = (l>>8)&255;
  409. b3 = (l>>16)&255;
  410. b4 = (l>>24)&255;
  411. return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
  412. }
  413. long BigLong (long l)
  414. {
  415. return l;
  416. }
  417. float LittleFloat (float l)
  418. {
  419. union {byte b[4]; float f;} in, out;
  420. in.f = l;
  421. out.b[0] = in.b[3];
  422. out.b[1] = in.b[2];
  423. out.b[2] = in.b[1];
  424. out.b[3] = in.b[0];
  425. return out.f;
  426. }
  427. float BigFloat (float l)
  428. {
  429. return l;
  430. }
  431. #else
  432. short BigShort (short l)
  433. {
  434. byte b1,b2;
  435. b1 = l&255;
  436. b2 = (l>>8)&255;
  437. return (b1<<8) + b2;
  438. }
  439. short LittleShort (short l)
  440. {
  441. return l;
  442. }
  443. long BigLong (long l)
  444. {
  445. byte b1,b2,b3,b4;
  446. b1 = l&255;
  447. b2 = (l>>8)&255;
  448. b3 = (l>>16)&255;
  449. b4 = (l>>24)&255;
  450. return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
  451. }
  452. long LittleLong (long l)
  453. {
  454. return l;
  455. }
  456. float BigFloat (float l)
  457. {
  458. union {byte b[4]; float f;} in, out;
  459. in.f = l;
  460. out.b[0] = in.b[3];
  461. out.b[1] = in.b[2];
  462. out.b[2] = in.b[1];
  463. out.b[3] = in.b[0];
  464. return out.f;
  465. }
  466. float LittleFloat (float l)
  467. {
  468. return l;
  469. }
  470. #endif