SC_MAN.C 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. //**************************************************************************
  2. //**
  3. //** sc_man.c : Heretic 2 : Raven Software, Corp.
  4. //**
  5. //** $RCSfile: sc_man.c,v $
  6. //** $Revision: 1.3 $
  7. //** $Date: 96/01/06 03:23:43 $
  8. //** $Author: bgokey $
  9. //**
  10. //**************************************************************************
  11. // HEADER FILES ------------------------------------------------------------
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include "h2def.h"
  15. // MACROS ------------------------------------------------------------------
  16. #define MAX_STRING_SIZE 64
  17. #define ASCII_COMMENT (';')
  18. #define ASCII_QUOTE (34)
  19. #define LUMP_SCRIPT 1
  20. #define FILE_ZONE_SCRIPT 2
  21. #define FILE_CLIB_SCRIPT 3
  22. // TYPES -------------------------------------------------------------------
  23. // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
  24. // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
  25. // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
  26. static void CheckOpen(void);
  27. static void OpenScript(char *name, int type);
  28. // EXTERNAL DATA DECLARATIONS ----------------------------------------------
  29. // PUBLIC DATA DEFINITIONS -------------------------------------------------
  30. char *sc_String;
  31. int sc_Number;
  32. int sc_Line;
  33. boolean sc_End;
  34. boolean sc_Crossed;
  35. boolean sc_FileScripts = false;
  36. char *sc_ScriptsDir = "";
  37. // PRIVATE DATA DEFINITIONS ------------------------------------------------
  38. static char ScriptName[16];
  39. static char *ScriptBuffer;
  40. static char *ScriptPtr;
  41. static char *ScriptEndPtr;
  42. static char StringBuffer[MAX_STRING_SIZE];
  43. static boolean ScriptOpen = false;
  44. static boolean ScriptFreeCLib; // true = de-allocate using free()
  45. static int ScriptSize;
  46. static boolean AlreadyGot = false;
  47. // CODE --------------------------------------------------------------------
  48. //==========================================================================
  49. //
  50. // SC_Open
  51. //
  52. //==========================================================================
  53. void SC_Open(char *name)
  54. {
  55. char fileName[128];
  56. if(sc_FileScripts == true)
  57. {
  58. sprintf(fileName, "%s%s.txt", sc_ScriptsDir, name);
  59. SC_OpenFile(fileName);
  60. }
  61. else
  62. {
  63. SC_OpenLump(name);
  64. }
  65. }
  66. //==========================================================================
  67. //
  68. // SC_OpenLump
  69. //
  70. // Loads a script (from the WAD files) and prepares it for parsing.
  71. //
  72. //==========================================================================
  73. void SC_OpenLump(char *name)
  74. {
  75. OpenScript(name, LUMP_SCRIPT);
  76. }
  77. //==========================================================================
  78. //
  79. // SC_OpenFile
  80. //
  81. // Loads a script (from a file) and prepares it for parsing. Uses the
  82. // zone memory allocator for memory allocation and de-allocation.
  83. //
  84. //==========================================================================
  85. void SC_OpenFile(char *name)
  86. {
  87. OpenScript(name, FILE_ZONE_SCRIPT);
  88. }
  89. //==========================================================================
  90. //
  91. // SC_OpenFileCLib
  92. //
  93. // Loads a script (from a file) and prepares it for parsing. Uses C
  94. // library function calls for memory allocation and de-allocation.
  95. //
  96. //==========================================================================
  97. void SC_OpenFileCLib(char *name)
  98. {
  99. OpenScript(name, FILE_CLIB_SCRIPT);
  100. }
  101. //==========================================================================
  102. //
  103. // OpenScript
  104. //
  105. //==========================================================================
  106. static void OpenScript(char *name, int type)
  107. {
  108. SC_Close();
  109. if(type == LUMP_SCRIPT)
  110. { // Lump script
  111. ScriptBuffer = (char *)W_CacheLumpName(name, PU_STATIC);
  112. ScriptSize = W_LumpLength(W_GetNumForName(name));
  113. strcpy(ScriptName, name);
  114. ScriptFreeCLib = false; // De-allocate using Z_Free()
  115. }
  116. else if(type == FILE_ZONE_SCRIPT)
  117. { // File script - zone
  118. ScriptSize = M_ReadFile(name, (byte **)&ScriptBuffer);
  119. M_ExtractFileBase(name, ScriptName);
  120. ScriptFreeCLib = false; // De-allocate using Z_Free()
  121. }
  122. else
  123. { // File script - clib
  124. ScriptSize = M_ReadFileCLib(name, (byte **)&ScriptBuffer);
  125. M_ExtractFileBase(name, ScriptName);
  126. ScriptFreeCLib = true; // De-allocate using free()
  127. }
  128. ScriptPtr = ScriptBuffer;
  129. ScriptEndPtr = ScriptPtr+ScriptSize;
  130. sc_Line = 1;
  131. sc_End = false;
  132. ScriptOpen = true;
  133. sc_String = StringBuffer;
  134. AlreadyGot = false;
  135. }
  136. //==========================================================================
  137. //
  138. // SC_Close
  139. //
  140. //==========================================================================
  141. void SC_Close(void)
  142. {
  143. if(ScriptOpen)
  144. {
  145. if(ScriptFreeCLib == true)
  146. {
  147. free(ScriptBuffer);
  148. }
  149. else
  150. {
  151. Z_Free(ScriptBuffer);
  152. }
  153. ScriptOpen = false;
  154. }
  155. }
  156. //==========================================================================
  157. //
  158. // SC_GetString
  159. //
  160. //==========================================================================
  161. boolean SC_GetString(void)
  162. {
  163. char *text;
  164. boolean foundToken;
  165. CheckOpen();
  166. if(AlreadyGot)
  167. {
  168. AlreadyGot = false;
  169. return true;
  170. }
  171. foundToken = false;
  172. sc_Crossed = false;
  173. if(ScriptPtr >= ScriptEndPtr)
  174. {
  175. sc_End = true;
  176. return false;
  177. }
  178. while(foundToken == false)
  179. {
  180. while(*ScriptPtr <= 32)
  181. {
  182. if(ScriptPtr >= ScriptEndPtr)
  183. {
  184. sc_End = true;
  185. return false;
  186. }
  187. if(*ScriptPtr++ == '\n')
  188. {
  189. sc_Line++;
  190. sc_Crossed = true;
  191. }
  192. }
  193. if(ScriptPtr >= ScriptEndPtr)
  194. {
  195. sc_End = true;
  196. return false;
  197. }
  198. if(*ScriptPtr != ASCII_COMMENT)
  199. { // Found a token
  200. foundToken = true;
  201. }
  202. else
  203. { // Skip comment
  204. while(*ScriptPtr++ != '\n')
  205. {
  206. if(ScriptPtr >= ScriptEndPtr)
  207. {
  208. sc_End = true;
  209. return false;
  210. }
  211. }
  212. sc_Line++;
  213. sc_Crossed = true;
  214. }
  215. }
  216. text = sc_String;
  217. if(*ScriptPtr == ASCII_QUOTE)
  218. { // Quoted string
  219. ScriptPtr++;
  220. while(*ScriptPtr != ASCII_QUOTE)
  221. {
  222. *text++ = *ScriptPtr++;
  223. if(ScriptPtr == ScriptEndPtr
  224. || text == &sc_String[MAX_STRING_SIZE-1])
  225. {
  226. break;
  227. }
  228. }
  229. ScriptPtr++;
  230. }
  231. else
  232. { // Normal string
  233. while((*ScriptPtr > 32) && (*ScriptPtr != ASCII_COMMENT))
  234. {
  235. *text++ = *ScriptPtr++;
  236. if(ScriptPtr == ScriptEndPtr
  237. || text == &sc_String[MAX_STRING_SIZE-1])
  238. {
  239. break;
  240. }
  241. }
  242. }
  243. *text = 0;
  244. return true;
  245. }
  246. //==========================================================================
  247. //
  248. // SC_MustGetString
  249. //
  250. //==========================================================================
  251. void SC_MustGetString(void)
  252. {
  253. if(SC_GetString() == false)
  254. {
  255. SC_ScriptError("Missing string.");
  256. }
  257. }
  258. //==========================================================================
  259. //
  260. // SC_MustGetStringName
  261. //
  262. //==========================================================================
  263. void SC_MustGetStringName(char *name)
  264. {
  265. SC_MustGetString();
  266. if(SC_Compare(name) == false)
  267. {
  268. SC_ScriptError(NULL);
  269. }
  270. }
  271. //==========================================================================
  272. //
  273. // SC_GetNumber
  274. //
  275. //==========================================================================
  276. boolean SC_GetNumber(void)
  277. {
  278. char *stopper;
  279. CheckOpen();
  280. if(SC_GetString())
  281. {
  282. sc_Number = strtol(sc_String, &stopper, 0);
  283. if(*stopper != 0)
  284. {
  285. I_Error("SC_GetNumber: Bad numeric constant \"%s\".\n"
  286. "Script %s, Line %d", sc_String, ScriptName, sc_Line);
  287. }
  288. return true;
  289. }
  290. else
  291. {
  292. return false;
  293. }
  294. }
  295. //==========================================================================
  296. //
  297. // SC_MustGetNumber
  298. //
  299. //==========================================================================
  300. void SC_MustGetNumber(void)
  301. {
  302. if(SC_GetNumber() == false)
  303. {
  304. SC_ScriptError("Missing integer.");
  305. }
  306. }
  307. //==========================================================================
  308. //
  309. // SC_UnGet
  310. //
  311. // Assumes there is a valid string in sc_String.
  312. //
  313. //==========================================================================
  314. void SC_UnGet(void)
  315. {
  316. AlreadyGot = true;
  317. }
  318. //==========================================================================
  319. //
  320. // SC_Check
  321. //
  322. // Returns true if another token is on the current line.
  323. //
  324. //==========================================================================
  325. /*
  326. boolean SC_Check(void)
  327. {
  328. char *text;
  329. CheckOpen();
  330. text = ScriptPtr;
  331. if(text >= ScriptEndPtr)
  332. {
  333. return false;
  334. }
  335. while(*text <= 32)
  336. {
  337. if(*text == '\n')
  338. {
  339. return false;
  340. }
  341. text++;
  342. if(text == ScriptEndPtr)
  343. {
  344. return false;
  345. }
  346. }
  347. if(*text == ASCII_COMMENT)
  348. {
  349. return false;
  350. }
  351. return true;
  352. }
  353. */
  354. //==========================================================================
  355. //
  356. // SC_MatchString
  357. //
  358. // Returns the index of the first match to sc_String from the passed
  359. // array of strings, or -1 if not found.
  360. //
  361. //==========================================================================
  362. int SC_MatchString(char **strings)
  363. {
  364. int i;
  365. for(i = 0; *strings != NULL; i++)
  366. {
  367. if(SC_Compare(*strings++))
  368. {
  369. return i;
  370. }
  371. }
  372. return -1;
  373. }
  374. //==========================================================================
  375. //
  376. // SC_MustMatchString
  377. //
  378. //==========================================================================
  379. int SC_MustMatchString(char **strings)
  380. {
  381. int i;
  382. i = SC_MatchString(strings);
  383. if(i == -1)
  384. {
  385. SC_ScriptError(NULL);
  386. }
  387. return i;
  388. }
  389. //==========================================================================
  390. //
  391. // SC_Compare
  392. //
  393. //==========================================================================
  394. boolean SC_Compare(char *text)
  395. {
  396. if(strcasecmp(text, sc_String) == 0)
  397. {
  398. return true;
  399. }
  400. return false;
  401. }
  402. //==========================================================================
  403. //
  404. // SC_ScriptError
  405. //
  406. //==========================================================================
  407. void SC_ScriptError(char *message)
  408. {
  409. if(message == NULL)
  410. {
  411. message = "Bad syntax.";
  412. }
  413. I_Error("Script error, \"%s\" line %d: %s", ScriptName,
  414. sc_Line, message);
  415. }
  416. //==========================================================================
  417. //
  418. // CheckOpen
  419. //
  420. //==========================================================================
  421. static void CheckOpen(void)
  422. {
  423. if(ScriptOpen == false)
  424. {
  425. I_Error("SC_ call before SC_Open().");
  426. }
  427. }