Parser.cpp 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code 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. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "precompiled.h"
  21. #pragma hdrstop
  22. //#define DEBUG_EVAL
  23. #define MAX_DEFINEPARMS 128
  24. #define DEFINEHASHSIZE 2048
  25. #define TOKEN_FL_RECURSIVE_DEFINE 1
  26. define_t * idParser::globaldefines;
  27. /*
  28. ================
  29. idParser::SetBaseFolder
  30. ================
  31. */
  32. void idParser::SetBaseFolder( const char *path) {
  33. idLexer::SetBaseFolder(path);
  34. }
  35. /*
  36. ================
  37. idParser::AddGlobalDefine
  38. ================
  39. */
  40. int idParser::AddGlobalDefine( const char *string ) {
  41. define_t *define;
  42. define = idParser::DefineFromString(string);
  43. if (!define) {
  44. return false;
  45. }
  46. define->next = globaldefines;
  47. globaldefines = define;
  48. return true;
  49. }
  50. /*
  51. ================
  52. idParser::RemoveGlobalDefine
  53. ================
  54. */
  55. int idParser::RemoveGlobalDefine( const char *name ) {
  56. define_t *d, *prev;
  57. for ( prev = NULL, d = idParser::globaldefines; d; prev = d, d = d->next ) {
  58. if ( !strcmp( d->name, name ) ) {
  59. break;
  60. }
  61. }
  62. if ( d ) {
  63. if ( prev ) {
  64. prev->next = d->next;
  65. }
  66. else {
  67. idParser::globaldefines = d->next;
  68. }
  69. idParser::FreeDefine( d );
  70. return true;
  71. }
  72. return false;
  73. }
  74. /*
  75. ================
  76. idParser::RemoveAllGlobalDefines
  77. ================
  78. */
  79. void idParser::RemoveAllGlobalDefines( void ) {
  80. define_t *define;
  81. for ( define = globaldefines; define; define = globaldefines ) {
  82. globaldefines = globaldefines->next;
  83. idParser::FreeDefine(define);
  84. }
  85. }
  86. /*
  87. ===============================================================================
  88. idParser
  89. ===============================================================================
  90. */
  91. /*
  92. ================
  93. idParser::PrintDefine
  94. ================
  95. */
  96. void idParser::PrintDefine( define_t *define ) {
  97. idLib::common->Printf("define->name = %s\n", define->name);
  98. idLib::common->Printf("define->flags = %d\n", define->flags);
  99. idLib::common->Printf("define->builtin = %d\n", define->builtin);
  100. idLib::common->Printf("define->numparms = %d\n", define->numparms);
  101. }
  102. /*
  103. ================
  104. PC_PrintDefineHashTable
  105. ================
  106. * /
  107. static void PC_PrintDefineHashTable(define_t **definehash) {
  108. int i;
  109. define_t *d;
  110. for (i = 0; i < DEFINEHASHSIZE; i++) {
  111. Log_Write("%4d:", i);
  112. for (d = definehash[i]; d; d = d->hashnext) {
  113. Log_Write(" %s", d->name);
  114. }
  115. Log_Write("\n");
  116. }
  117. }
  118. */
  119. /*
  120. ================
  121. PC_NameHash
  122. ================
  123. */
  124. ID_INLINE int PC_NameHash( const char *name ) {
  125. int hash, i;
  126. hash = 0;
  127. for ( i = 0; name[i] != '\0'; i++ ) {
  128. hash += name[i] * (119 + i);
  129. }
  130. hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (DEFINEHASHSIZE-1);
  131. return hash;
  132. }
  133. /*
  134. ================
  135. idParser::AddDefineToHash
  136. ================
  137. */
  138. void idParser::AddDefineToHash( define_t *define, define_t **definehash ) {
  139. int hash;
  140. hash = PC_NameHash(define->name);
  141. define->hashnext = definehash[hash];
  142. definehash[hash] = define;
  143. }
  144. /*
  145. ================
  146. FindHashedDefine
  147. ================
  148. */
  149. define_t *idParser::FindHashedDefine( define_t **definehash, const char *name ) {
  150. define_t *d;
  151. int hash;
  152. hash = PC_NameHash(name);
  153. for ( d = definehash[hash]; d; d = d->hashnext ) {
  154. if ( !strcmp(d->name, name) ) {
  155. return d;
  156. }
  157. }
  158. return NULL;
  159. }
  160. /*
  161. ================
  162. idParser::FindDefine
  163. ================
  164. */
  165. define_t *idParser::FindDefine( define_t *defines, const char *name ) {
  166. define_t *d;
  167. for ( d = defines; d; d = d->next ) {
  168. if ( !strcmp(d->name, name) ) {
  169. return d;
  170. }
  171. }
  172. return NULL;
  173. }
  174. /*
  175. ================
  176. idParser::FindDefineParm
  177. ================
  178. */
  179. int idParser::FindDefineParm( define_t *define, const char *name ) {
  180. idToken *p;
  181. int i;
  182. i = 0;
  183. for ( p = define->parms; p; p = p->next ) {
  184. if ( (*p) == name ) {
  185. return i;
  186. }
  187. i++;
  188. }
  189. return -1;
  190. }
  191. /*
  192. ================
  193. idParser::CopyDefine
  194. ================
  195. */
  196. define_t *idParser::CopyDefine( define_t *define ) {
  197. define_t *newdefine;
  198. idToken *token, *newtoken, *lasttoken;
  199. newdefine = (define_t *) Mem_Alloc(sizeof(define_t) + strlen(define->name) + 1);
  200. //copy the define name
  201. newdefine->name = (char *) newdefine + sizeof(define_t);
  202. strcpy(newdefine->name, define->name);
  203. newdefine->flags = define->flags;
  204. newdefine->builtin = define->builtin;
  205. newdefine->numparms = define->numparms;
  206. //the define is not linked
  207. newdefine->next = NULL;
  208. newdefine->hashnext = NULL;
  209. //copy the define tokens
  210. newdefine->tokens = NULL;
  211. for (lasttoken = NULL, token = define->tokens; token; token = token->next) {
  212. newtoken = new idToken(token);
  213. newtoken->next = NULL;
  214. if (lasttoken) lasttoken->next = newtoken;
  215. else newdefine->tokens = newtoken;
  216. lasttoken = newtoken;
  217. }
  218. //copy the define parameters
  219. newdefine->parms = NULL;
  220. for (lasttoken = NULL, token = define->parms; token; token = token->next) {
  221. newtoken = new idToken(token);
  222. newtoken->next = NULL;
  223. if (lasttoken) lasttoken->next = newtoken;
  224. else newdefine->parms = newtoken;
  225. lasttoken = newtoken;
  226. }
  227. return newdefine;
  228. }
  229. /*
  230. ================
  231. idParser::FreeDefine
  232. ================
  233. */
  234. void idParser::FreeDefine( define_t *define ) {
  235. idToken *t, *next;
  236. //free the define parameters
  237. for (t = define->parms; t; t = next) {
  238. next = t->next;
  239. delete t;
  240. }
  241. //free the define tokens
  242. for (t = define->tokens; t; t = next) {
  243. next = t->next;
  244. delete t;
  245. }
  246. //free the define
  247. Mem_Free( define );
  248. }
  249. /*
  250. ================
  251. idParser::DefineFromString
  252. ================
  253. */
  254. define_t *idParser::DefineFromString( const char *string ) {
  255. idParser src;
  256. define_t *def;
  257. if ( !src.LoadMemory(string, strlen(string), "*defineString") ) {
  258. return NULL;
  259. }
  260. // create a define from the source
  261. if ( !src.Directive_define() ) {
  262. src.FreeSource();
  263. return NULL;
  264. }
  265. def = src.CopyFirstDefine();
  266. src.FreeSource();
  267. //if the define was created succesfully
  268. return def;
  269. }
  270. /*
  271. ================
  272. idParser::Error
  273. ================
  274. */
  275. void idParser::Error( const char *str, ... ) const {
  276. char text[MAX_STRING_CHARS];
  277. va_list ap;
  278. va_start(ap, str);
  279. vsprintf(text, str, ap);
  280. va_end(ap);
  281. if ( idParser::scriptstack ) {
  282. idParser::scriptstack->Error( text );
  283. }
  284. }
  285. /*
  286. ================
  287. idParser::Warning
  288. ================
  289. */
  290. void idParser::Warning( const char *str, ... ) const {
  291. char text[MAX_STRING_CHARS];
  292. va_list ap;
  293. va_start(ap, str);
  294. vsprintf(text, str, ap);
  295. va_end(ap);
  296. if ( idParser::scriptstack ) {
  297. idParser::scriptstack->Warning( text );
  298. }
  299. }
  300. /*
  301. ================
  302. idParser::PushIndent
  303. ================
  304. */
  305. void idParser::PushIndent( int type, int skip ) {
  306. indent_t *indent;
  307. indent = (indent_t *) Mem_Alloc(sizeof(indent_t));
  308. indent->type = type;
  309. indent->script = idParser::scriptstack;
  310. indent->skip = (skip != 0);
  311. idParser::skip += indent->skip;
  312. indent->next = idParser::indentstack;
  313. idParser::indentstack = indent;
  314. }
  315. /*
  316. ================
  317. idParser::PopIndent
  318. ================
  319. */
  320. void idParser::PopIndent( int *type, int *skip ) {
  321. indent_t *indent;
  322. *type = 0;
  323. *skip = 0;
  324. indent = idParser::indentstack;
  325. if (!indent) return;
  326. // must be an indent from the current script
  327. if (idParser::indentstack->script != idParser::scriptstack) {
  328. return;
  329. }
  330. *type = indent->type;
  331. *skip = indent->skip;
  332. idParser::indentstack = idParser::indentstack->next;
  333. idParser::skip -= indent->skip;
  334. Mem_Free( indent );
  335. }
  336. /*
  337. ================
  338. idParser::PushScript
  339. ================
  340. */
  341. void idParser::PushScript( idLexer *script ) {
  342. idLexer *s;
  343. for ( s = idParser::scriptstack; s; s = s->next ) {
  344. if ( !idStr::Icmp(s->GetFileName(), script->GetFileName()) ) {
  345. idParser::Warning( "'%s' recursively included", script->GetFileName() );
  346. return;
  347. }
  348. }
  349. //push the script on the script stack
  350. script->next = idParser::scriptstack;
  351. idParser::scriptstack = script;
  352. }
  353. /*
  354. ================
  355. idParser::ReadSourceToken
  356. ================
  357. */
  358. int idParser::ReadSourceToken( idToken *token ) {
  359. idToken *t;
  360. idLexer *script;
  361. int type, skip, changedScript;
  362. if ( !idParser::scriptstack ) {
  363. idLib::common->FatalError( "idParser::ReadSourceToken: not loaded" );
  364. return false;
  365. }
  366. changedScript = 0;
  367. // if there's no token already available
  368. while( !idParser::tokens ) {
  369. // if there's a token to read from the script
  370. if ( idParser::scriptstack->ReadToken( token ) ) {
  371. token->linesCrossed += changedScript;
  372. // set the marker based on the start of the token read in
  373. if ( !marker_p ) {
  374. marker_p = token->whiteSpaceEnd_p;
  375. }
  376. return true;
  377. }
  378. // if at the end of the script
  379. if ( idParser::scriptstack->EndOfFile() ) {
  380. // remove all indents of the script
  381. while( idParser::indentstack && idParser::indentstack->script == idParser::scriptstack ) {
  382. idParser::Warning( "missing #endif" );
  383. idParser::PopIndent( &type, &skip );
  384. }
  385. changedScript = 1;
  386. }
  387. // if this was the initial script
  388. if ( !idParser::scriptstack->next ) {
  389. return false;
  390. }
  391. // remove the script and return to the previous one
  392. script = idParser::scriptstack;
  393. idParser::scriptstack = idParser::scriptstack->next;
  394. delete script;
  395. }
  396. // copy the already available token
  397. *token = idParser::tokens;
  398. // remove the token from the source
  399. t = idParser::tokens;
  400. idParser::tokens = idParser::tokens->next;
  401. delete t;
  402. return true;
  403. }
  404. /*
  405. ================
  406. idParser::UnreadSourceToken
  407. ================
  408. */
  409. int idParser::UnreadSourceToken( idToken *token ) {
  410. idToken *t;
  411. t = new idToken(token);
  412. t->next = idParser::tokens;
  413. idParser::tokens = t;
  414. return true;
  415. }
  416. /*
  417. ================
  418. idParser::ReadDefineParms
  419. ================
  420. */
  421. int idParser::ReadDefineParms( define_t *define, idToken **parms, int maxparms ) {
  422. define_t *newdefine;
  423. idToken token, *t, *last;
  424. int i, done, lastcomma, numparms, indent;
  425. if ( !idParser::ReadSourceToken( &token ) ) {
  426. idParser::Error( "define '%s' missing parameters", define->name );
  427. return false;
  428. }
  429. if ( define->numparms > maxparms ) {
  430. idParser::Error( "define with more than %d parameters", maxparms );
  431. return false;
  432. }
  433. for ( i = 0; i < define->numparms; i++ ) {
  434. parms[i] = NULL;
  435. }
  436. // if no leading "("
  437. if ( token != "(" ) {
  438. idParser::UnreadSourceToken( &token );
  439. idParser::Error( "define '%s' missing parameters", define->name );
  440. return false;
  441. }
  442. // read the define parameters
  443. for ( done = 0, numparms = 0, indent = 1; !done; ) {
  444. if ( numparms >= maxparms ) {
  445. idParser::Error( "define '%s' with too many parameters", define->name );
  446. return false;
  447. }
  448. parms[numparms] = NULL;
  449. lastcomma = 1;
  450. last = NULL;
  451. while( !done ) {
  452. if ( !idParser::ReadSourceToken( &token ) ) {
  453. idParser::Error( "define '%s' incomplete", define->name );
  454. return false;
  455. }
  456. if ( token == "," ) {
  457. if ( indent <= 1 ) {
  458. if ( lastcomma ) {
  459. idParser::Warning( "too many comma's" );
  460. }
  461. if ( numparms >= define->numparms ) {
  462. idParser::Warning( "too many define parameters" );
  463. }
  464. lastcomma = 1;
  465. break;
  466. }
  467. }
  468. else if ( token == "(" ) {
  469. indent++;
  470. }
  471. else if ( token == ")" ) {
  472. indent--;
  473. if ( indent <= 0 ) {
  474. if ( !parms[define->numparms-1] ) {
  475. idParser::Warning( "too few define parameters" );
  476. }
  477. done = 1;
  478. break;
  479. }
  480. }
  481. else if ( token.type == TT_NAME ) {
  482. newdefine = FindHashedDefine( idParser::definehash, token.c_str() );
  483. if ( newdefine ) {
  484. if ( !idParser::ExpandDefineIntoSource( &token, newdefine ) ) {
  485. return false;
  486. }
  487. continue;
  488. }
  489. }
  490. lastcomma = 0;
  491. if ( numparms < define->numparms ) {
  492. t = new idToken( token );
  493. t->next = NULL;
  494. if (last) last->next = t;
  495. else parms[numparms] = t;
  496. last = t;
  497. }
  498. }
  499. numparms++;
  500. }
  501. return true;
  502. }
  503. /*
  504. ================
  505. idParser::StringizeTokens
  506. ================
  507. */
  508. int idParser::StringizeTokens( idToken *tokens, idToken *token ) {
  509. idToken *t;
  510. token->type = TT_STRING;
  511. token->whiteSpaceStart_p = NULL;
  512. token->whiteSpaceEnd_p = NULL;
  513. (*token) = "";
  514. for ( t = tokens; t; t = t->next ) {
  515. token->Append( t->c_str() );
  516. }
  517. return true;
  518. }
  519. /*
  520. ================
  521. idParser::MergeTokens
  522. ================
  523. */
  524. int idParser::MergeTokens( idToken *t1, idToken *t2 ) {
  525. // merging of a name with a name or number
  526. if ( t1->type == TT_NAME && (t2->type == TT_NAME || (t2->type == TT_NUMBER && !(t2->subtype & TT_FLOAT))) ) {
  527. t1->Append( t2->c_str() );
  528. return true;
  529. }
  530. // merging of two strings
  531. if (t1->type == TT_STRING && t2->type == TT_STRING) {
  532. t1->Append( t2->c_str() );
  533. return true;
  534. }
  535. // merging of two numbers
  536. if ( t1->type == TT_NUMBER && t2->type == TT_NUMBER &&
  537. !(t1->subtype & (TT_HEX|TT_BINARY)) && !(t2->subtype & (TT_HEX|TT_BINARY)) &&
  538. (!(t1->subtype & TT_FLOAT) || !(t2->subtype & TT_FLOAT)) ) {
  539. t1->Append( t2->c_str() );
  540. return true;
  541. }
  542. return false;
  543. }
  544. /*
  545. ================
  546. idParser::AddBuiltinDefines
  547. ================
  548. */
  549. void idParser::AddBuiltinDefines( void ) {
  550. int i;
  551. define_t *define;
  552. struct builtin
  553. {
  554. char *string;
  555. int id;
  556. } builtin[] = {
  557. { "__LINE__", BUILTIN_LINE },
  558. { "__FILE__", BUILTIN_FILE },
  559. { "__DATE__", BUILTIN_DATE },
  560. { "__TIME__", BUILTIN_TIME },
  561. { "__STDC__", BUILTIN_STDC },
  562. { NULL, 0 }
  563. };
  564. for (i = 0; builtin[i].string; i++) {
  565. define = (define_t *) Mem_Alloc(sizeof(define_t) + strlen(builtin[i].string) + 1);
  566. define->name = (char *) define + sizeof(define_t);
  567. strcpy(define->name, builtin[i].string);
  568. define->flags = DEFINE_FIXED;
  569. define->builtin = builtin[i].id;
  570. define->numparms = 0;
  571. define->parms = NULL;
  572. define->tokens = NULL;
  573. // add the define to the source
  574. AddDefineToHash(define, idParser::definehash);
  575. }
  576. }
  577. /*
  578. ================
  579. idParser::CopyFirstDefine
  580. ================
  581. */
  582. define_t *idParser::CopyFirstDefine( void ) {
  583. int i;
  584. for ( i = 0; i < DEFINEHASHSIZE; i++ ) {
  585. if ( idParser::definehash[i] ) {
  586. return CopyDefine(idParser::definehash[i]);
  587. }
  588. }
  589. return NULL;
  590. }
  591. /*
  592. ================
  593. idParser::ExpandBuiltinDefine
  594. ================
  595. */
  596. int idParser::ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ) {
  597. idToken *token;
  598. ID_TIME_T t;
  599. char *curtime;
  600. char buf[MAX_STRING_CHARS];
  601. token = new idToken(deftoken);
  602. switch( define->builtin ) {
  603. case BUILTIN_LINE: {
  604. sprintf( buf, "%d", deftoken->line );
  605. (*token) = buf;
  606. token->intvalue = deftoken->line;
  607. token->floatvalue = deftoken->line;
  608. token->type = TT_NUMBER;
  609. token->subtype = TT_DECIMAL | TT_INTEGER | TT_VALUESVALID;
  610. token->line = deftoken->line;
  611. token->linesCrossed = deftoken->linesCrossed;
  612. token->flags = 0;
  613. *firsttoken = token;
  614. *lasttoken = token;
  615. break;
  616. }
  617. case BUILTIN_FILE: {
  618. (*token) = idParser::scriptstack->GetFileName();
  619. token->type = TT_NAME;
  620. token->subtype = token->Length();
  621. token->line = deftoken->line;
  622. token->linesCrossed = deftoken->linesCrossed;
  623. token->flags = 0;
  624. *firsttoken = token;
  625. *lasttoken = token;
  626. break;
  627. }
  628. case BUILTIN_DATE: {
  629. t = time(NULL);
  630. curtime = ctime(&t);
  631. (*token) = "\"";
  632. token->Append( curtime+4 );
  633. token[7] = '\0';
  634. token->Append( curtime+20 );
  635. token[10] = '\0';
  636. token->Append( "\"" );
  637. free(curtime);
  638. token->type = TT_STRING;
  639. token->subtype = token->Length();
  640. token->line = deftoken->line;
  641. token->linesCrossed = deftoken->linesCrossed;
  642. token->flags = 0;
  643. *firsttoken = token;
  644. *lasttoken = token;
  645. break;
  646. }
  647. case BUILTIN_TIME: {
  648. t = time(NULL);
  649. curtime = ctime(&t);
  650. (*token) = "\"";
  651. token->Append( curtime+11 );
  652. token[8] = '\0';
  653. token->Append( "\"" );
  654. free(curtime);
  655. token->type = TT_STRING;
  656. token->subtype = token->Length();
  657. token->line = deftoken->line;
  658. token->linesCrossed = deftoken->linesCrossed;
  659. token->flags = 0;
  660. *firsttoken = token;
  661. *lasttoken = token;
  662. break;
  663. }
  664. case BUILTIN_STDC: {
  665. idParser::Warning( "__STDC__ not supported\n" );
  666. *firsttoken = NULL;
  667. *lasttoken = NULL;
  668. break;
  669. }
  670. default: {
  671. *firsttoken = NULL;
  672. *lasttoken = NULL;
  673. break;
  674. }
  675. }
  676. return true;
  677. }
  678. /*
  679. ================
  680. idParser::ExpandDefine
  681. ================
  682. */
  683. int idParser::ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ) {
  684. idToken *parms[MAX_DEFINEPARMS], *dt, *pt, *t;
  685. idToken *t1, *t2, *first, *last, *nextpt, token;
  686. int parmnum, i;
  687. // if it is a builtin define
  688. if ( define->builtin ) {
  689. return idParser::ExpandBuiltinDefine( deftoken, define, firsttoken, lasttoken );
  690. }
  691. // if the define has parameters
  692. if ( define->numparms ) {
  693. if ( !idParser::ReadDefineParms( define, parms, MAX_DEFINEPARMS ) ) {
  694. return false;
  695. }
  696. #ifdef DEBUG_EVAL
  697. for ( i = 0; i < define->numparms; i++ ) {
  698. Log_Write("define parms %d:", i);
  699. for ( pt = parms[i]; pt; pt = pt->next ) {
  700. Log_Write( "%s", pt->c_str() );
  701. }
  702. }
  703. #endif //DEBUG_EVAL
  704. }
  705. // empty list at first
  706. first = NULL;
  707. last = NULL;
  708. // create a list with tokens of the expanded define
  709. for ( dt = define->tokens; dt; dt = dt->next ) {
  710. parmnum = -1;
  711. // if the token is a name, it could be a define parameter
  712. if ( dt->type == TT_NAME ) {
  713. parmnum = FindDefineParm( define, dt->c_str() );
  714. }
  715. // if it is a define parameter
  716. if ( parmnum >= 0 ) {
  717. for ( pt = parms[parmnum]; pt; pt = pt->next ) {
  718. t = new idToken(pt);
  719. //add the token to the list
  720. t->next = NULL;
  721. if (last) last->next = t;
  722. else first = t;
  723. last = t;
  724. }
  725. }
  726. else {
  727. // if stringizing operator
  728. if ( (*dt) == "#" ) {
  729. // the stringizing operator must be followed by a define parameter
  730. if ( dt->next ) {
  731. parmnum = FindDefineParm( define, dt->next->c_str() );
  732. }
  733. else {
  734. parmnum = -1;
  735. }
  736. if ( parmnum >= 0 ) {
  737. // step over the stringizing operator
  738. dt = dt->next;
  739. // stringize the define parameter tokens
  740. if ( !idParser::StringizeTokens( parms[parmnum], &token ) ) {
  741. idParser::Error( "can't stringize tokens" );
  742. return false;
  743. }
  744. t = new idToken(token);
  745. t->line = deftoken->line;
  746. }
  747. else {
  748. idParser::Warning( "stringizing operator without define parameter" );
  749. continue;
  750. }
  751. }
  752. else {
  753. t = new idToken(dt);
  754. t->line = deftoken->line;
  755. }
  756. // add the token to the list
  757. t->next = NULL;
  758. // the token being read from the define list should use the line number of
  759. // the original file, not the header file
  760. t->line = deftoken->line;
  761. if ( last ) last->next = t;
  762. else first = t;
  763. last = t;
  764. }
  765. }
  766. // check for the merging operator
  767. for ( t = first; t; ) {
  768. if ( t->next ) {
  769. // if the merging operator
  770. if ( (*t->next) == "##" ) {
  771. t1 = t;
  772. t2 = t->next->next;
  773. if ( t2 ) {
  774. if ( !idParser::MergeTokens( t1, t2 ) ) {
  775. idParser::Error( "can't merge '%s' with '%s'", t1->c_str(), t2->c_str() );
  776. return false;
  777. }
  778. delete t1->next;
  779. t1->next = t2->next;
  780. if ( t2 == last ) last = t1;
  781. delete t2;
  782. continue;
  783. }
  784. }
  785. }
  786. t = t->next;
  787. }
  788. // store the first and last token of the list
  789. *firsttoken = first;
  790. *lasttoken = last;
  791. // free all the parameter tokens
  792. for ( i = 0; i < define->numparms; i++ ) {
  793. for ( pt = parms[i]; pt; pt = nextpt ) {
  794. nextpt = pt->next;
  795. delete pt;
  796. }
  797. }
  798. return true;
  799. }
  800. /*
  801. ================
  802. idParser::ExpandDefineIntoSource
  803. ================
  804. */
  805. int idParser::ExpandDefineIntoSource( idToken *deftoken, define_t *define ) {
  806. idToken *firsttoken, *lasttoken;
  807. if ( !idParser::ExpandDefine( deftoken, define, &firsttoken, &lasttoken ) ) {
  808. return false;
  809. }
  810. // if the define is not empty
  811. if ( firsttoken && lasttoken ) {
  812. firsttoken->linesCrossed += deftoken->linesCrossed;
  813. lasttoken->next = idParser::tokens;
  814. idParser::tokens = firsttoken;
  815. }
  816. return true;
  817. }
  818. /*
  819. ================
  820. idParser::ReadLine
  821. reads a token from the current line, continues reading on the next
  822. line only if a backslash '\' is found
  823. ================
  824. */
  825. int idParser::ReadLine( idToken *token ) {
  826. int crossline;
  827. crossline = 0;
  828. do {
  829. if (!idParser::ReadSourceToken( token )) {
  830. return false;
  831. }
  832. if (token->linesCrossed > crossline) {
  833. idParser::UnreadSourceToken( token );
  834. return false;
  835. }
  836. crossline = 1;
  837. } while( (*token) == "\\" );
  838. return true;
  839. }
  840. /*
  841. ================
  842. idParser::Directive_include
  843. ================
  844. */
  845. int idParser::Directive_include( void ) {
  846. idLexer *script;
  847. idToken token;
  848. idStr path;
  849. if ( !idParser::ReadSourceToken( &token ) ) {
  850. idParser::Error( "#include without file name" );
  851. return false;
  852. }
  853. if ( token.linesCrossed > 0 ) {
  854. idParser::Error( "#include without file name" );
  855. return false;
  856. }
  857. if ( token.type == TT_STRING ) {
  858. script = new idLexer;
  859. // try relative to the current file
  860. path = scriptstack->GetFileName();
  861. path.StripFilename();
  862. path += "/";
  863. path += token;
  864. if ( !script->LoadFile( path, OSPath ) ) {
  865. // try absolute path
  866. path = token;
  867. if ( !script->LoadFile( path, OSPath ) ) {
  868. // try from the include path
  869. path = includepath + token;
  870. if ( !script->LoadFile( path, OSPath ) ) {
  871. delete script;
  872. script = NULL;
  873. }
  874. }
  875. }
  876. }
  877. else if ( token.type == TT_PUNCTUATION && token == "<" ) {
  878. path = idParser::includepath;
  879. while( idParser::ReadSourceToken( &token ) ) {
  880. if ( token.linesCrossed > 0 ) {
  881. idParser::UnreadSourceToken( &token );
  882. break;
  883. }
  884. if ( token.type == TT_PUNCTUATION && token == ">" ) {
  885. break;
  886. }
  887. path += token;
  888. }
  889. if ( token != ">" ) {
  890. idParser::Warning( "#include missing trailing >" );
  891. }
  892. if ( !path.Length() ) {
  893. idParser::Error( "#include without file name between < >" );
  894. return false;
  895. }
  896. if ( idParser::flags & LEXFL_NOBASEINCLUDES ) {
  897. return true;
  898. }
  899. script = new idLexer;
  900. if ( !script->LoadFile( includepath + path, OSPath ) ) {
  901. delete script;
  902. script = NULL;
  903. }
  904. }
  905. else {
  906. idParser::Error( "#include without file name" );
  907. return false;
  908. }
  909. if (!script) {
  910. idParser::Error( "file '%s' not found", path.c_str() );
  911. return false;
  912. }
  913. script->SetFlags( idParser::flags );
  914. script->SetPunctuations( idParser::punctuations );
  915. idParser::PushScript( script );
  916. return true;
  917. }
  918. /*
  919. ================
  920. idParser::Directive_undef
  921. ================
  922. */
  923. int idParser::Directive_undef( void ) {
  924. idToken token;
  925. define_t *define, *lastdefine;
  926. int hash;
  927. //
  928. if (!idParser::ReadLine( &token )) {
  929. idParser::Error( "undef without name" );
  930. return false;
  931. }
  932. if (token.type != TT_NAME) {
  933. idParser::UnreadSourceToken( &token );
  934. idParser::Error( "expected name but found '%s'", token.c_str() );
  935. return false;
  936. }
  937. hash = PC_NameHash( token.c_str() );
  938. for (lastdefine = NULL, define = idParser::definehash[hash]; define; define = define->hashnext) {
  939. if (!strcmp(define->name, token.c_str()))
  940. {
  941. if (define->flags & DEFINE_FIXED) {
  942. idParser::Warning( "can't undef '%s'", token.c_str() );
  943. }
  944. else {
  945. if (lastdefine) {
  946. lastdefine->hashnext = define->hashnext;
  947. }
  948. else {
  949. idParser::definehash[hash] = define->hashnext;
  950. }
  951. FreeDefine(define);
  952. }
  953. break;
  954. }
  955. lastdefine = define;
  956. }
  957. return true;
  958. }
  959. /*
  960. ================
  961. idParser::Directive_define
  962. ================
  963. */
  964. int idParser::Directive_define( void ) {
  965. idToken token, *t, *last;
  966. define_t *define;
  967. if (!idParser::ReadLine( &token )) {
  968. idParser::Error( "#define without name" );
  969. return false;
  970. }
  971. if (token.type != TT_NAME) {
  972. idParser::UnreadSourceToken( &token );
  973. idParser::Error( "expected name after #define, found '%s'", token.c_str() );
  974. return false;
  975. }
  976. // check if the define already exists
  977. define = FindHashedDefine(idParser::definehash, token.c_str());
  978. if (define) {
  979. if (define->flags & DEFINE_FIXED) {
  980. idParser::Error( "can't redefine '%s'", token.c_str() );
  981. return false;
  982. }
  983. idParser::Warning( "redefinition of '%s'", token.c_str() );
  984. // unread the define name before executing the #undef directive
  985. idParser::UnreadSourceToken( &token );
  986. if (!idParser::Directive_undef())
  987. return false;
  988. // if the define was not removed (define->flags & DEFINE_FIXED)
  989. define = FindHashedDefine(idParser::definehash, token.c_str());
  990. }
  991. // allocate define
  992. define = (define_t *) Mem_ClearedAlloc(sizeof(define_t) + token.Length() + 1);
  993. define->name = (char *) define + sizeof(define_t);
  994. strcpy(define->name, token.c_str());
  995. // add the define to the source
  996. AddDefineToHash(define, idParser::definehash);
  997. // if nothing is defined, just return
  998. if ( !idParser::ReadLine( &token ) ) {
  999. return true;
  1000. }
  1001. // if it is a define with parameters
  1002. if ( token.WhiteSpaceBeforeToken() == 0 && token == "(" ) {
  1003. // read the define parameters
  1004. last = NULL;
  1005. if ( !idParser::CheckTokenString(")") ) {
  1006. while(1) {
  1007. if ( !idParser::ReadLine( &token ) ) {
  1008. idParser::Error( "expected define parameter" );
  1009. return false;
  1010. }
  1011. // if it isn't a name
  1012. if (token.type != TT_NAME) {
  1013. idParser::Error( "invalid define parameter" );
  1014. return false;
  1015. }
  1016. if (FindDefineParm(define, token.c_str()) >= 0) {
  1017. idParser::Error( "two the same define parameters" );
  1018. return false;
  1019. }
  1020. // add the define parm
  1021. t = new idToken(token);
  1022. t->ClearTokenWhiteSpace();
  1023. t->next = NULL;
  1024. if (last) last->next = t;
  1025. else define->parms = t;
  1026. last = t;
  1027. define->numparms++;
  1028. // read next token
  1029. if (!idParser::ReadLine( &token )) {
  1030. idParser::Error( "define parameters not terminated" );
  1031. return false;
  1032. }
  1033. if ( token == ")" ) {
  1034. break;
  1035. }
  1036. // then it must be a comma
  1037. if ( token != "," ) {
  1038. idParser::Error( "define not terminated" );
  1039. return false;
  1040. }
  1041. }
  1042. }
  1043. if ( !idParser::ReadLine( &token ) ) {
  1044. return true;
  1045. }
  1046. }
  1047. // read the defined stuff
  1048. last = NULL;
  1049. do
  1050. {
  1051. t = new idToken(token);
  1052. if ( t->type == TT_NAME && !strcmp( t->c_str(), define->name ) ) {
  1053. t->flags |= TOKEN_FL_RECURSIVE_DEFINE;
  1054. idParser::Warning( "recursive define (removed recursion)" );
  1055. }
  1056. t->ClearTokenWhiteSpace();
  1057. t->next = NULL;
  1058. if ( last ) last->next = t;
  1059. else define->tokens = t;
  1060. last = t;
  1061. } while( idParser::ReadLine( &token ) );
  1062. if ( last ) {
  1063. // check for merge operators at the beginning or end
  1064. if ( (*define->tokens) == "##" || (*last) == "##" ) {
  1065. idParser::Error( "define with misplaced ##" );
  1066. return false;
  1067. }
  1068. }
  1069. return true;
  1070. }
  1071. /*
  1072. ================
  1073. idParser::AddDefine
  1074. ================
  1075. */
  1076. int idParser::AddDefine( const char *string ) {
  1077. define_t *define;
  1078. define = DefineFromString( string );
  1079. if (!define) {
  1080. return false;
  1081. }
  1082. AddDefineToHash(define, idParser::definehash);
  1083. return true;
  1084. }
  1085. /*
  1086. ================
  1087. idParser::AddGlobalDefinesToSource
  1088. ================
  1089. */
  1090. void idParser::AddGlobalDefinesToSource( void ) {
  1091. define_t *define, *newdefine;
  1092. for (define = globaldefines; define; define = define->next) {
  1093. newdefine = CopyDefine( define );
  1094. AddDefineToHash(newdefine, idParser::definehash);
  1095. }
  1096. }
  1097. /*
  1098. ================
  1099. idParser::Directive_if_def
  1100. ================
  1101. */
  1102. int idParser::Directive_if_def( int type ) {
  1103. idToken token;
  1104. define_t *d;
  1105. int skip;
  1106. if ( !idParser::ReadLine( &token ) ) {
  1107. idParser::Error( "#ifdef without name" );
  1108. return false;
  1109. }
  1110. if (token.type != TT_NAME) {
  1111. idParser::UnreadSourceToken( &token );
  1112. idParser::Error( "expected name after #ifdef, found '%s'", token.c_str() );
  1113. return false;
  1114. }
  1115. d = FindHashedDefine(idParser::definehash, token.c_str());
  1116. skip = (type == INDENT_IFDEF) == (d == NULL);
  1117. idParser::PushIndent( type, skip );
  1118. return true;
  1119. }
  1120. /*
  1121. ================
  1122. idParser::Directive_ifdef
  1123. ================
  1124. */
  1125. int idParser::Directive_ifdef( void ) {
  1126. return idParser::Directive_if_def( INDENT_IFDEF );
  1127. }
  1128. /*
  1129. ================
  1130. idParser::Directive_ifndef
  1131. ================
  1132. */
  1133. int idParser::Directive_ifndef( void ) {
  1134. return idParser::Directive_if_def( INDENT_IFNDEF );
  1135. }
  1136. /*
  1137. ================
  1138. idParser::Directive_else
  1139. ================
  1140. */
  1141. int idParser::Directive_else( void ) {
  1142. int type, skip;
  1143. idParser::PopIndent( &type, &skip );
  1144. if (!type) {
  1145. idParser::Error( "misplaced #else" );
  1146. return false;
  1147. }
  1148. if (type == INDENT_ELSE) {
  1149. idParser::Error( "#else after #else" );
  1150. return false;
  1151. }
  1152. idParser::PushIndent( INDENT_ELSE, !skip );
  1153. return true;
  1154. }
  1155. /*
  1156. ================
  1157. idParser::Directive_endif
  1158. ================
  1159. */
  1160. int idParser::Directive_endif( void ) {
  1161. int type, skip;
  1162. idParser::PopIndent( &type, &skip );
  1163. if (!type) {
  1164. idParser::Error( "misplaced #endif" );
  1165. return false;
  1166. }
  1167. return true;
  1168. }
  1169. /*
  1170. ================
  1171. idParser::EvaluateTokens
  1172. ================
  1173. */
  1174. typedef struct operator_s
  1175. {
  1176. int op;
  1177. int priority;
  1178. int parentheses;
  1179. struct operator_s *prev, *next;
  1180. } operator_t;
  1181. typedef struct value_s
  1182. {
  1183. signed long int intvalue;
  1184. double floatvalue;
  1185. int parentheses;
  1186. struct value_s *prev, *next;
  1187. } value_t;
  1188. int PC_OperatorPriority(int op) {
  1189. switch(op) {
  1190. case P_MUL: return 15;
  1191. case P_DIV: return 15;
  1192. case P_MOD: return 15;
  1193. case P_ADD: return 14;
  1194. case P_SUB: return 14;
  1195. case P_LOGIC_AND: return 7;
  1196. case P_LOGIC_OR: return 6;
  1197. case P_LOGIC_GEQ: return 12;
  1198. case P_LOGIC_LEQ: return 12;
  1199. case P_LOGIC_EQ: return 11;
  1200. case P_LOGIC_UNEQ: return 11;
  1201. case P_LOGIC_NOT: return 16;
  1202. case P_LOGIC_GREATER: return 12;
  1203. case P_LOGIC_LESS: return 12;
  1204. case P_RSHIFT: return 13;
  1205. case P_LSHIFT: return 13;
  1206. case P_BIN_AND: return 10;
  1207. case P_BIN_OR: return 8;
  1208. case P_BIN_XOR: return 9;
  1209. case P_BIN_NOT: return 16;
  1210. case P_COLON: return 5;
  1211. case P_QUESTIONMARK: return 5;
  1212. }
  1213. return false;
  1214. }
  1215. //#define AllocValue() GetClearedMemory(sizeof(value_t));
  1216. //#define FreeValue(val) FreeMemory(val)
  1217. //#define AllocOperator(op) op = (operator_t *) GetClearedMemory(sizeof(operator_t));
  1218. //#define FreeOperator(op) FreeMemory(op);
  1219. #define MAX_VALUES 64
  1220. #define MAX_OPERATORS 64
  1221. #define AllocValue(val) \
  1222. if ( numvalues >= MAX_VALUES ) { \
  1223. idParser::Error( "out of value space\n" ); \
  1224. error = 1; \
  1225. break; \
  1226. } \
  1227. else { \
  1228. val = &value_heap[numvalues++]; \
  1229. }
  1230. #define FreeValue(val)
  1231. #define AllocOperator(op) \
  1232. if ( numoperators >= MAX_OPERATORS ) { \
  1233. idParser::Error( "out of operator space\n" ); \
  1234. error = 1; \
  1235. break; \
  1236. } \
  1237. else { \
  1238. op = &operator_heap[numoperators++]; \
  1239. }
  1240. #define FreeOperator(op)
  1241. int idParser::EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer ) {
  1242. operator_t *o, *firstoperator, *lastoperator;
  1243. value_t *v, *firstvalue, *lastvalue, *v1, *v2;
  1244. idToken *t;
  1245. int brace = 0;
  1246. int parentheses = 0;
  1247. int error = 0;
  1248. int lastwasvalue = 0;
  1249. int negativevalue = 0;
  1250. int questmarkintvalue = 0;
  1251. double questmarkfloatvalue = 0;
  1252. int gotquestmarkvalue = false;
  1253. int lastoperatortype = 0;
  1254. //
  1255. operator_t operator_heap[MAX_OPERATORS];
  1256. int numoperators = 0;
  1257. value_t value_heap[MAX_VALUES];
  1258. int numvalues = 0;
  1259. firstoperator = lastoperator = NULL;
  1260. firstvalue = lastvalue = NULL;
  1261. if (intvalue) *intvalue = 0;
  1262. if (floatvalue) *floatvalue = 0;
  1263. for ( t = tokens; t; t = t->next ) {
  1264. switch( t->type ) {
  1265. case TT_NAME:
  1266. {
  1267. if ( lastwasvalue || negativevalue ) {
  1268. idParser::Error( "syntax error in #if/#elif" );
  1269. error = 1;
  1270. break;
  1271. }
  1272. if ( (*t) != "defined" ) {
  1273. idParser::Error( "undefined name '%s' in #if/#elif", t->c_str() );
  1274. error = 1;
  1275. break;
  1276. }
  1277. t = t->next;
  1278. if ( (*t) == "(" ) {
  1279. brace = true;
  1280. t = t->next;
  1281. }
  1282. if (!t || t->type != TT_NAME) {
  1283. idParser::Error( "defined() without name in #if/#elif" );
  1284. error = 1;
  1285. break;
  1286. }
  1287. //v = (value_t *) GetClearedMemory(sizeof(value_t));
  1288. AllocValue(v);
  1289. if (FindHashedDefine(idParser::definehash, t->c_str())) {
  1290. v->intvalue = 1;
  1291. v->floatvalue = 1;
  1292. }
  1293. else {
  1294. v->intvalue = 0;
  1295. v->floatvalue = 0;
  1296. }
  1297. v->parentheses = parentheses;
  1298. v->next = NULL;
  1299. v->prev = lastvalue;
  1300. if (lastvalue) lastvalue->next = v;
  1301. else firstvalue = v;
  1302. lastvalue = v;
  1303. if (brace) {
  1304. t = t->next;
  1305. if (!t || (*t) != ")" ) {
  1306. idParser::Error( "defined missing ) in #if/#elif" );
  1307. error = 1;
  1308. break;
  1309. }
  1310. }
  1311. brace = false;
  1312. // defined() creates a value
  1313. lastwasvalue = 1;
  1314. break;
  1315. }
  1316. case TT_NUMBER:
  1317. {
  1318. if (lastwasvalue) {
  1319. idParser::Error( "syntax error in #if/#elif" );
  1320. error = 1;
  1321. break;
  1322. }
  1323. //v = (value_t *) GetClearedMemory(sizeof(value_t));
  1324. AllocValue(v);
  1325. if (negativevalue) {
  1326. v->intvalue = - t->GetIntValue();
  1327. v->floatvalue = - t->GetFloatValue();
  1328. }
  1329. else {
  1330. v->intvalue = t->GetIntValue();
  1331. v->floatvalue = t->GetFloatValue();
  1332. }
  1333. v->parentheses = parentheses;
  1334. v->next = NULL;
  1335. v->prev = lastvalue;
  1336. if (lastvalue) lastvalue->next = v;
  1337. else firstvalue = v;
  1338. lastvalue = v;
  1339. //last token was a value
  1340. lastwasvalue = 1;
  1341. //
  1342. negativevalue = 0;
  1343. break;
  1344. }
  1345. case TT_PUNCTUATION:
  1346. {
  1347. if (negativevalue) {
  1348. idParser::Error( "misplaced minus sign in #if/#elif" );
  1349. error = 1;
  1350. break;
  1351. }
  1352. if (t->subtype == P_PARENTHESESOPEN) {
  1353. parentheses++;
  1354. break;
  1355. }
  1356. else if (t->subtype == P_PARENTHESESCLOSE) {
  1357. parentheses--;
  1358. if (parentheses < 0) {
  1359. idParser::Error( "too many ) in #if/#elsif" );
  1360. error = 1;
  1361. }
  1362. break;
  1363. }
  1364. //check for invalid operators on floating point values
  1365. if ( !integer ) {
  1366. if (t->subtype == P_BIN_NOT || t->subtype == P_MOD ||
  1367. t->subtype == P_RSHIFT || t->subtype == P_LSHIFT ||
  1368. t->subtype == P_BIN_AND || t->subtype == P_BIN_OR ||
  1369. t->subtype == P_BIN_XOR) {
  1370. idParser::Error( "illigal operator '%s' on floating point operands\n", t->c_str() );
  1371. error = 1;
  1372. break;
  1373. }
  1374. }
  1375. switch( t->subtype ) {
  1376. case P_LOGIC_NOT:
  1377. case P_BIN_NOT:
  1378. {
  1379. if (lastwasvalue) {
  1380. idParser::Error( "! or ~ after value in #if/#elif" );
  1381. error = 1;
  1382. break;
  1383. }
  1384. break;
  1385. }
  1386. case P_INC:
  1387. case P_DEC:
  1388. {
  1389. idParser::Error( "++ or -- used in #if/#elif" );
  1390. break;
  1391. }
  1392. case P_SUB:
  1393. {
  1394. if (!lastwasvalue) {
  1395. negativevalue = 1;
  1396. break;
  1397. }
  1398. }
  1399. case P_MUL:
  1400. case P_DIV:
  1401. case P_MOD:
  1402. case P_ADD:
  1403. case P_LOGIC_AND:
  1404. case P_LOGIC_OR:
  1405. case P_LOGIC_GEQ:
  1406. case P_LOGIC_LEQ:
  1407. case P_LOGIC_EQ:
  1408. case P_LOGIC_UNEQ:
  1409. case P_LOGIC_GREATER:
  1410. case P_LOGIC_LESS:
  1411. case P_RSHIFT:
  1412. case P_LSHIFT:
  1413. case P_BIN_AND:
  1414. case P_BIN_OR:
  1415. case P_BIN_XOR:
  1416. case P_COLON:
  1417. case P_QUESTIONMARK:
  1418. {
  1419. if (!lastwasvalue) {
  1420. idParser::Error( "operator '%s' after operator in #if/#elif", t->c_str() );
  1421. error = 1;
  1422. break;
  1423. }
  1424. break;
  1425. }
  1426. default:
  1427. {
  1428. idParser::Error( "invalid operator '%s' in #if/#elif", t->c_str() );
  1429. error = 1;
  1430. break;
  1431. }
  1432. }
  1433. if (!error && !negativevalue) {
  1434. //o = (operator_t *) GetClearedMemory(sizeof(operator_t));
  1435. AllocOperator(o);
  1436. o->op = t->subtype;
  1437. o->priority = PC_OperatorPriority(t->subtype);
  1438. o->parentheses = parentheses;
  1439. o->next = NULL;
  1440. o->prev = lastoperator;
  1441. if (lastoperator) lastoperator->next = o;
  1442. else firstoperator = o;
  1443. lastoperator = o;
  1444. lastwasvalue = 0;
  1445. }
  1446. break;
  1447. }
  1448. default:
  1449. {
  1450. idParser::Error( "unknown '%s' in #if/#elif", t->c_str() );
  1451. error = 1;
  1452. break;
  1453. }
  1454. }
  1455. if (error) {
  1456. break;
  1457. }
  1458. }
  1459. if (!error) {
  1460. if (!lastwasvalue) {
  1461. idParser::Error( "trailing operator in #if/#elif" );
  1462. error = 1;
  1463. }
  1464. else if (parentheses) {
  1465. idParser::Error( "too many ( in #if/#elif" );
  1466. error = 1;
  1467. }
  1468. }
  1469. //
  1470. gotquestmarkvalue = false;
  1471. questmarkintvalue = 0;
  1472. questmarkfloatvalue = 0;
  1473. //while there are operators
  1474. while( !error && firstoperator ) {
  1475. v = firstvalue;
  1476. for (o = firstoperator; o->next; o = o->next) {
  1477. //if the current operator is nested deeper in parentheses
  1478. //than the next operator
  1479. if (o->parentheses > o->next->parentheses) {
  1480. break;
  1481. }
  1482. //if the current and next operator are nested equally deep in parentheses
  1483. if (o->parentheses == o->next->parentheses) {
  1484. //if the priority of the current operator is equal or higher
  1485. //than the priority of the next operator
  1486. if (o->priority >= o->next->priority) {
  1487. break;
  1488. }
  1489. }
  1490. //if the arity of the operator isn't equal to 1
  1491. if (o->op != P_LOGIC_NOT && o->op != P_BIN_NOT) {
  1492. v = v->next;
  1493. }
  1494. //if there's no value or no next value
  1495. if (!v) {
  1496. idParser::Error( "mising values in #if/#elif" );
  1497. error = 1;
  1498. break;
  1499. }
  1500. }
  1501. if (error) {
  1502. break;
  1503. }
  1504. v1 = v;
  1505. v2 = v->next;
  1506. #ifdef DEBUG_EVAL
  1507. if (integer) {
  1508. Log_Write("operator %s, value1 = %d", idParser::scriptstack->getPunctuationFromId(o->op), v1->intvalue);
  1509. if (v2) Log_Write("value2 = %d", v2->intvalue);
  1510. }
  1511. else {
  1512. Log_Write("operator %s, value1 = %f", idParser::scriptstack->getPunctuationFromId(o->op), v1->floatvalue);
  1513. if (v2) Log_Write("value2 = %f", v2->floatvalue);
  1514. }
  1515. #endif //DEBUG_EVAL
  1516. switch(o->op) {
  1517. case P_LOGIC_NOT: v1->intvalue = !v1->intvalue;
  1518. v1->floatvalue = !v1->floatvalue; break;
  1519. case P_BIN_NOT: v1->intvalue = ~v1->intvalue;
  1520. break;
  1521. case P_MUL: v1->intvalue *= v2->intvalue;
  1522. v1->floatvalue *= v2->floatvalue; break;
  1523. case P_DIV: if (!v2->intvalue || !v2->floatvalue)
  1524. {
  1525. idParser::Error( "divide by zero in #if/#elif\n" );
  1526. error = 1;
  1527. break;
  1528. }
  1529. v1->intvalue /= v2->intvalue;
  1530. v1->floatvalue /= v2->floatvalue; break;
  1531. case P_MOD: if (!v2->intvalue)
  1532. {
  1533. idParser::Error( "divide by zero in #if/#elif\n" );
  1534. error = 1;
  1535. break;
  1536. }
  1537. v1->intvalue %= v2->intvalue; break;
  1538. case P_ADD: v1->intvalue += v2->intvalue;
  1539. v1->floatvalue += v2->floatvalue; break;
  1540. case P_SUB: v1->intvalue -= v2->intvalue;
  1541. v1->floatvalue -= v2->floatvalue; break;
  1542. case P_LOGIC_AND: v1->intvalue = v1->intvalue && v2->intvalue;
  1543. v1->floatvalue = v1->floatvalue && v2->floatvalue; break;
  1544. case P_LOGIC_OR: v1->intvalue = v1->intvalue || v2->intvalue;
  1545. v1->floatvalue = v1->floatvalue || v2->floatvalue; break;
  1546. case P_LOGIC_GEQ: v1->intvalue = v1->intvalue >= v2->intvalue;
  1547. v1->floatvalue = v1->floatvalue >= v2->floatvalue; break;
  1548. case P_LOGIC_LEQ: v1->intvalue = v1->intvalue <= v2->intvalue;
  1549. v1->floatvalue = v1->floatvalue <= v2->floatvalue; break;
  1550. case P_LOGIC_EQ: v1->intvalue = v1->intvalue == v2->intvalue;
  1551. v1->floatvalue = v1->floatvalue == v2->floatvalue; break;
  1552. case P_LOGIC_UNEQ: v1->intvalue = v1->intvalue != v2->intvalue;
  1553. v1->floatvalue = v1->floatvalue != v2->floatvalue; break;
  1554. case P_LOGIC_GREATER: v1->intvalue = v1->intvalue > v2->intvalue;
  1555. v1->floatvalue = v1->floatvalue > v2->floatvalue; break;
  1556. case P_LOGIC_LESS: v1->intvalue = v1->intvalue < v2->intvalue;
  1557. v1->floatvalue = v1->floatvalue < v2->floatvalue; break;
  1558. case P_RSHIFT: v1->intvalue >>= v2->intvalue;
  1559. break;
  1560. case P_LSHIFT: v1->intvalue <<= v2->intvalue;
  1561. break;
  1562. case P_BIN_AND: v1->intvalue &= v2->intvalue;
  1563. break;
  1564. case P_BIN_OR: v1->intvalue |= v2->intvalue;
  1565. break;
  1566. case P_BIN_XOR: v1->intvalue ^= v2->intvalue;
  1567. break;
  1568. case P_COLON:
  1569. {
  1570. if (!gotquestmarkvalue) {
  1571. idParser::Error( ": without ? in #if/#elif" );
  1572. error = 1;
  1573. break;
  1574. }
  1575. if (integer) {
  1576. if (!questmarkintvalue)
  1577. v1->intvalue = v2->intvalue;
  1578. }
  1579. else {
  1580. if (!questmarkfloatvalue)
  1581. v1->floatvalue = v2->floatvalue;
  1582. }
  1583. gotquestmarkvalue = false;
  1584. break;
  1585. }
  1586. case P_QUESTIONMARK:
  1587. {
  1588. if (gotquestmarkvalue) {
  1589. idParser::Error( "? after ? in #if/#elif" );
  1590. error = 1;
  1591. break;
  1592. }
  1593. questmarkintvalue = v1->intvalue;
  1594. questmarkfloatvalue = v1->floatvalue;
  1595. gotquestmarkvalue = true;
  1596. break;
  1597. }
  1598. }
  1599. #ifdef DEBUG_EVAL
  1600. if (integer) Log_Write("result value = %d", v1->intvalue);
  1601. else Log_Write("result value = %f", v1->floatvalue);
  1602. #endif //DEBUG_EVAL
  1603. if (error)
  1604. break;
  1605. lastoperatortype = o->op;
  1606. //if not an operator with arity 1
  1607. if (o->op != P_LOGIC_NOT && o->op != P_BIN_NOT) {
  1608. //remove the second value if not question mark operator
  1609. if (o->op != P_QUESTIONMARK) {
  1610. v = v->next;
  1611. }
  1612. //
  1613. if (v->prev) v->prev->next = v->next;
  1614. else firstvalue = v->next;
  1615. if (v->next) v->next->prev = v->prev;
  1616. else lastvalue = v->prev;
  1617. //FreeMemory(v);
  1618. FreeValue(v);
  1619. }
  1620. //remove the operator
  1621. if (o->prev) o->prev->next = o->next;
  1622. else firstoperator = o->next;
  1623. if (o->next) o->next->prev = o->prev;
  1624. else lastoperator = o->prev;
  1625. //FreeMemory(o);
  1626. FreeOperator(o);
  1627. }
  1628. if (firstvalue) {
  1629. if (intvalue) *intvalue = firstvalue->intvalue;
  1630. if (floatvalue) *floatvalue = firstvalue->floatvalue;
  1631. }
  1632. for (o = firstoperator; o; o = lastoperator) {
  1633. lastoperator = o->next;
  1634. //FreeMemory(o);
  1635. FreeOperator(o);
  1636. }
  1637. for (v = firstvalue; v; v = lastvalue) {
  1638. lastvalue = v->next;
  1639. //FreeMemory(v);
  1640. FreeValue(v);
  1641. }
  1642. if (!error) {
  1643. return true;
  1644. }
  1645. if (intvalue) {
  1646. *intvalue = 0;
  1647. }
  1648. if (floatvalue) {
  1649. *floatvalue = 0;
  1650. }
  1651. return false;
  1652. }
  1653. /*
  1654. ================
  1655. idParser::Evaluate
  1656. ================
  1657. */
  1658. int idParser::Evaluate( signed long int *intvalue, double *floatvalue, int integer ) {
  1659. idToken token, *firsttoken, *lasttoken;
  1660. idToken *t, *nexttoken;
  1661. define_t *define;
  1662. int defined = false;
  1663. if (intvalue) {
  1664. *intvalue = 0;
  1665. }
  1666. if (floatvalue) {
  1667. *floatvalue = 0;
  1668. }
  1669. //
  1670. if ( !idParser::ReadLine( &token ) ) {
  1671. idParser::Error( "no value after #if/#elif" );
  1672. return false;
  1673. }
  1674. firsttoken = NULL;
  1675. lasttoken = NULL;
  1676. do {
  1677. //if the token is a name
  1678. if (token.type == TT_NAME) {
  1679. if (defined) {
  1680. defined = false;
  1681. t = new idToken(token);
  1682. t->next = NULL;
  1683. if (lasttoken) lasttoken->next = t;
  1684. else firsttoken = t;
  1685. lasttoken = t;
  1686. }
  1687. else if ( token == "defined" ) {
  1688. defined = true;
  1689. t = new idToken(token);
  1690. t->next = NULL;
  1691. if (lasttoken) lasttoken->next = t;
  1692. else firsttoken = t;
  1693. lasttoken = t;
  1694. }
  1695. else {
  1696. //then it must be a define
  1697. define = FindHashedDefine(idParser::definehash, token.c_str());
  1698. if (!define) {
  1699. idParser::Error( "can't Evaluate '%s', not defined", token.c_str() );
  1700. return false;
  1701. }
  1702. if ( !idParser::ExpandDefineIntoSource( &token, define ) ) {
  1703. return false;
  1704. }
  1705. }
  1706. }
  1707. //if the token is a number or a punctuation
  1708. else if (token.type == TT_NUMBER || token.type == TT_PUNCTUATION) {
  1709. t = new idToken(token);
  1710. t->next = NULL;
  1711. if (lasttoken) lasttoken->next = t;
  1712. else firsttoken = t;
  1713. lasttoken = t;
  1714. }
  1715. else {
  1716. idParser::Error( "can't Evaluate '%s'", token.c_str() );
  1717. return false;
  1718. }
  1719. } while(idParser::ReadLine( &token ));
  1720. //
  1721. if ( !idParser::EvaluateTokens( firsttoken, intvalue, floatvalue, integer ) ) {
  1722. return false;
  1723. }
  1724. //
  1725. #ifdef DEBUG_EVAL
  1726. Log_Write("eval:");
  1727. #endif //DEBUG_EVAL
  1728. for (t = firsttoken; t; t = nexttoken) {
  1729. #ifdef DEBUG_EVAL
  1730. Log_Write(" %s", t->c_str());
  1731. #endif //DEBUG_EVAL
  1732. nexttoken = t->next;
  1733. delete t;
  1734. } //end for
  1735. #ifdef DEBUG_EVAL
  1736. if (integer) Log_Write("eval result: %d", *intvalue);
  1737. else Log_Write("eval result: %f", *floatvalue);
  1738. #endif //DEBUG_EVAL
  1739. //
  1740. return true;
  1741. }
  1742. /*
  1743. ================
  1744. idParser::DollarEvaluate
  1745. ================
  1746. */
  1747. int idParser::DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer) {
  1748. int indent, defined = false;
  1749. idToken token, *firsttoken, *lasttoken;
  1750. idToken *t, *nexttoken;
  1751. define_t *define;
  1752. if (intvalue) {
  1753. *intvalue = 0;
  1754. }
  1755. if (floatvalue) {
  1756. *floatvalue = 0;
  1757. }
  1758. //
  1759. if ( !idParser::ReadSourceToken( &token ) ) {
  1760. idParser::Error( "no leading ( after $evalint/$evalfloat" );
  1761. return false;
  1762. }
  1763. if ( !idParser::ReadSourceToken( &token ) ) {
  1764. idParser::Error( "nothing to Evaluate" );
  1765. return false;
  1766. }
  1767. indent = 1;
  1768. firsttoken = NULL;
  1769. lasttoken = NULL;
  1770. do {
  1771. //if the token is a name
  1772. if (token.type == TT_NAME) {
  1773. if (defined) {
  1774. defined = false;
  1775. t = new idToken(token);
  1776. t->next = NULL;
  1777. if (lasttoken) lasttoken->next = t;
  1778. else firsttoken = t;
  1779. lasttoken = t;
  1780. }
  1781. else if ( token == "defined" ) {
  1782. defined = true;
  1783. t = new idToken(token);
  1784. t->next = NULL;
  1785. if (lasttoken) lasttoken->next = t;
  1786. else firsttoken = t;
  1787. lasttoken = t;
  1788. }
  1789. else {
  1790. //then it must be a define
  1791. define = FindHashedDefine(idParser::definehash, token.c_str());
  1792. if (!define) {
  1793. idParser::Warning( "can't Evaluate '%s', not defined", token.c_str() );
  1794. return false;
  1795. }
  1796. if ( !idParser::ExpandDefineIntoSource( &token, define ) ) {
  1797. return false;
  1798. }
  1799. }
  1800. }
  1801. //if the token is a number or a punctuation
  1802. else if (token.type == TT_NUMBER || token.type == TT_PUNCTUATION) {
  1803. if ( token[0] == '(' ) indent++;
  1804. else if ( token[0] == ')' ) indent--;
  1805. if (indent <= 0) {
  1806. break;
  1807. }
  1808. t = new idToken(token);
  1809. t->next = NULL;
  1810. if (lasttoken) lasttoken->next = t;
  1811. else firsttoken = t;
  1812. lasttoken = t;
  1813. }
  1814. else {
  1815. idParser::Error( "can't Evaluate '%s'", token.c_str() );
  1816. return false;
  1817. }
  1818. } while(idParser::ReadSourceToken( &token ));
  1819. //
  1820. if (!idParser::EvaluateTokens( firsttoken, intvalue, floatvalue, integer)) {
  1821. return false;
  1822. }
  1823. //
  1824. #ifdef DEBUG_EVAL
  1825. Log_Write("$eval:");
  1826. #endif //DEBUG_EVAL
  1827. for (t = firsttoken; t; t = nexttoken) {
  1828. #ifdef DEBUG_EVAL
  1829. Log_Write(" %s", t->c_str());
  1830. #endif //DEBUG_EVAL
  1831. nexttoken = t->next;
  1832. delete t;
  1833. } //end for
  1834. #ifdef DEBUG_EVAL
  1835. if (integer) Log_Write("$eval result: %d", *intvalue);
  1836. else Log_Write("$eval result: %f", *floatvalue);
  1837. #endif //DEBUG_EVAL
  1838. //
  1839. return true;
  1840. }
  1841. /*
  1842. ================
  1843. idParser::Directive_elif
  1844. ================
  1845. */
  1846. int idParser::Directive_elif( void ) {
  1847. signed long int value;
  1848. int type, skip;
  1849. idParser::PopIndent( &type, &skip );
  1850. if (!type || type == INDENT_ELSE) {
  1851. idParser::Error( "misplaced #elif" );
  1852. return false;
  1853. }
  1854. if ( !idParser::Evaluate( &value, NULL, true ) ) {
  1855. return false;
  1856. }
  1857. skip = (value == 0);
  1858. idParser::PushIndent( INDENT_ELIF, skip );
  1859. return true;
  1860. }
  1861. /*
  1862. ================
  1863. idParser::Directive_if
  1864. ================
  1865. */
  1866. int idParser::Directive_if( void ) {
  1867. signed long int value;
  1868. int skip;
  1869. if ( !idParser::Evaluate( &value, NULL, true ) ) {
  1870. return false;
  1871. }
  1872. skip = (value == 0);
  1873. idParser::PushIndent( INDENT_IF, skip );
  1874. return true;
  1875. }
  1876. /*
  1877. ================
  1878. idParser::Directive_line
  1879. ================
  1880. */
  1881. int idParser::Directive_line( void ) {
  1882. idToken token;
  1883. idParser::Error( "#line directive not supported" );
  1884. while( idParser::ReadLine( &token ) ) {
  1885. }
  1886. return true;
  1887. }
  1888. /*
  1889. ================
  1890. idParser::Directive_error
  1891. ================
  1892. */
  1893. int idParser::Directive_error( void ) {
  1894. idToken token;
  1895. if ( !idParser::ReadLine( &token) || token.type != TT_STRING ) {
  1896. idParser::Error( "#error without string" );
  1897. return false;
  1898. }
  1899. idParser::Error( "#error: %s", token.c_str() );
  1900. return true;
  1901. }
  1902. /*
  1903. ================
  1904. idParser::Directive_warning
  1905. ================
  1906. */
  1907. int idParser::Directive_warning( void ) {
  1908. idToken token;
  1909. if ( !idParser::ReadLine( &token) || token.type != TT_STRING ) {
  1910. idParser::Warning( "#warning without string" );
  1911. return false;
  1912. }
  1913. idParser::Warning( "#warning: %s", token.c_str() );
  1914. return true;
  1915. }
  1916. /*
  1917. ================
  1918. idParser::Directive_pragma
  1919. ================
  1920. */
  1921. int idParser::Directive_pragma( void ) {
  1922. idToken token;
  1923. idParser::Warning( "#pragma directive not supported" );
  1924. while( idParser::ReadLine( &token ) ) {
  1925. }
  1926. return true;
  1927. }
  1928. /*
  1929. ================
  1930. idParser::UnreadSignToken
  1931. ================
  1932. */
  1933. void idParser::UnreadSignToken( void ) {
  1934. idToken token;
  1935. token.line = idParser::scriptstack->GetLineNum();
  1936. token.whiteSpaceStart_p = NULL;
  1937. token.whiteSpaceEnd_p = NULL;
  1938. token.linesCrossed = 0;
  1939. token.flags = 0;
  1940. token = "-";
  1941. token.type = TT_PUNCTUATION;
  1942. token.subtype = P_SUB;
  1943. idParser::UnreadSourceToken( &token );
  1944. }
  1945. /*
  1946. ================
  1947. idParser::Directive_eval
  1948. ================
  1949. */
  1950. int idParser::Directive_eval( void ) {
  1951. signed long int value;
  1952. idToken token;
  1953. char buf[128];
  1954. if ( !idParser::Evaluate( &value, NULL, true ) ) {
  1955. return false;
  1956. }
  1957. token.line = idParser::scriptstack->GetLineNum();
  1958. token.whiteSpaceStart_p = NULL;
  1959. token.whiteSpaceEnd_p = NULL;
  1960. token.linesCrossed = 0;
  1961. token.flags = 0;
  1962. sprintf(buf, "%d", abs(value));
  1963. token = buf;
  1964. token.type = TT_NUMBER;
  1965. token.subtype = TT_INTEGER|TT_LONG|TT_DECIMAL;
  1966. idParser::UnreadSourceToken( &token );
  1967. if ( value < 0 ) {
  1968. idParser::UnreadSignToken();
  1969. }
  1970. return true;
  1971. }
  1972. /*
  1973. ================
  1974. idParser::Directive_evalfloat
  1975. ================
  1976. */
  1977. int idParser::Directive_evalfloat( void ) {
  1978. double value;
  1979. idToken token;
  1980. char buf[128];
  1981. if ( !idParser::Evaluate( NULL, &value, false ) ) {
  1982. return false;
  1983. }
  1984. token.line = idParser::scriptstack->GetLineNum();
  1985. token.whiteSpaceStart_p = NULL;
  1986. token.whiteSpaceEnd_p = NULL;
  1987. token.linesCrossed = 0;
  1988. token.flags = 0;
  1989. sprintf(buf, "%1.2f", idMath::Fabs(value));
  1990. token = buf;
  1991. token.type = TT_NUMBER;
  1992. token.subtype = TT_FLOAT|TT_LONG|TT_DECIMAL;
  1993. idParser::UnreadSourceToken( &token );
  1994. if (value < 0) {
  1995. idParser::UnreadSignToken();
  1996. }
  1997. return true;
  1998. }
  1999. /*
  2000. ================
  2001. idParser::ReadDirective
  2002. ================
  2003. */
  2004. int idParser::ReadDirective( void ) {
  2005. idToken token;
  2006. //read the directive name
  2007. if ( !idParser::ReadSourceToken( &token ) ) {
  2008. idParser::Error( "found '#' without name" );
  2009. return false;
  2010. }
  2011. //directive name must be on the same line
  2012. if (token.linesCrossed > 0) {
  2013. idParser::UnreadSourceToken( &token );
  2014. idParser::Error( "found '#' at end of line" );
  2015. return false;
  2016. }
  2017. //if if is a name
  2018. if (token.type == TT_NAME) {
  2019. if ( token == "if" ) {
  2020. return idParser::Directive_if();
  2021. }
  2022. else if ( token == "ifdef" ) {
  2023. return idParser::Directive_ifdef();
  2024. }
  2025. else if ( token == "ifndef" ) {
  2026. return idParser::Directive_ifndef();
  2027. }
  2028. else if ( token == "elif" ) {
  2029. return idParser::Directive_elif();
  2030. }
  2031. else if ( token == "else" ) {
  2032. return idParser::Directive_else();
  2033. }
  2034. else if ( token == "endif" ) {
  2035. return idParser::Directive_endif();
  2036. }
  2037. else if (idParser::skip > 0) {
  2038. // skip the rest of the line
  2039. while( idParser::ReadLine( &token ) ) {
  2040. }
  2041. return true;
  2042. }
  2043. else {
  2044. if ( token == "include" ) {
  2045. return idParser::Directive_include();
  2046. }
  2047. else if ( token == "define" ) {
  2048. return idParser::Directive_define();
  2049. }
  2050. else if ( token == "undef" ) {
  2051. return idParser::Directive_undef();
  2052. }
  2053. else if ( token == "line" ) {
  2054. return idParser::Directive_line();
  2055. }
  2056. else if ( token == "error" ) {
  2057. return idParser::Directive_error();
  2058. }
  2059. else if ( token == "warning" ) {
  2060. return idParser::Directive_warning();
  2061. }
  2062. else if ( token == "pragma" ) {
  2063. return idParser::Directive_pragma();
  2064. }
  2065. else if ( token == "eval" ) {
  2066. return idParser::Directive_eval();
  2067. }
  2068. else if ( token == "evalfloat" ) {
  2069. return idParser::Directive_evalfloat();
  2070. }
  2071. }
  2072. }
  2073. idParser::Error( "unknown precompiler directive '%s'", token.c_str() );
  2074. return false;
  2075. }
  2076. /*
  2077. ================
  2078. idParser::DollarDirective_evalint
  2079. ================
  2080. */
  2081. int idParser::DollarDirective_evalint( void ) {
  2082. signed long int value;
  2083. idToken token;
  2084. char buf[128];
  2085. if ( !idParser::DollarEvaluate( &value, NULL, true ) ) {
  2086. return false;
  2087. }
  2088. token.line = idParser::scriptstack->GetLineNum();
  2089. token.whiteSpaceStart_p = NULL;
  2090. token.whiteSpaceEnd_p = NULL;
  2091. token.linesCrossed = 0;
  2092. token.flags = 0;
  2093. sprintf( buf, "%d", abs( value ) );
  2094. token = buf;
  2095. token.type = TT_NUMBER;
  2096. token.subtype = TT_INTEGER | TT_LONG | TT_DECIMAL | TT_VALUESVALID;
  2097. token.intvalue = abs( value );
  2098. token.floatvalue = abs( value );
  2099. idParser::UnreadSourceToken( &token );
  2100. if ( value < 0 ) {
  2101. idParser::UnreadSignToken();
  2102. }
  2103. return true;
  2104. }
  2105. /*
  2106. ================
  2107. idParser::DollarDirective_evalfloat
  2108. ================
  2109. */
  2110. int idParser::DollarDirective_evalfloat( void ) {
  2111. double value;
  2112. idToken token;
  2113. char buf[128];
  2114. if ( !idParser::DollarEvaluate( NULL, &value, false ) ) {
  2115. return false;
  2116. }
  2117. token.line = idParser::scriptstack->GetLineNum();
  2118. token.whiteSpaceStart_p = NULL;
  2119. token.whiteSpaceEnd_p = NULL;
  2120. token.linesCrossed = 0;
  2121. token.flags = 0;
  2122. sprintf( buf, "%1.2f", fabs( value ) );
  2123. token = buf;
  2124. token.type = TT_NUMBER;
  2125. token.subtype = TT_FLOAT | TT_LONG | TT_DECIMAL | TT_VALUESVALID;
  2126. token.intvalue = (unsigned long) fabs( value );
  2127. token.floatvalue = fabs( value );
  2128. idParser::UnreadSourceToken( &token );
  2129. if ( value < 0 ) {
  2130. idParser::UnreadSignToken();
  2131. }
  2132. return true;
  2133. }
  2134. /*
  2135. ================
  2136. idParser::ReadDollarDirective
  2137. ================
  2138. */
  2139. int idParser::ReadDollarDirective( void ) {
  2140. idToken token;
  2141. // read the directive name
  2142. if ( !idParser::ReadSourceToken( &token ) ) {
  2143. idParser::Error( "found '$' without name" );
  2144. return false;
  2145. }
  2146. // directive name must be on the same line
  2147. if ( token.linesCrossed > 0 ) {
  2148. idParser::UnreadSourceToken( &token );
  2149. idParser::Error( "found '$' at end of line" );
  2150. return false;
  2151. }
  2152. // if if is a name
  2153. if (token.type == TT_NAME) {
  2154. if ( token == "evalint" ) {
  2155. return idParser::DollarDirective_evalint();
  2156. }
  2157. else if ( token == "evalfloat" ) {
  2158. return idParser::DollarDirective_evalfloat();
  2159. }
  2160. }
  2161. idParser::UnreadSourceToken( &token );
  2162. return false;
  2163. }
  2164. /*
  2165. ================
  2166. idParser::ReadToken
  2167. ================
  2168. */
  2169. int idParser::ReadToken( idToken *token ) {
  2170. define_t *define;
  2171. while(1) {
  2172. if ( !idParser::ReadSourceToken( token ) ) {
  2173. return false;
  2174. }
  2175. // check for precompiler directives
  2176. if ( token->type == TT_PUNCTUATION && (*token)[0] == '#' && (*token)[1] == '\0' ) {
  2177. // read the precompiler directive
  2178. if ( !idParser::ReadDirective() ) {
  2179. return false;
  2180. }
  2181. continue;
  2182. }
  2183. // if skipping source because of conditional compilation
  2184. if ( idParser::skip ) {
  2185. continue;
  2186. }
  2187. // recursively concatenate strings that are behind each other still resolving defines
  2188. if ( token->type == TT_STRING && !(idParser::scriptstack->GetFlags() & LEXFL_NOSTRINGCONCAT) ) {
  2189. idToken newtoken;
  2190. if ( idParser::ReadToken( &newtoken ) ) {
  2191. if ( newtoken.type == TT_STRING ) {
  2192. token->Append( newtoken.c_str() );
  2193. }
  2194. else {
  2195. idParser::UnreadSourceToken( &newtoken );
  2196. }
  2197. }
  2198. }
  2199. //
  2200. if ( !(idParser::scriptstack->GetFlags() & LEXFL_NODOLLARPRECOMPILE) ) {
  2201. // check for special precompiler directives
  2202. if ( token->type == TT_PUNCTUATION && (*token)[0] == '$' && (*token)[1] == '\0' ) {
  2203. // read the precompiler directive
  2204. if ( idParser::ReadDollarDirective() ) {
  2205. continue;
  2206. }
  2207. }
  2208. }
  2209. // if the token is a name
  2210. if ( token->type == TT_NAME && !( token->flags & TOKEN_FL_RECURSIVE_DEFINE ) ) {
  2211. // check if the name is a define macro
  2212. define = FindHashedDefine( idParser::definehash, token->c_str() );
  2213. // if it is a define macro
  2214. if ( define ) {
  2215. // expand the defined macro
  2216. if ( !idParser::ExpandDefineIntoSource( token, define ) ) {
  2217. return false;
  2218. }
  2219. continue;
  2220. }
  2221. }
  2222. // found a token
  2223. return true;
  2224. }
  2225. }
  2226. /*
  2227. ================
  2228. idParser::ExpectTokenString
  2229. ================
  2230. */
  2231. int idParser::ExpectTokenString( const char *string ) {
  2232. idToken token;
  2233. if ( !idParser::ReadToken( &token ) ) {
  2234. idParser::Error( "couldn't find expected '%s'", string );
  2235. return false;
  2236. }
  2237. if ( token != string ) {
  2238. idParser::Error( "expected '%s' but found '%s'", string, token.c_str() );
  2239. return false;
  2240. }
  2241. return true;
  2242. }
  2243. /*
  2244. ================
  2245. idParser::ExpectTokenType
  2246. ================
  2247. */
  2248. int idParser::ExpectTokenType( int type, int subtype, idToken *token ) {
  2249. idStr str;
  2250. if ( !idParser::ReadToken( token ) ) {
  2251. idParser::Error( "couldn't read expected token" );
  2252. return 0;
  2253. }
  2254. if ( token->type != type ) {
  2255. switch( type ) {
  2256. case TT_STRING: str = "string"; break;
  2257. case TT_LITERAL: str = "literal"; break;
  2258. case TT_NUMBER: str = "number"; break;
  2259. case TT_NAME: str = "name"; break;
  2260. case TT_PUNCTUATION: str = "punctuation"; break;
  2261. default: str = "unknown type"; break;
  2262. }
  2263. idParser::Error( "expected a %s but found '%s'", str.c_str(), token->c_str() );
  2264. return 0;
  2265. }
  2266. if ( token->type == TT_NUMBER ) {
  2267. if ( (token->subtype & subtype) != subtype ) {
  2268. str.Clear();
  2269. if ( subtype & TT_DECIMAL ) str = "decimal ";
  2270. if ( subtype & TT_HEX ) str = "hex ";
  2271. if ( subtype & TT_OCTAL ) str = "octal ";
  2272. if ( subtype & TT_BINARY ) str = "binary ";
  2273. if ( subtype & TT_UNSIGNED ) str += "unsigned ";
  2274. if ( subtype & TT_LONG ) str += "long ";
  2275. if ( subtype & TT_FLOAT ) str += "float ";
  2276. if ( subtype & TT_INTEGER ) str += "integer ";
  2277. str.StripTrailing( ' ' );
  2278. idParser::Error( "expected %s but found '%s'", str.c_str(), token->c_str() );
  2279. return 0;
  2280. }
  2281. }
  2282. else if ( token->type == TT_PUNCTUATION ) {
  2283. if ( subtype < 0 ) {
  2284. idParser::Error( "BUG: wrong punctuation subtype" );
  2285. return 0;
  2286. }
  2287. if ( token->subtype != subtype ) {
  2288. idParser::Error( "expected '%s' but found '%s'", scriptstack->GetPunctuationFromId( subtype ), token->c_str() );
  2289. return 0;
  2290. }
  2291. }
  2292. return 1;
  2293. }
  2294. /*
  2295. ================
  2296. idParser::ExpectAnyToken
  2297. ================
  2298. */
  2299. int idParser::ExpectAnyToken( idToken *token ) {
  2300. if (!idParser::ReadToken( token )) {
  2301. idParser::Error( "couldn't read expected token" );
  2302. return false;
  2303. }
  2304. else {
  2305. return true;
  2306. }
  2307. }
  2308. /*
  2309. ================
  2310. idParser::CheckTokenString
  2311. ================
  2312. */
  2313. int idParser::CheckTokenString( const char *string ) {
  2314. idToken tok;
  2315. if ( !ReadToken( &tok ) ) {
  2316. return false;
  2317. }
  2318. //if the token is available
  2319. if ( tok == string ) {
  2320. return true;
  2321. }
  2322. UnreadSourceToken( &tok );
  2323. return false;
  2324. }
  2325. /*
  2326. ================
  2327. idParser::CheckTokenType
  2328. ================
  2329. */
  2330. int idParser::CheckTokenType( int type, int subtype, idToken *token ) {
  2331. idToken tok;
  2332. if ( !ReadToken( &tok ) ) {
  2333. return false;
  2334. }
  2335. //if the type matches
  2336. if (tok.type == type && (tok.subtype & subtype) == subtype) {
  2337. *token = tok;
  2338. return true;
  2339. }
  2340. UnreadSourceToken( &tok );
  2341. return false;
  2342. }
  2343. /*
  2344. ================
  2345. idParser::PeekTokenString
  2346. ================
  2347. */
  2348. int idParser::PeekTokenString( const char *string ) {
  2349. idToken tok;
  2350. if ( !ReadToken( &tok ) ) {
  2351. return false;
  2352. }
  2353. UnreadSourceToken( &tok );
  2354. // if the token is available
  2355. if ( tok == string ) {
  2356. return true;
  2357. }
  2358. return false;
  2359. }
  2360. /*
  2361. ================
  2362. idParser::PeekTokenType
  2363. ================
  2364. */
  2365. int idParser::PeekTokenType( int type, int subtype, idToken *token ) {
  2366. idToken tok;
  2367. if ( !ReadToken( &tok ) ) {
  2368. return false;
  2369. }
  2370. UnreadSourceToken( &tok );
  2371. // if the type matches
  2372. if ( tok.type == type && ( tok.subtype & subtype ) == subtype ) {
  2373. *token = tok;
  2374. return true;
  2375. }
  2376. return false;
  2377. }
  2378. /*
  2379. ================
  2380. idParser::SkipUntilString
  2381. ================
  2382. */
  2383. int idParser::SkipUntilString( const char *string ) {
  2384. idToken token;
  2385. while(idParser::ReadToken( &token )) {
  2386. if ( token == string ) {
  2387. return true;
  2388. }
  2389. }
  2390. return false;
  2391. }
  2392. /*
  2393. ================
  2394. idParser::SkipRestOfLine
  2395. ================
  2396. */
  2397. int idParser::SkipRestOfLine( void ) {
  2398. idToken token;
  2399. while(idParser::ReadToken( &token )) {
  2400. if ( token.linesCrossed ) {
  2401. idParser::UnreadSourceToken( &token );
  2402. return true;
  2403. }
  2404. }
  2405. return false;
  2406. }
  2407. /*
  2408. =================
  2409. idParser::SkipBracedSection
  2410. Skips until a matching close brace is found.
  2411. Internal brace depths are properly skipped.
  2412. =================
  2413. */
  2414. int idParser::SkipBracedSection( bool parseFirstBrace ) {
  2415. idToken token;
  2416. int depth;
  2417. depth = parseFirstBrace ? 0 : 1;
  2418. do {
  2419. if ( !ReadToken( &token ) ) {
  2420. return false;
  2421. }
  2422. if( token.type == TT_PUNCTUATION ) {
  2423. if( token == "{" ) {
  2424. depth++;
  2425. } else if ( token == "}" ) {
  2426. depth--;
  2427. }
  2428. }
  2429. } while( depth );
  2430. return true;
  2431. }
  2432. /*
  2433. =================
  2434. idParser::ParseBracedSectionExact
  2435. The next token should be an open brace.
  2436. Parses until a matching close brace is found.
  2437. Maintains the exact formating of the braced section
  2438. FIXME: what about precompilation ?
  2439. =================
  2440. */
  2441. const char *idParser::ParseBracedSectionExact( idStr &out, int tabs ) {
  2442. return scriptstack->ParseBracedSectionExact( out, tabs );
  2443. }
  2444. /*
  2445. =================
  2446. idParser::ParseBracedSection
  2447. The next token should be an open brace.
  2448. Parses until a matching close brace is found.
  2449. Internal brace depths are properly skipped.
  2450. =================
  2451. */
  2452. const char *idParser::ParseBracedSection( idStr &out, int tabs ) {
  2453. idToken token;
  2454. int i, depth;
  2455. bool doTabs = false;
  2456. if (tabs >= 0) {
  2457. doTabs = true;
  2458. }
  2459. out.Empty();
  2460. if ( !idParser::ExpectTokenString( "{" ) ) {
  2461. return out.c_str();
  2462. }
  2463. out = "{";
  2464. depth = 1;
  2465. do {
  2466. if ( !idParser::ReadToken( &token ) ) {
  2467. Error( "missing closing brace" );
  2468. return out.c_str();
  2469. }
  2470. // if the token is on a new line
  2471. for ( i = 0; i < token.linesCrossed; i++ ) {
  2472. out += "\r\n";
  2473. }
  2474. if (doTabs && token.linesCrossed) {
  2475. i = tabs;
  2476. if (token[0] == '}' && i > 0) {
  2477. i--;
  2478. }
  2479. while (i-- > 0) {
  2480. out += "\t";
  2481. }
  2482. }
  2483. if ( token.type == TT_PUNCTUATION ) {
  2484. if ( token[0] == '{' ) {
  2485. depth++;
  2486. if (doTabs) {
  2487. tabs++;
  2488. }
  2489. }
  2490. else if ( token[0] == '}' ) {
  2491. depth--;
  2492. if (doTabs) {
  2493. tabs--;
  2494. }
  2495. }
  2496. }
  2497. if ( token.type == TT_STRING ) {
  2498. out += "\"" + token + "\"";
  2499. }
  2500. else {
  2501. out += token;
  2502. }
  2503. out += " ";
  2504. } while( depth );
  2505. return out.c_str();
  2506. }
  2507. /*
  2508. =================
  2509. idParser::ParseRestOfLine
  2510. parse the rest of the line
  2511. =================
  2512. */
  2513. const char *idParser::ParseRestOfLine( idStr &out ) {
  2514. idToken token;
  2515. out.Empty();
  2516. while(idParser::ReadToken( &token )) {
  2517. if ( token.linesCrossed ) {
  2518. idParser::UnreadSourceToken( &token );
  2519. break;
  2520. }
  2521. if ( out.Length() ) {
  2522. out += " ";
  2523. }
  2524. out += token;
  2525. }
  2526. return out.c_str();
  2527. }
  2528. /*
  2529. ================
  2530. idParser::UnreadToken
  2531. ================
  2532. */
  2533. void idParser::UnreadToken( idToken *token ) {
  2534. idParser::UnreadSourceToken( token );
  2535. }
  2536. /*
  2537. ================
  2538. idParser::ReadTokenOnLine
  2539. ================
  2540. */
  2541. int idParser::ReadTokenOnLine( idToken *token ) {
  2542. idToken tok;
  2543. if (!idParser::ReadToken( &tok )) {
  2544. return false;
  2545. }
  2546. // if no lines were crossed before this token
  2547. if ( !tok.linesCrossed ) {
  2548. *token = tok;
  2549. return true;
  2550. }
  2551. //
  2552. idParser::UnreadSourceToken( &tok );
  2553. return false;
  2554. }
  2555. /*
  2556. ================
  2557. idParser::ParseInt
  2558. ================
  2559. */
  2560. int idParser::ParseInt( void ) {
  2561. idToken token;
  2562. if ( !idParser::ReadToken( &token ) ) {
  2563. idParser::Error( "couldn't read expected integer" );
  2564. return 0;
  2565. }
  2566. if ( token.type == TT_PUNCTUATION && token == "-" ) {
  2567. idParser::ExpectTokenType( TT_NUMBER, TT_INTEGER, &token );
  2568. return -((signed int) token.GetIntValue());
  2569. }
  2570. else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) {
  2571. idParser::Error( "expected integer value, found '%s'", token.c_str() );
  2572. }
  2573. return token.GetIntValue();
  2574. }
  2575. /*
  2576. ================
  2577. idParser::ParseBool
  2578. ================
  2579. */
  2580. bool idParser::ParseBool( void ) {
  2581. idToken token;
  2582. if ( !idParser::ExpectTokenType( TT_NUMBER, 0, &token ) ) {
  2583. idParser::Error( "couldn't read expected boolean" );
  2584. return false;
  2585. }
  2586. return ( token.GetIntValue() != 0 );
  2587. }
  2588. /*
  2589. ================
  2590. idParser::ParseFloat
  2591. ================
  2592. */
  2593. float idParser::ParseFloat( void ) {
  2594. idToken token;
  2595. if ( !idParser::ReadToken( &token ) ) {
  2596. idParser::Error( "couldn't read expected floating point number" );
  2597. return 0.0f;
  2598. }
  2599. if ( token.type == TT_PUNCTUATION && token == "-" ) {
  2600. idParser::ExpectTokenType( TT_NUMBER, 0, &token );
  2601. return -token.GetFloatValue();
  2602. }
  2603. else if ( token.type != TT_NUMBER ) {
  2604. idParser::Error( "expected float value, found '%s'", token.c_str() );
  2605. }
  2606. return token.GetFloatValue();
  2607. }
  2608. /*
  2609. ================
  2610. idParser::Parse1DMatrix
  2611. ================
  2612. */
  2613. int idParser::Parse1DMatrix( int x, float *m ) {
  2614. int i;
  2615. if ( !idParser::ExpectTokenString( "(" ) ) {
  2616. return false;
  2617. }
  2618. for ( i = 0; i < x; i++ ) {
  2619. m[i] = idParser::ParseFloat();
  2620. }
  2621. if ( !idParser::ExpectTokenString( ")" ) ) {
  2622. return false;
  2623. }
  2624. return true;
  2625. }
  2626. /*
  2627. ================
  2628. idParser::Parse2DMatrix
  2629. ================
  2630. */
  2631. int idParser::Parse2DMatrix( int y, int x, float *m ) {
  2632. int i;
  2633. if ( !idParser::ExpectTokenString( "(" ) ) {
  2634. return false;
  2635. }
  2636. for ( i = 0; i < y; i++ ) {
  2637. if ( !idParser::Parse1DMatrix( x, m + i * x ) ) {
  2638. return false;
  2639. }
  2640. }
  2641. if ( !idParser::ExpectTokenString( ")" ) ) {
  2642. return false;
  2643. }
  2644. return true;
  2645. }
  2646. /*
  2647. ================
  2648. idParser::Parse3DMatrix
  2649. ================
  2650. */
  2651. int idParser::Parse3DMatrix( int z, int y, int x, float *m ) {
  2652. int i;
  2653. if ( !idParser::ExpectTokenString( "(" ) ) {
  2654. return false;
  2655. }
  2656. for ( i = 0 ; i < z; i++ ) {
  2657. if ( !idParser::Parse2DMatrix( y, x, m + i * x*y ) ) {
  2658. return false;
  2659. }
  2660. }
  2661. if ( !idParser::ExpectTokenString( ")" ) ) {
  2662. return false;
  2663. }
  2664. return true;
  2665. }
  2666. /*
  2667. ================
  2668. idParser::GetLastWhiteSpace
  2669. ================
  2670. */
  2671. int idParser::GetLastWhiteSpace( idStr &whiteSpace ) const {
  2672. if ( scriptstack ) {
  2673. scriptstack->GetLastWhiteSpace( whiteSpace );
  2674. } else {
  2675. whiteSpace.Clear();
  2676. }
  2677. return whiteSpace.Length();
  2678. }
  2679. /*
  2680. ================
  2681. idParser::SetMarker
  2682. ================
  2683. */
  2684. void idParser::SetMarker( void ) {
  2685. marker_p = NULL;
  2686. }
  2687. /*
  2688. ================
  2689. idParser::GetStringFromMarker
  2690. FIXME: this is very bad code, the script isn't even garrenteed to still be around
  2691. ================
  2692. */
  2693. void idParser::GetStringFromMarker( idStr& out, bool clean ) {
  2694. char* p;
  2695. char save;
  2696. if ( marker_p == NULL ) {
  2697. marker_p = scriptstack->buffer;
  2698. }
  2699. if ( tokens ) {
  2700. p = (char*)tokens->whiteSpaceStart_p;
  2701. } else {
  2702. p = (char*)scriptstack->script_p;
  2703. }
  2704. // Set the end character to NULL to give us a complete string
  2705. save = *p;
  2706. *p = 0;
  2707. // If cleaning then reparse
  2708. if ( clean ) {
  2709. idParser temp( marker_p, strlen( marker_p ), "temp", flags );
  2710. idToken token;
  2711. while ( temp.ReadToken ( &token ) ) {
  2712. out += token;
  2713. }
  2714. } else {
  2715. out = marker_p;
  2716. }
  2717. // restore the character we set to NULL
  2718. *p = save;
  2719. }
  2720. /*
  2721. ================
  2722. idParser::SetIncludePath
  2723. ================
  2724. */
  2725. void idParser::SetIncludePath( const char *path ) {
  2726. idParser::includepath = path;
  2727. // add trailing path seperator
  2728. if (idParser::includepath[idParser::includepath.Length()-1] != '\\' &&
  2729. idParser::includepath[idParser::includepath.Length()-1] != '/') {
  2730. idParser::includepath += PATHSEPERATOR_STR;
  2731. }
  2732. }
  2733. /*
  2734. ================
  2735. idParser::SetPunctuations
  2736. ================
  2737. */
  2738. void idParser::SetPunctuations( const punctuation_t *p ) {
  2739. idParser::punctuations = p;
  2740. }
  2741. /*
  2742. ================
  2743. idParser::SetFlags
  2744. ================
  2745. */
  2746. void idParser::SetFlags( int flags ) {
  2747. idLexer *s;
  2748. idParser::flags = flags;
  2749. for ( s = idParser::scriptstack; s; s = s->next ) {
  2750. s->SetFlags( flags );
  2751. }
  2752. }
  2753. /*
  2754. ================
  2755. idParser::GetFlags
  2756. ================
  2757. */
  2758. int idParser::GetFlags( void ) const {
  2759. return idParser::flags;
  2760. }
  2761. /*
  2762. ================
  2763. idParser::LoadFile
  2764. ================
  2765. */
  2766. int idParser::LoadFile( const char *filename, bool OSPath ) {
  2767. idLexer *script;
  2768. if ( idParser::loaded ) {
  2769. idLib::common->FatalError("idParser::loadFile: another source already loaded");
  2770. return false;
  2771. }
  2772. script = new idLexer( filename, 0, OSPath );
  2773. if ( !script->IsLoaded() ) {
  2774. delete script;
  2775. return false;
  2776. }
  2777. script->SetFlags( idParser::flags );
  2778. script->SetPunctuations( idParser::punctuations );
  2779. script->next = NULL;
  2780. idParser::OSPath = OSPath;
  2781. idParser::filename = filename;
  2782. idParser::scriptstack = script;
  2783. idParser::tokens = NULL;
  2784. idParser::indentstack = NULL;
  2785. idParser::skip = 0;
  2786. idParser::loaded = true;
  2787. if ( !idParser::definehash ) {
  2788. idParser::defines = NULL;
  2789. idParser::definehash = (define_t **) Mem_ClearedAlloc( DEFINEHASHSIZE * sizeof(define_t *) );
  2790. idParser::AddGlobalDefinesToSource();
  2791. }
  2792. return true;
  2793. }
  2794. /*
  2795. ================
  2796. idParser::LoadMemory
  2797. ================
  2798. */
  2799. int idParser::LoadMemory(const char *ptr, int length, const char *name ) {
  2800. idLexer *script;
  2801. if ( idParser::loaded ) {
  2802. idLib::common->FatalError("idParser::loadMemory: another source already loaded");
  2803. return false;
  2804. }
  2805. script = new idLexer( ptr, length, name );
  2806. if ( !script->IsLoaded() ) {
  2807. delete script;
  2808. return false;
  2809. }
  2810. script->SetFlags( idParser::flags );
  2811. script->SetPunctuations( idParser::punctuations );
  2812. script->next = NULL;
  2813. idParser::filename = name;
  2814. idParser::scriptstack = script;
  2815. idParser::tokens = NULL;
  2816. idParser::indentstack = NULL;
  2817. idParser::skip = 0;
  2818. idParser::loaded = true;
  2819. if ( !idParser::definehash ) {
  2820. idParser::defines = NULL;
  2821. idParser::definehash = (define_t **) Mem_ClearedAlloc( DEFINEHASHSIZE * sizeof(define_t *) );
  2822. idParser::AddGlobalDefinesToSource();
  2823. }
  2824. return true;
  2825. }
  2826. /*
  2827. ================
  2828. idParser::FreeSource
  2829. ================
  2830. */
  2831. void idParser::FreeSource( bool keepDefines ) {
  2832. idLexer *script;
  2833. idToken *token;
  2834. define_t *define;
  2835. indent_t *indent;
  2836. int i;
  2837. // free all the scripts
  2838. while( scriptstack ) {
  2839. script = scriptstack;
  2840. scriptstack = scriptstack->next;
  2841. delete script;
  2842. }
  2843. // free all the tokens
  2844. while( tokens ) {
  2845. token = tokens;
  2846. tokens = tokens->next;
  2847. delete token;
  2848. }
  2849. // free all indents
  2850. while( indentstack ) {
  2851. indent = indentstack;
  2852. indentstack = indentstack->next;
  2853. Mem_Free( indent );
  2854. }
  2855. if ( !keepDefines ) {
  2856. // free hash table
  2857. if ( definehash ) {
  2858. // free defines
  2859. for ( i = 0; i < DEFINEHASHSIZE; i++ ) {
  2860. while( definehash[i] ) {
  2861. define = definehash[i];
  2862. definehash[i] = definehash[i]->hashnext;
  2863. FreeDefine(define);
  2864. }
  2865. }
  2866. defines = NULL;
  2867. Mem_Free( idParser::definehash );
  2868. definehash = NULL;
  2869. }
  2870. }
  2871. loaded = false;
  2872. }
  2873. /*
  2874. ================
  2875. idParser::GetPunctuationFromId
  2876. ================
  2877. */
  2878. const char *idParser::GetPunctuationFromId( int id ) {
  2879. int i;
  2880. if ( !idParser::punctuations ) {
  2881. idLexer lex;
  2882. return lex.GetPunctuationFromId( id );
  2883. }
  2884. for (i = 0; idParser::punctuations[i].p; i++) {
  2885. if ( idParser::punctuations[i].n == id ) {
  2886. return idParser::punctuations[i].p;
  2887. }
  2888. }
  2889. return "unkown punctuation";
  2890. }
  2891. /*
  2892. ================
  2893. idParser::GetPunctuationId
  2894. ================
  2895. */
  2896. int idParser::GetPunctuationId( const char *p ) {
  2897. int i;
  2898. if ( !idParser::punctuations ) {
  2899. idLexer lex;
  2900. return lex.GetPunctuationId( p );
  2901. }
  2902. for (i = 0; idParser::punctuations[i].p; i++) {
  2903. if ( !strcmp(idParser::punctuations[i].p, p) ) {
  2904. return idParser::punctuations[i].n;
  2905. }
  2906. }
  2907. return 0;
  2908. }
  2909. /*
  2910. ================
  2911. idParser::idParser
  2912. ================
  2913. */
  2914. idParser::idParser() {
  2915. this->loaded = false;
  2916. this->OSPath = false;
  2917. this->punctuations = 0;
  2918. this->flags = 0;
  2919. this->scriptstack = NULL;
  2920. this->indentstack = NULL;
  2921. this->definehash = NULL;
  2922. this->defines = NULL;
  2923. this->tokens = NULL;
  2924. this->marker_p = NULL;
  2925. }
  2926. /*
  2927. ================
  2928. idParser::idParser
  2929. ================
  2930. */
  2931. idParser::idParser( int flags ) {
  2932. this->loaded = false;
  2933. this->OSPath = false;
  2934. this->punctuations = 0;
  2935. this->flags = flags;
  2936. this->scriptstack = NULL;
  2937. this->indentstack = NULL;
  2938. this->definehash = NULL;
  2939. this->defines = NULL;
  2940. this->tokens = NULL;
  2941. this->marker_p = NULL;
  2942. }
  2943. /*
  2944. ================
  2945. idParser::idParser
  2946. ================
  2947. */
  2948. idParser::idParser( const char *filename, int flags, bool OSPath ) {
  2949. this->loaded = false;
  2950. this->OSPath = true;
  2951. this->punctuations = 0;
  2952. this->flags = flags;
  2953. this->scriptstack = NULL;
  2954. this->indentstack = NULL;
  2955. this->definehash = NULL;
  2956. this->defines = NULL;
  2957. this->tokens = NULL;
  2958. this->marker_p = NULL;
  2959. LoadFile( filename, OSPath );
  2960. }
  2961. /*
  2962. ================
  2963. idParser::idParser
  2964. ================
  2965. */
  2966. idParser::idParser( const char *ptr, int length, const char *name, int flags ) {
  2967. this->loaded = false;
  2968. this->OSPath = false;
  2969. this->punctuations = 0;
  2970. this->flags = flags;
  2971. this->scriptstack = NULL;
  2972. this->indentstack = NULL;
  2973. this->definehash = NULL;
  2974. this->defines = NULL;
  2975. this->tokens = NULL;
  2976. this->marker_p = NULL;
  2977. LoadMemory( ptr, length, name );
  2978. }
  2979. /*
  2980. ================
  2981. idParser::~idParser
  2982. ================
  2983. */
  2984. idParser::~idParser( void ) {
  2985. idParser::FreeSource( false );
  2986. }