cmdlib.c 9.9 KB

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