Parser.cpp 73 KB

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