sc_man.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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 <stdlib.h>
  13. #include "doomtype.h"
  14. #include "w_wad.h"
  15. #include "m_misc.h"
  16. #include "z_zone.h"
  17. #include "lprintf.h"
  18. #include "sc_man.h"
  19. // MACROS ------------------------------------------------------------------
  20. #define MAX_STRING_SIZE 256
  21. #define ASCII_COMMENT (';')
  22. #define ASCII_QUOTE (34)
  23. // TYPES -------------------------------------------------------------------
  24. // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
  25. // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
  26. // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
  27. static void CheckOpen(void);
  28. static void OpenScript(void);
  29. static void OpenScriptByName(const char *name);
  30. static void OpenScriptByNum(int lump);
  31. // EXTERNAL DATA DECLARATIONS ----------------------------------------------
  32. // PUBLIC DATA DEFINITIONS -------------------------------------------------
  33. char *sc_String;
  34. int sc_Number;
  35. int sc_Line;
  36. dboolean sc_End;
  37. dboolean sc_Crossed;
  38. dboolean sc_FileScripts = false;
  39. // PRIVATE DATA DEFINITIONS ------------------------------------------------
  40. static char ScriptName[16];
  41. static int ScriptLump;
  42. static const char *ScriptBuffer;
  43. static const char *ScriptPtr;
  44. static const char *ScriptEndPtr;
  45. static char StringBuffer[MAX_STRING_SIZE];
  46. static dboolean ScriptOpen = false;
  47. static int ScriptSize;
  48. static dboolean AlreadyGot = false;
  49. // CODE --------------------------------------------------------------------
  50. //==========================================================================
  51. //
  52. // SC_OpenLump
  53. //
  54. // Loads a script (from the WAD files) and prepares it for parsing.
  55. //
  56. //==========================================================================
  57. void SC_OpenLump(const char *name)
  58. {
  59. OpenScriptByName(name);
  60. }
  61. void SC_OpenLumpByNum(int lump)
  62. {
  63. OpenScriptByNum(lump);
  64. }
  65. //==========================================================================
  66. //
  67. // OpenScript
  68. //
  69. //==========================================================================
  70. static void OpenScript(void)
  71. {
  72. ScriptBuffer = W_CacheLumpNum(ScriptLump);
  73. ScriptSize = W_LumpLength(ScriptLump);
  74. ScriptBuffer = W_CacheLumpNum(ScriptLump);
  75. ScriptSize = W_LumpLength(ScriptLump);
  76. ScriptPtr = ScriptBuffer;
  77. ScriptEndPtr = ScriptPtr + ScriptSize;
  78. sc_Line = 1;
  79. sc_End = false;
  80. ScriptOpen = true;
  81. sc_String = StringBuffer;
  82. AlreadyGot = false;
  83. }
  84. static void OpenScriptByName(const char *name)
  85. {
  86. SC_Close();
  87. // Lump script
  88. ScriptLump = W_GetNumForName(name);
  89. strcpy(ScriptName, name);
  90. OpenScript();
  91. }
  92. static void OpenScriptByNum(int lump)
  93. {
  94. SC_Close();
  95. // Lump script
  96. ScriptLump = lump;
  97. strcpy(ScriptName, W_GetLumpInfoByNum(ScriptLump)->name);
  98. OpenScript();
  99. }
  100. //==========================================================================
  101. //
  102. // SC_Close
  103. //
  104. //==========================================================================
  105. void SC_Close(void)
  106. {
  107. if (ScriptOpen)
  108. {
  109. W_UnlockLumpNum(ScriptLump);
  110. ScriptOpen = false;
  111. }
  112. }
  113. //==========================================================================
  114. //
  115. // SC_GetString
  116. //
  117. //==========================================================================
  118. dboolean SC_GetString(void)
  119. {
  120. char *text;
  121. dboolean foundToken;
  122. CheckOpen();
  123. if (AlreadyGot)
  124. {
  125. AlreadyGot = false;
  126. return true;
  127. }
  128. foundToken = false;
  129. sc_Crossed = false;
  130. if (ScriptPtr >= ScriptEndPtr)
  131. {
  132. sc_End = true;
  133. return false;
  134. }
  135. while (foundToken == false)
  136. {
  137. while (*ScriptPtr <= 32)
  138. {
  139. if (ScriptPtr >= ScriptEndPtr)
  140. {
  141. sc_End = true;
  142. return false;
  143. }
  144. if (*ScriptPtr++ == '\n')
  145. {
  146. sc_Line++;
  147. sc_Crossed = true;
  148. }
  149. }
  150. if (ScriptPtr >= ScriptEndPtr)
  151. {
  152. sc_End = true;
  153. return false;
  154. }
  155. if (*ScriptPtr != ASCII_COMMENT)
  156. { // Found a token
  157. foundToken = true;
  158. }
  159. else
  160. { // Skip comment
  161. while (*ScriptPtr++ != '\n')
  162. {
  163. if (ScriptPtr >= ScriptEndPtr)
  164. {
  165. sc_End = true;
  166. return false;
  167. }
  168. }
  169. sc_Line++;
  170. sc_Crossed = true;
  171. }
  172. }
  173. text = sc_String;
  174. if (*ScriptPtr == ASCII_QUOTE)
  175. { // Quoted string
  176. ScriptPtr++;
  177. while (*ScriptPtr != ASCII_QUOTE)
  178. {
  179. *text++ = *ScriptPtr++;
  180. if (ScriptPtr == ScriptEndPtr || text == &sc_String[MAX_STRING_SIZE - 1])
  181. {
  182. break;
  183. }
  184. }
  185. ScriptPtr++;
  186. }
  187. else
  188. { // Normal string
  189. while ((*ScriptPtr > 32) && (*ScriptPtr != ASCII_COMMENT))
  190. {
  191. *text++ = *ScriptPtr++;
  192. if(ScriptPtr == ScriptEndPtr || text == &sc_String[MAX_STRING_SIZE-1])
  193. {
  194. break;
  195. }
  196. }
  197. }
  198. *text = 0;
  199. return true;
  200. }
  201. //==========================================================================
  202. //
  203. // SC_MustGetString
  204. //
  205. //==========================================================================
  206. void SC_MustGetString(void)
  207. {
  208. if (SC_GetString() == false)
  209. {
  210. SC_ScriptError("Missing string.");
  211. }
  212. }
  213. //==========================================================================
  214. //
  215. // SC_MustGetStringName
  216. //
  217. //==========================================================================
  218. void SC_MustGetStringName(const char *name)
  219. {
  220. SC_MustGetString();
  221. if (SC_Compare(name) == false)
  222. {
  223. SC_ScriptError(NULL);
  224. }
  225. }
  226. //==========================================================================
  227. //
  228. // SC_GetNumber
  229. //
  230. //==========================================================================
  231. dboolean SC_GetNumber(void)
  232. {
  233. char *stopper;
  234. CheckOpen();
  235. if (SC_GetString())
  236. {
  237. sc_Number = strtol(sc_String, &stopper, 0);
  238. if (*stopper != 0)
  239. {
  240. I_Error("SC_GetNumber: Bad numeric constant \"%s\".\n"
  241. "Script %s, Line %d", sc_String, ScriptName, sc_Line);
  242. }
  243. return true;
  244. }
  245. else
  246. {
  247. return false;
  248. }
  249. }
  250. //==========================================================================
  251. //
  252. // SC_MustGetNumber
  253. //
  254. //==========================================================================
  255. void SC_MustGetNumber(void)
  256. {
  257. if (SC_GetNumber() == false)
  258. {
  259. SC_ScriptError("Missing integer.");
  260. }
  261. }
  262. //==========================================================================
  263. //
  264. // SC_UnGet
  265. //
  266. // Assumes there is a valid string in sc_String.
  267. //
  268. //==========================================================================
  269. void SC_UnGet(void)
  270. {
  271. AlreadyGot = true;
  272. }
  273. //==========================================================================
  274. //
  275. // SC_Check
  276. //
  277. // Returns true if another token is on the current line.
  278. //
  279. //==========================================================================
  280. dboolean SC_Check(void)
  281. {
  282. const char *text;
  283. CheckOpen();
  284. text = ScriptPtr;
  285. if (text >= ScriptEndPtr)
  286. {
  287. return false;
  288. }
  289. while (*text <= 32)
  290. {
  291. if (*text == '\n')
  292. {
  293. return false;
  294. }
  295. text++;
  296. if(text == ScriptEndPtr)
  297. {
  298. return false;
  299. }
  300. }
  301. if (*text == ASCII_COMMENT)
  302. {
  303. return false;
  304. }
  305. return true;
  306. }
  307. //==========================================================================
  308. //
  309. // SC_MatchString
  310. //
  311. // Returns the index of the first match to sc_String from the passed
  312. // array of strings, or -1 if not found.
  313. //
  314. //==========================================================================
  315. int SC_MatchString(const char **strings)
  316. {
  317. int i;
  318. for (i = 0; *strings != NULL; i++)
  319. {
  320. if (SC_Compare(*strings++))
  321. {
  322. return i;
  323. }
  324. }
  325. return -1;
  326. }
  327. //==========================================================================
  328. //
  329. // SC_MustMatchString
  330. //
  331. //==========================================================================
  332. int SC_MustMatchString(const char **strings)
  333. {
  334. int i;
  335. i = SC_MatchString(strings);
  336. if (i == -1)
  337. {
  338. SC_ScriptError(NULL);
  339. }
  340. return i;
  341. }
  342. //==========================================================================
  343. //
  344. // SC_Compare
  345. //
  346. //==========================================================================
  347. dboolean SC_Compare(const char *text)
  348. {
  349. if (strcasecmp(text, sc_String) == 0)
  350. {
  351. return true;
  352. }
  353. return false;
  354. }
  355. //==========================================================================
  356. //
  357. // SC_ScriptError
  358. //
  359. //==========================================================================
  360. void SC_ScriptError(const char *message)
  361. {
  362. if (message == NULL)
  363. {
  364. message = "Bad syntax.";
  365. }
  366. I_Error("Script error, \"%s\" line %d: %s", ScriptName, sc_Line, message);
  367. }
  368. //==========================================================================
  369. //
  370. // CheckOpen
  371. //
  372. //==========================================================================
  373. static void CheckOpen(void)
  374. {
  375. if (ScriptOpen == false)
  376. {
  377. I_Error("SC_ call before SC_Open().");
  378. }
  379. }