mojoshader_preprocessor.c 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362
  1. /**
  2. * MojoShader; generate shader programs from bytecode of compiled
  3. * Direct3D shaders.
  4. *
  5. * Please see the file LICENSE.txt in the source's root directory.
  6. *
  7. * This file written by Ryan C. Gordon.
  8. */
  9. #define __MOJOSHADER_INTERNAL__ 1
  10. #include "mojoshader_internal.h"
  11. #if DEBUG_PREPROCESSOR
  12. #define print_debug_token(token, len, val) \
  13. MOJOSHADER_print_debug_token("PREPROCESSOR", token, len, val)
  14. #else
  15. #define print_debug_token(token, len, val)
  16. #endif
  17. #if DEBUG_LEXER
  18. static Token debug_preprocessor_lexer(IncludeState *s)
  19. {
  20. const Token retval = preprocessor_lexer(s);
  21. MOJOSHADER_print_debug_token("LEXER", s->token, s->tokenlen, retval);
  22. return retval;
  23. } // debug_preprocessor_lexer
  24. #define preprocessor_lexer(s) debug_preprocessor_lexer(s)
  25. #endif
  26. #if DEBUG_TOKENIZER
  27. static void print_debug_lexing_position(IncludeState *s)
  28. {
  29. if (s != NULL)
  30. printf("NOW LEXING %s:%d ...\n", s->filename, s->line);
  31. } // print_debug_lexing_position
  32. #else
  33. #define print_debug_lexing_position(s)
  34. #endif
  35. typedef struct Context
  36. {
  37. int isfail;
  38. int out_of_memory;
  39. char failstr[256];
  40. int recursion_count;
  41. int asm_comments;
  42. int parsing_pragma;
  43. Conditional *conditional_pool;
  44. IncludeState *include_stack;
  45. IncludeState *include_pool;
  46. Define *define_hashtable[256];
  47. Define *define_pool;
  48. Define *file_macro;
  49. Define *line_macro;
  50. StringCache *filename_cache;
  51. MOJOSHADER_includeOpen open_callback;
  52. MOJOSHADER_includeClose close_callback;
  53. MOJOSHADER_malloc malloc;
  54. MOJOSHADER_free free;
  55. void *malloc_data;
  56. } Context;
  57. // Convenience functions for allocators...
  58. static inline void out_of_memory(Context *ctx)
  59. {
  60. ctx->out_of_memory = 1;
  61. } // out_of_memory
  62. static inline void *Malloc(Context *ctx, const size_t len)
  63. {
  64. void *retval = ctx->malloc((int) len, ctx->malloc_data);
  65. if (retval == NULL)
  66. out_of_memory(ctx);
  67. return retval;
  68. } // Malloc
  69. static inline void Free(Context *ctx, void *ptr)
  70. {
  71. ctx->free(ptr, ctx->malloc_data);
  72. } // Free
  73. static void *MallocBridge(int bytes, void *data)
  74. {
  75. return Malloc((Context *) data, (size_t) bytes);
  76. } // MallocBridge
  77. static void FreeBridge(void *ptr, void *data)
  78. {
  79. Free((Context *) data, ptr);
  80. } // FreeBridge
  81. static inline char *StrDup(Context *ctx, const char *str)
  82. {
  83. char *retval = (char *) Malloc(ctx, strlen(str) + 1);
  84. if (retval != NULL)
  85. strcpy(retval, str);
  86. return retval;
  87. } // StrDup
  88. static void failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
  89. static void failf(Context *ctx, const char *fmt, ...)
  90. {
  91. ctx->isfail = 1;
  92. va_list ap;
  93. va_start(ap, fmt);
  94. vsnprintf(ctx->failstr, sizeof (ctx->failstr), fmt, ap);
  95. va_end(ap);
  96. } // failf
  97. static inline void fail(Context *ctx, const char *reason)
  98. {
  99. failf(ctx, "%s", reason);
  100. } // fail
  101. #if DEBUG_TOKENIZER
  102. void MOJOSHADER_print_debug_token(const char *subsystem, const char *token,
  103. const unsigned int tokenlen,
  104. const Token tokenval)
  105. {
  106. printf("%s TOKEN: \"", subsystem);
  107. unsigned int i;
  108. for (i = 0; i < tokenlen; i++)
  109. {
  110. if (token[i] == '\n')
  111. printf("\\n");
  112. else if (token[i] == '\\')
  113. printf("\\\\");
  114. else
  115. printf("%c", token[i]);
  116. } // for
  117. printf("\" (");
  118. switch (tokenval)
  119. {
  120. #define TOKENCASE(x) case x: printf("%s", #x); break
  121. TOKENCASE(TOKEN_UNKNOWN);
  122. TOKENCASE(TOKEN_IDENTIFIER);
  123. TOKENCASE(TOKEN_INT_LITERAL);
  124. TOKENCASE(TOKEN_FLOAT_LITERAL);
  125. TOKENCASE(TOKEN_STRING_LITERAL);
  126. TOKENCASE(TOKEN_ADDASSIGN);
  127. TOKENCASE(TOKEN_SUBASSIGN);
  128. TOKENCASE(TOKEN_MULTASSIGN);
  129. TOKENCASE(TOKEN_DIVASSIGN);
  130. TOKENCASE(TOKEN_MODASSIGN);
  131. TOKENCASE(TOKEN_XORASSIGN);
  132. TOKENCASE(TOKEN_ANDASSIGN);
  133. TOKENCASE(TOKEN_ORASSIGN);
  134. TOKENCASE(TOKEN_INCREMENT);
  135. TOKENCASE(TOKEN_DECREMENT);
  136. TOKENCASE(TOKEN_RSHIFT);
  137. TOKENCASE(TOKEN_LSHIFT);
  138. TOKENCASE(TOKEN_ANDAND);
  139. TOKENCASE(TOKEN_OROR);
  140. TOKENCASE(TOKEN_LEQ);
  141. TOKENCASE(TOKEN_GEQ);
  142. TOKENCASE(TOKEN_EQL);
  143. TOKENCASE(TOKEN_NEQ);
  144. TOKENCASE(TOKEN_HASH);
  145. TOKENCASE(TOKEN_HASHHASH);
  146. TOKENCASE(TOKEN_PP_INCLUDE);
  147. TOKENCASE(TOKEN_PP_LINE);
  148. TOKENCASE(TOKEN_PP_DEFINE);
  149. TOKENCASE(TOKEN_PP_UNDEF);
  150. TOKENCASE(TOKEN_PP_IF);
  151. TOKENCASE(TOKEN_PP_IFDEF);
  152. TOKENCASE(TOKEN_PP_IFNDEF);
  153. TOKENCASE(TOKEN_PP_ELSE);
  154. TOKENCASE(TOKEN_PP_ELIF);
  155. TOKENCASE(TOKEN_PP_ENDIF);
  156. TOKENCASE(TOKEN_PP_ERROR);
  157. TOKENCASE(TOKEN_PP_PRAGMA);
  158. TOKENCASE(TOKEN_INCOMPLETE_COMMENT);
  159. TOKENCASE(TOKEN_BAD_CHARS);
  160. TOKENCASE(TOKEN_EOI);
  161. TOKENCASE(TOKEN_PREPROCESSING_ERROR);
  162. #undef TOKENCASE
  163. case ((Token) '\n'):
  164. printf("'\\n'");
  165. break;
  166. case ((Token) '\\'):
  167. printf("'\\\\'");
  168. break;
  169. default:
  170. assert(((int)tokenval) < 256);
  171. printf("'%c'", (char) tokenval);
  172. break;
  173. } // switch
  174. printf(")\n");
  175. } // MOJOSHADER_print_debug_token
  176. #endif
  177. #if !MOJOSHADER_FORCE_INCLUDE_CALLBACKS
  178. // !!! FIXME: most of these _MSC_VER should probably be _WINDOWS?
  179. #ifdef _MSC_VER
  180. #define WIN32_LEAN_AND_MEAN 1
  181. #include <windows.h> // GL headers need this for WINGDIAPI definition.
  182. #else
  183. #include <sys/stat.h>
  184. #include <fcntl.h>
  185. #include <unistd.h>
  186. #endif
  187. int MOJOSHADER_internal_include_open(MOJOSHADER_includeType inctype,
  188. const char *fname, const char *parent,
  189. const char **outdata,
  190. unsigned int *outbytes,
  191. MOJOSHADER_malloc m, MOJOSHADER_free f,
  192. void *d)
  193. {
  194. #ifdef _MSC_VER
  195. WCHAR wpath[MAX_PATH];
  196. if (!MultiByteToWideChar(CP_UTF8, 0, fname, -1, wpath, MAX_PATH))
  197. return 0;
  198. const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
  199. const HANDLE handle = CreateFileW(wpath, FILE_GENERIC_READ, share,
  200. NULL, OPEN_EXISTING, NULL, NULL);
  201. if (handle == INVALID_HANDLE_VALUE)
  202. return 0;
  203. const DWORD fileSize = GetFileSize(handle, NULL);
  204. if (fileSize == INVALID_FILE_SIZE)
  205. {
  206. CloseHandle(handle);
  207. return 0;
  208. } // if
  209. char *data = (char *) m(fileSize, d);
  210. if (data == NULL)
  211. {
  212. CloseHandle(handle);
  213. return 0;
  214. } // if
  215. DWORD readLength = 0;
  216. if (!ReadFile(handle, data, fileSize, &readLength, NULL))
  217. {
  218. CloseHandle(handle);
  219. f(data, d);
  220. return 0;
  221. } // if
  222. CloseHandle(handle);
  223. if (readLength != fileSize)
  224. {
  225. f(data, d);
  226. return 0;
  227. } // if
  228. *outdata = data;
  229. *outbytes = fileSize;
  230. return 1;
  231. #else
  232. struct stat statbuf;
  233. if (stat(fname, &statbuf) == -1)
  234. return 0;
  235. char *data = (char *) m(statbuf.st_size, d);
  236. if (data == NULL)
  237. return 0;
  238. const int fd = open(fname, O_RDONLY);
  239. if (fd == -1)
  240. {
  241. f(data, d);
  242. return 0;
  243. } // if
  244. if (read(fd, data, statbuf.st_size) != statbuf.st_size)
  245. {
  246. f(data, d);
  247. close(fd);
  248. return 0;
  249. } // if
  250. close(fd);
  251. *outdata = data;
  252. *outbytes = (unsigned int) statbuf.st_size;
  253. return 1;
  254. #endif
  255. } // MOJOSHADER_internal_include_open
  256. void MOJOSHADER_internal_include_close(const char *data, MOJOSHADER_malloc m,
  257. MOJOSHADER_free f, void *d)
  258. {
  259. f((void *) data, d);
  260. } // MOJOSHADER_internal_include_close
  261. #endif // !MOJOSHADER_FORCE_INCLUDE_CALLBACKS
  262. // !!! FIXME: maybe use these pool magic elsewhere?
  263. // !!! FIXME: maybe just get rid of this? (maybe the fragmentation isn't a big deal?)
  264. // Pool stuff...
  265. // ugh, I hate this macro salsa.
  266. #define FREE_POOL(type, poolname) \
  267. static void free_##poolname##_pool(Context *ctx) { \
  268. type *item = ctx->poolname##_pool; \
  269. while (item != NULL) { \
  270. type *next = item->next; \
  271. Free(ctx, item); \
  272. item = next; \
  273. } \
  274. }
  275. #define GET_POOL(type, poolname) \
  276. static type *get_##poolname(Context *ctx) { \
  277. type *retval = ctx->poolname##_pool; \
  278. if (retval != NULL) \
  279. ctx->poolname##_pool = retval->next; \
  280. else \
  281. retval = (type *) Malloc(ctx, sizeof (type)); \
  282. if (retval != NULL) \
  283. memset(retval, '\0', sizeof (type)); \
  284. return retval; \
  285. }
  286. #define PUT_POOL(type, poolname) \
  287. static void put_##poolname(Context *ctx, type *item) { \
  288. item->next = ctx->poolname##_pool; \
  289. ctx->poolname##_pool = item; \
  290. }
  291. #define IMPLEMENT_POOL(type, poolname) \
  292. FREE_POOL(type, poolname) \
  293. GET_POOL(type, poolname) \
  294. PUT_POOL(type, poolname)
  295. IMPLEMENT_POOL(Conditional, conditional)
  296. IMPLEMENT_POOL(IncludeState, include)
  297. IMPLEMENT_POOL(Define, define)
  298. // Preprocessor define hashtable stuff...
  299. // !!! FIXME: why isn't this using mojoshader_common.c's code?
  300. // this is djb's xor hashing function.
  301. static inline uint32 hash_string_djbxor(const char *sym)
  302. {
  303. register uint32 hash = 5381;
  304. while (*sym)
  305. hash = ((hash << 5) + hash) ^ *(sym++);
  306. return hash;
  307. } // hash_string_djbxor
  308. static inline uint8 hash_define(const char *sym)
  309. {
  310. return (uint8) hash_string_djbxor(sym);
  311. } // hash_define
  312. static int add_define(Context *ctx, const char *sym, const char *val,
  313. char **parameters, int paramcount)
  314. {
  315. const uint8 hash = hash_define(sym);
  316. Define *bucket = ctx->define_hashtable[hash];
  317. while (bucket)
  318. {
  319. if (strcmp(bucket->identifier, sym) == 0)
  320. {
  321. failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
  322. // !!! FIXME: gcc reports the location of previous #define here.
  323. return 0;
  324. } // if
  325. bucket = bucket->next;
  326. } // while
  327. bucket = get_define(ctx);
  328. if (bucket == NULL)
  329. return 0;
  330. bucket->definition = val;
  331. bucket->original = NULL;
  332. bucket->identifier = sym;
  333. bucket->parameters = (const char **) parameters;
  334. bucket->paramcount = paramcount;
  335. bucket->next = ctx->define_hashtable[hash];
  336. ctx->define_hashtable[hash] = bucket;
  337. return 1;
  338. } // add_define
  339. static void free_define(Context *ctx, Define *def)
  340. {
  341. if (def != NULL)
  342. {
  343. int i;
  344. for (i = 0; i < def->paramcount; i++)
  345. Free(ctx, (void *) def->parameters[i]);
  346. Free(ctx, (void *) def->parameters);
  347. Free(ctx, (void *) def->identifier);
  348. Free(ctx, (void *) def->definition);
  349. Free(ctx, (void *) def->original);
  350. put_define(ctx, def);
  351. } // if
  352. } // free_define
  353. static int remove_define(Context *ctx, const char *sym)
  354. {
  355. const uint8 hash = hash_define(sym);
  356. Define *bucket = ctx->define_hashtable[hash];
  357. Define *prev = NULL;
  358. while (bucket)
  359. {
  360. if (strcmp(bucket->identifier, sym) == 0)
  361. {
  362. if (prev == NULL)
  363. ctx->define_hashtable[hash] = bucket->next;
  364. else
  365. prev->next = bucket->next;
  366. free_define(ctx, bucket);
  367. return 1;
  368. } // if
  369. prev = bucket;
  370. bucket = bucket->next;
  371. } // while
  372. return 0;
  373. } // remove_define
  374. static const Define *find_define(Context *ctx, const char *sym)
  375. {
  376. if ( (ctx->file_macro) && (strcmp(sym, "__FILE__") == 0) )
  377. {
  378. Free(ctx, (char *) ctx->file_macro->definition);
  379. const IncludeState *state = ctx->include_stack;
  380. const char *fname = state ? state->filename : "";
  381. const size_t len = strlen(fname) + 2;
  382. char *str = (char *) Malloc(ctx, len);
  383. if (!str)
  384. return NULL;
  385. str[0] = '\"';
  386. memcpy(str + 1, fname, len - 2);
  387. str[len - 1] = '\"';
  388. ctx->file_macro->definition = str;
  389. return ctx->file_macro;
  390. } // if
  391. else if ( (ctx->line_macro) && (strcmp(sym, "__LINE__") == 0) )
  392. {
  393. Free(ctx, (char *) ctx->line_macro->definition);
  394. const IncludeState *state = ctx->include_stack;
  395. const size_t bufsize = 32;
  396. char *str = (char *) Malloc(ctx, bufsize);
  397. if (!str)
  398. return 0;
  399. const size_t len = snprintf(str, bufsize, "%u", state->line);
  400. assert(len < bufsize);
  401. ctx->line_macro->definition = str;
  402. return ctx->line_macro;
  403. } // else
  404. const uint8 hash = hash_define(sym);
  405. Define *bucket = ctx->define_hashtable[hash];
  406. while (bucket)
  407. {
  408. if (strcmp(bucket->identifier, sym) == 0)
  409. return bucket;
  410. bucket = bucket->next;
  411. } // while
  412. return NULL;
  413. } // find_define
  414. static const Define *find_define_by_token(Context *ctx)
  415. {
  416. IncludeState *state = ctx->include_stack;
  417. assert(state->tokenval == TOKEN_IDENTIFIER);
  418. char *sym = (char *) alloca(state->tokenlen+1);
  419. memcpy(sym, state->token, state->tokenlen);
  420. sym[state->tokenlen] = '\0';
  421. return find_define(ctx, sym);
  422. } // find_define_by_token
  423. static const Define *find_macro_arg(const IncludeState *state,
  424. const Define *defines)
  425. {
  426. const Define *def = NULL;
  427. char *sym = (char *) alloca(state->tokenlen + 1);
  428. memcpy(sym, state->token, state->tokenlen);
  429. sym[state->tokenlen] = '\0';
  430. for (def = defines; def != NULL; def = def->next)
  431. {
  432. assert(def->parameters == NULL); // args can't have args!
  433. assert(def->paramcount == 0); // args can't have args!
  434. if (strcmp(def->identifier, sym) == 0)
  435. break;
  436. } // while
  437. return def;
  438. } // find_macro_arg
  439. static void put_all_defines(Context *ctx)
  440. {
  441. size_t i;
  442. for (i = 0; i < STATICARRAYLEN(ctx->define_hashtable); i++)
  443. {
  444. Define *bucket = ctx->define_hashtable[i];
  445. ctx->define_hashtable[i] = NULL;
  446. while (bucket)
  447. {
  448. Define *next = bucket->next;
  449. free_define(ctx, bucket);
  450. bucket = next;
  451. } // while
  452. } // for
  453. } // put_all_defines
  454. static int push_source(Context *ctx, const char *fname, const char *source,
  455. unsigned int srclen, unsigned int linenum,
  456. MOJOSHADER_includeClose close_callback)
  457. {
  458. IncludeState *state = get_include(ctx);
  459. if (state == NULL)
  460. return 0;
  461. if (fname != NULL)
  462. {
  463. state->filename = stringcache(ctx->filename_cache, fname);
  464. if (state->filename == NULL)
  465. {
  466. put_include(ctx, state);
  467. return 0;
  468. } // if
  469. } // if
  470. state->close_callback = close_callback;
  471. state->source_base = source;
  472. state->source = source;
  473. state->token = source;
  474. state->tokenval = ((Token) '\n');
  475. state->orig_length = srclen;
  476. state->bytes_left = srclen;
  477. state->line = linenum;
  478. state->next = ctx->include_stack;
  479. state->asm_comments = ctx->asm_comments;
  480. print_debug_lexing_position(state);
  481. ctx->include_stack = state;
  482. return 1;
  483. } // push_source
  484. static void pop_source(Context *ctx)
  485. {
  486. IncludeState *state = ctx->include_stack;
  487. assert(state != NULL); // more pops than pushes!
  488. if (state == NULL)
  489. return;
  490. if (state->close_callback)
  491. {
  492. state->close_callback(state->source_base, ctx->malloc,
  493. ctx->free, ctx->malloc_data);
  494. } // if
  495. // state->filename is a pointer to the filename cache; don't free it here!
  496. Conditional *cond = state->conditional_stack;
  497. while (cond)
  498. {
  499. Conditional *next = cond->next;
  500. put_conditional(ctx, cond);
  501. cond = next;
  502. } // while
  503. ctx->include_stack = state->next;
  504. print_debug_lexing_position(ctx->include_stack);
  505. put_include(ctx, state);
  506. } // pop_source
  507. static void close_define_include(const char *data, MOJOSHADER_malloc m,
  508. MOJOSHADER_free f, void *d)
  509. {
  510. f((void *) data, d);
  511. } // close_define_include
  512. Preprocessor *preprocessor_start(const char *fname, const char *source,
  513. unsigned int sourcelen,
  514. MOJOSHADER_includeOpen open_callback,
  515. MOJOSHADER_includeClose close_callback,
  516. const MOJOSHADER_preprocessorDefine *defines,
  517. unsigned int define_count, int asm_comments,
  518. MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  519. {
  520. int okay = 1;
  521. unsigned int i = 0;
  522. // the preprocessor is internal-only, so we verify all these are != NULL.
  523. assert(m != NULL);
  524. assert(f != NULL);
  525. Context *ctx = (Context *) m(sizeof (Context), d);
  526. if (ctx == NULL)
  527. return NULL;
  528. memset(ctx, '\0', sizeof (Context));
  529. ctx->malloc = m;
  530. ctx->free = f;
  531. ctx->malloc_data = d;
  532. ctx->open_callback = open_callback;
  533. ctx->close_callback = close_callback;
  534. ctx->asm_comments = asm_comments;
  535. ctx->filename_cache = stringcache_create(MallocBridge, FreeBridge, ctx);
  536. okay = ((okay) && (ctx->filename_cache != NULL));
  537. ctx->file_macro = get_define(ctx);
  538. okay = ((okay) && (ctx->file_macro != NULL));
  539. if ((okay) && (ctx->file_macro))
  540. okay = ((ctx->file_macro->identifier = StrDup(ctx, "__FILE__")) != 0);
  541. ctx->line_macro = get_define(ctx);
  542. okay = ((okay) && (ctx->line_macro != NULL));
  543. if ((okay) && (ctx->line_macro))
  544. okay = ((ctx->line_macro->identifier = StrDup(ctx, "__LINE__")) != 0);
  545. // let the usual preprocessor parser sort these out.
  546. char *define_include = NULL;
  547. unsigned int define_include_len = 0;
  548. if ((okay) && (define_count > 0))
  549. {
  550. Buffer *predefbuf = buffer_create(256, MallocBridge, FreeBridge, ctx);
  551. okay = okay && (predefbuf != NULL);
  552. for (i = 0; okay && (i < define_count); i++)
  553. {
  554. okay = okay && buffer_append_fmt(predefbuf, "#define %s %s\n",
  555. defines[i].identifier, defines[i].definition);
  556. } // for
  557. define_include_len = buffer_size(predefbuf);
  558. if (define_include_len > 0)
  559. {
  560. define_include = buffer_flatten(predefbuf);
  561. okay = okay && (define_include != NULL);
  562. } // if
  563. buffer_destroy(predefbuf);
  564. } // if
  565. if ((okay) && (!push_source(ctx,fname,source,sourcelen,1,NULL)))
  566. okay = 0;
  567. if ((okay) && (define_include_len > 0))
  568. {
  569. assert(define_include != NULL);
  570. okay = push_source(ctx, "<predefined macros>", define_include,
  571. define_include_len, 1, close_define_include);
  572. } // if
  573. if (!okay)
  574. {
  575. preprocessor_end((Preprocessor *) ctx);
  576. return NULL;
  577. } // if
  578. return (Preprocessor *) ctx;
  579. } // preprocessor_start
  580. void preprocessor_end(Preprocessor *_ctx)
  581. {
  582. Context *ctx = (Context *) _ctx;
  583. if (ctx == NULL)
  584. return;
  585. while (ctx->include_stack != NULL)
  586. pop_source(ctx);
  587. put_all_defines(ctx);
  588. if (ctx->filename_cache != NULL)
  589. stringcache_destroy(ctx->filename_cache);
  590. free_define(ctx, ctx->file_macro);
  591. free_define(ctx, ctx->line_macro);
  592. free_define_pool(ctx);
  593. free_conditional_pool(ctx);
  594. free_include_pool(ctx);
  595. Free(ctx, ctx);
  596. } // preprocessor_end
  597. int preprocessor_outofmemory(Preprocessor *_ctx)
  598. {
  599. Context *ctx = (Context *) _ctx;
  600. return ctx->out_of_memory;
  601. } // preprocessor_outofmemory
  602. static inline void pushback(IncludeState *state)
  603. {
  604. #if DEBUG_PREPROCESSOR
  605. printf("PREPROCESSOR PUSHBACK\n");
  606. #endif
  607. assert(!state->pushedback);
  608. state->pushedback = 1;
  609. } // pushback
  610. static Token lexer(IncludeState *state)
  611. {
  612. if (!state->pushedback)
  613. return preprocessor_lexer(state);
  614. state->pushedback = 0;
  615. return state->tokenval;
  616. } // lexer
  617. // !!! FIXME: parsing fails on preprocessor directives should skip rest of line.
  618. static int require_newline(IncludeState *state)
  619. {
  620. const Token token = lexer(state);
  621. pushback(state); // rewind no matter what.
  622. return ( (token == TOKEN_INCOMPLETE_COMMENT) || // call it an eol.
  623. (token == ((Token) '\n')) || (token == TOKEN_EOI) );
  624. } // require_newline
  625. // !!! FIXME: didn't we implement this by hand elsewhere?
  626. static int token_to_int(IncludeState *state)
  627. {
  628. assert(state->tokenval == TOKEN_INT_LITERAL);
  629. char *buf = (char *) alloca(state->tokenlen+1);
  630. memcpy(buf, state->token, state->tokenlen);
  631. buf[state->tokenlen] = '\0';
  632. return atoi(buf);
  633. } // token_to_int
  634. static void handle_pp_include(Context *ctx)
  635. {
  636. IncludeState *state = ctx->include_stack;
  637. Token token = lexer(state);
  638. MOJOSHADER_includeType incltype;
  639. char *filename = NULL;
  640. int bogus = 0;
  641. if (token == TOKEN_STRING_LITERAL)
  642. incltype = MOJOSHADER_INCLUDETYPE_LOCAL;
  643. else if (token == ((Token) '<'))
  644. {
  645. incltype = MOJOSHADER_INCLUDETYPE_SYSTEM;
  646. // can't use lexer, since every byte between the < > pair is
  647. // considered part of the filename. :/
  648. while (!bogus)
  649. {
  650. if ( !(bogus = (state->bytes_left == 0)) )
  651. {
  652. const char ch = *state->source;
  653. if ( !(bogus = ((ch == '\r') || (ch == '\n'))) )
  654. {
  655. state->source++;
  656. state->bytes_left--;
  657. if (ch == '>')
  658. break;
  659. } // if
  660. } // if
  661. } // while
  662. } // else if
  663. else
  664. {
  665. bogus = 1;
  666. } // else
  667. if (!bogus)
  668. {
  669. state->token++; // skip '<' or '\"'...
  670. const unsigned int len = ((unsigned int) (state->source-state->token));
  671. filename = (char *) alloca(len);
  672. memcpy(filename, state->token, len-1);
  673. filename[len-1] = '\0';
  674. bogus = !require_newline(state);
  675. } // if
  676. if (bogus)
  677. {
  678. fail(ctx, "Invalid #include directive");
  679. return;
  680. } // else
  681. const char *newdata = NULL;
  682. unsigned int newbytes = 0;
  683. if ((ctx->open_callback == NULL) || (ctx->close_callback == NULL))
  684. {
  685. fail(ctx, "Saw #include, but no include callbacks defined");
  686. return;
  687. } // if
  688. if (!ctx->open_callback(incltype, filename, state->source_base,
  689. &newdata, &newbytes, ctx->malloc,
  690. ctx->free, ctx->malloc_data))
  691. {
  692. fail(ctx, "Include callback failed"); // !!! FIXME: better error
  693. return;
  694. } // if
  695. MOJOSHADER_includeClose callback = ctx->close_callback;
  696. if (!push_source(ctx, filename, newdata, newbytes, 1, callback))
  697. {
  698. assert(ctx->out_of_memory);
  699. ctx->close_callback(newdata, ctx->malloc, ctx->free, ctx->malloc_data);
  700. } // if
  701. } // handle_pp_include
  702. static void handle_pp_line(Context *ctx)
  703. {
  704. IncludeState *state = ctx->include_stack;
  705. char *filename = NULL;
  706. int linenum = 0;
  707. int bogus = 0;
  708. if (lexer(state) != TOKEN_INT_LITERAL)
  709. bogus = 1;
  710. else
  711. linenum = token_to_int(state);
  712. if (!bogus)
  713. {
  714. Token t = lexer(state);
  715. if (t == ((Token) '\n'))
  716. {
  717. state->line = linenum;
  718. return;
  719. }
  720. bogus = (t != TOKEN_STRING_LITERAL);
  721. }
  722. if (!bogus)
  723. {
  724. state->token++; // skip '\"'...
  725. filename = (char *) alloca(state->tokenlen);
  726. memcpy(filename, state->token, state->tokenlen-1);
  727. filename[state->tokenlen-1] = '\0';
  728. bogus = !require_newline(state);
  729. } // if
  730. if (bogus)
  731. {
  732. fail(ctx, "Invalid #line directive");
  733. return;
  734. } // if
  735. const char *cached = stringcache(ctx->filename_cache, filename);
  736. state->filename = cached; // may be NULL if stringcache() failed.
  737. state->line = linenum;
  738. } // handle_pp_line
  739. static void handle_pp_error(Context *ctx)
  740. {
  741. IncludeState *state = ctx->include_stack;
  742. char *ptr = ctx->failstr;
  743. int avail = sizeof (ctx->failstr) - 1;
  744. int cpy = 0;
  745. int done = 0;
  746. const char *prefix = "#error";
  747. const size_t prefixlen = strlen(prefix);
  748. strcpy(ctx->failstr, prefix);
  749. avail -= prefixlen;
  750. ptr += prefixlen;
  751. state->report_whitespace = 1;
  752. while (!done)
  753. {
  754. const Token token = lexer(state);
  755. switch (token)
  756. {
  757. case ((Token) '\n'):
  758. state->line--; // make sure error is on the right line.
  759. // fall through!
  760. case TOKEN_INCOMPLETE_COMMENT:
  761. case TOKEN_EOI:
  762. pushback(state); // move back so we catch this later.
  763. done = 1;
  764. break;
  765. case ((Token) ' '):
  766. if (!avail)
  767. break;
  768. *(ptr++) = ' ';
  769. avail--;
  770. break;
  771. default:
  772. cpy = Min(avail, (int) state->tokenlen);
  773. if (cpy)
  774. memcpy(ptr, state->token, cpy);
  775. ptr += cpy;
  776. avail -= cpy;
  777. break;
  778. } // switch
  779. } // while
  780. *ptr = '\0';
  781. state->report_whitespace = 0;
  782. ctx->isfail = 1;
  783. } // handle_pp_error
  784. static void handle_pp_define(Context *ctx)
  785. {
  786. IncludeState *state = ctx->include_stack;
  787. int done = 0;
  788. if (lexer(state) != TOKEN_IDENTIFIER)
  789. {
  790. fail(ctx, "Macro names must be identifiers");
  791. return;
  792. } // if
  793. char *definition = NULL;
  794. char *sym = (char *) Malloc(ctx, state->tokenlen+1);
  795. if (sym == NULL)
  796. return;
  797. memcpy(sym, state->token, state->tokenlen);
  798. sym[state->tokenlen] = '\0';
  799. if (strcmp(sym, "defined") == 0)
  800. {
  801. Free(ctx, sym);
  802. fail(ctx, "'defined' cannot be used as a macro name");
  803. return;
  804. } // if
  805. // Don't treat these symbols as special anymore if they get (re)#defined.
  806. if (strcmp(sym, "__FILE__") == 0)
  807. {
  808. if (ctx->file_macro)
  809. {
  810. failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
  811. free_define(ctx, ctx->file_macro);
  812. ctx->file_macro = NULL;
  813. } // if
  814. } // if
  815. else if (strcmp(sym, "__LINE__") == 0)
  816. {
  817. if (ctx->line_macro)
  818. {
  819. failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
  820. free_define(ctx, ctx->line_macro);
  821. ctx->line_macro = NULL;
  822. } // if
  823. } // else if
  824. // #define a(b) is different than #define a (b) :(
  825. state->report_whitespace = 1;
  826. lexer(state);
  827. state->report_whitespace = 0;
  828. int params = 0;
  829. char **idents = NULL;
  830. static const char space = ' ';
  831. if (state->tokenval == ((Token) ' '))
  832. lexer(state); // skip it.
  833. else if (state->tokenval == ((Token) '('))
  834. {
  835. IncludeState saved;
  836. memcpy(&saved, state, sizeof (IncludeState));
  837. while (1)
  838. {
  839. if (lexer(state) != TOKEN_IDENTIFIER)
  840. break;
  841. params++;
  842. if (lexer(state) != ((Token) ','))
  843. break;
  844. } // while
  845. if (state->tokenval != ((Token) ')'))
  846. {
  847. fail(ctx, "syntax error in macro parameter list");
  848. goto handle_pp_define_failed;
  849. } // if
  850. if (params == 0) // special case for void args: "#define a() b"
  851. params = -1;
  852. else
  853. {
  854. idents = (char **) Malloc(ctx, sizeof (char *) * params);
  855. if (idents == NULL)
  856. goto handle_pp_define_failed;
  857. // roll all the way back, do it again.
  858. memcpy(state, &saved, sizeof (IncludeState));
  859. memset(idents, '\0', sizeof (char *) * params);
  860. int i;
  861. for (i = 0; i < params; i++)
  862. {
  863. lexer(state);
  864. assert(state->tokenval == TOKEN_IDENTIFIER);
  865. char *dst = (char *) Malloc(ctx, state->tokenlen+1);
  866. if (dst == NULL)
  867. break;
  868. memcpy(dst, state->token, state->tokenlen);
  869. dst[state->tokenlen] = '\0';
  870. idents[i] = dst;
  871. if (i < (params-1))
  872. {
  873. lexer(state);
  874. assert(state->tokenval == ((Token) ','));
  875. } // if
  876. } // for
  877. if (i != params)
  878. {
  879. assert(ctx->out_of_memory);
  880. goto handle_pp_define_failed;
  881. } // if
  882. lexer(state);
  883. assert(state->tokenval == ((Token) ')'));
  884. } // else
  885. lexer(state);
  886. } // else if
  887. pushback(state);
  888. Buffer *buffer = buffer_create(128, MallocBridge, FreeBridge, ctx);
  889. state->report_whitespace = 1;
  890. while ((!done) && (!ctx->out_of_memory))
  891. {
  892. const Token token = lexer(state);
  893. switch (token)
  894. {
  895. case TOKEN_INCOMPLETE_COMMENT:
  896. case TOKEN_EOI:
  897. pushback(state); // move back so we catch this later.
  898. done = 1;
  899. break;
  900. case ((Token) '\n'):
  901. done = 1;
  902. break;
  903. case ((Token) ' '): // may not actually point to ' '.
  904. assert(buffer_size(buffer) > 0);
  905. buffer_append(buffer, &space, 1);
  906. break;
  907. default:
  908. buffer_append(buffer, state->token, state->tokenlen);
  909. break;
  910. } // switch
  911. } // while
  912. state->report_whitespace = 0;
  913. size_t buflen = buffer_size(buffer) + 1;
  914. if (!ctx->out_of_memory)
  915. definition = buffer_flatten(buffer);
  916. buffer_destroy(buffer);
  917. if (ctx->out_of_memory)
  918. goto handle_pp_define_failed;
  919. int hashhash_error = 0;
  920. if ((buflen > 2) && (definition[0] == '#') && (definition[1] == '#'))
  921. {
  922. hashhash_error = 1;
  923. buflen -= 2;
  924. memmove(definition, definition + 2, buflen);
  925. } // if
  926. if (buflen > 2)
  927. {
  928. char *ptr = (definition + buflen) - 2;
  929. if (*ptr == ' ')
  930. {
  931. ptr--;
  932. buflen--;
  933. } // if
  934. if ((buflen > 2) && (ptr[0] == '#') && (ptr[-1] == '#'))
  935. {
  936. hashhash_error = 1;
  937. buflen -= 2;
  938. ptr[-1] = '\0';
  939. } // if
  940. } // if
  941. if (hashhash_error)
  942. fail(ctx, "'##' cannot appear at either end of a macro expansion");
  943. assert(done);
  944. if (!add_define(ctx, sym, definition, idents, params))
  945. goto handle_pp_define_failed;
  946. return;
  947. handle_pp_define_failed:
  948. Free(ctx, sym);
  949. Free(ctx, definition);
  950. if (idents != NULL)
  951. {
  952. while (params--)
  953. Free(ctx, idents[params]);
  954. } // if
  955. Free(ctx, idents);
  956. } // handle_pp_define
  957. static void handle_pp_undef(Context *ctx)
  958. {
  959. IncludeState *state = ctx->include_stack;
  960. if (lexer(state) != TOKEN_IDENTIFIER)
  961. {
  962. fail(ctx, "Macro names must be indentifiers");
  963. return;
  964. } // if
  965. char *sym = (char *) alloca(state->tokenlen+1);
  966. memcpy(sym, state->token, state->tokenlen);
  967. sym[state->tokenlen] = '\0';
  968. if (!require_newline(state))
  969. {
  970. fail(ctx, "Invalid #undef directive");
  971. return;
  972. } // if
  973. if (strcmp(sym, "__FILE__") == 0)
  974. {
  975. if (ctx->file_macro)
  976. {
  977. failf(ctx, "undefining \"%s\"", sym); // !!! FIXME: should be warning.
  978. free_define(ctx, ctx->file_macro);
  979. ctx->file_macro = NULL;
  980. } // if
  981. } // if
  982. else if (strcmp(sym, "__LINE__") == 0)
  983. {
  984. if (ctx->line_macro)
  985. {
  986. failf(ctx, "undefining \"%s\"", sym); // !!! FIXME: should be warning.
  987. free_define(ctx, ctx->line_macro);
  988. ctx->line_macro = NULL;
  989. } // if
  990. } // if
  991. remove_define(ctx, sym);
  992. } // handle_pp_undef
  993. static Conditional *_handle_pp_ifdef(Context *ctx, const Token type)
  994. {
  995. IncludeState *state = ctx->include_stack;
  996. assert((type == TOKEN_PP_IFDEF) || (type == TOKEN_PP_IFNDEF));
  997. if (lexer(state) != TOKEN_IDENTIFIER)
  998. {
  999. fail(ctx, "Macro names must be indentifiers");
  1000. return NULL;
  1001. } // if
  1002. char *sym = (char *) alloca(state->tokenlen+1);
  1003. memcpy(sym, state->token, state->tokenlen);
  1004. sym[state->tokenlen] = '\0';
  1005. if (!require_newline(state))
  1006. {
  1007. if (type == TOKEN_PP_IFDEF)
  1008. fail(ctx, "Invalid #ifdef directive");
  1009. else
  1010. fail(ctx, "Invalid #ifndef directive");
  1011. return NULL;
  1012. } // if
  1013. Conditional *conditional = get_conditional(ctx);
  1014. assert((conditional != NULL) || (ctx->out_of_memory));
  1015. if (conditional == NULL)
  1016. return NULL;
  1017. Conditional *parent = state->conditional_stack;
  1018. const int found = (find_define(ctx, sym) != NULL);
  1019. const int chosen = (type == TOKEN_PP_IFDEF) ? found : !found;
  1020. const int skipping = ( (((parent) && (parent->skipping))) || (!chosen) );
  1021. conditional->type = type;
  1022. conditional->linenum = state->line - 1;
  1023. conditional->skipping = skipping;
  1024. conditional->chosen = chosen;
  1025. conditional->next = parent;
  1026. state->conditional_stack = conditional;
  1027. return conditional;
  1028. } // _handle_pp_ifdef
  1029. static inline void handle_pp_ifdef(Context *ctx)
  1030. {
  1031. _handle_pp_ifdef(ctx, TOKEN_PP_IFDEF);
  1032. } // handle_pp_ifdef
  1033. static inline void handle_pp_ifndef(Context *ctx)
  1034. {
  1035. _handle_pp_ifdef(ctx, TOKEN_PP_IFNDEF);
  1036. } // handle_pp_ifndef
  1037. static int replace_and_push_macro(Context *ctx, const Define *def,
  1038. const Define *params)
  1039. {
  1040. char *final = NULL;
  1041. // We push the #define and lex it, building a buffer with argument
  1042. // replacement, stringification, and concatenation.
  1043. Buffer *buffer = buffer_create(128, MallocBridge, FreeBridge, ctx);
  1044. if (buffer == NULL)
  1045. return 0;
  1046. IncludeState *state = ctx->include_stack;
  1047. if (!push_source(ctx, state->filename, def->definition,
  1048. strlen(def->definition), state->line, NULL))
  1049. {
  1050. buffer_destroy(buffer);
  1051. return 0;
  1052. } // if
  1053. state = ctx->include_stack;
  1054. while (lexer(state) != TOKEN_EOI)
  1055. {
  1056. int wantorig = 0;
  1057. const Define *arg = NULL;
  1058. // put a space between tokens if we're not concatenating.
  1059. if (state->tokenval == TOKEN_HASHHASH) // concatenate?
  1060. {
  1061. wantorig = 1;
  1062. lexer(state);
  1063. assert(state->tokenval != TOKEN_EOI);
  1064. } // if
  1065. else
  1066. {
  1067. if (buffer_size(buffer) > 0)
  1068. {
  1069. if (!buffer_append(buffer, " ", 1))
  1070. goto replace_and_push_macro_failed;
  1071. } // if
  1072. } // else
  1073. const char *data = state->token;
  1074. unsigned int len = state->tokenlen;
  1075. if (state->tokenval == TOKEN_HASH) // stringify?
  1076. {
  1077. lexer(state);
  1078. assert(state->tokenval != TOKEN_EOI); // we checked for this.
  1079. if (!buffer_append(buffer, "\"", 1))
  1080. goto replace_and_push_macro_failed;
  1081. if (state->tokenval == TOKEN_IDENTIFIER)
  1082. {
  1083. arg = find_macro_arg(state, params);
  1084. if (arg != NULL)
  1085. {
  1086. data = arg->original;
  1087. len = strlen(data);
  1088. } // if
  1089. } // if
  1090. if (!buffer_append(buffer, data, len))
  1091. goto replace_and_push_macro_failed;
  1092. if (!buffer_append(buffer, "\"", 1))
  1093. goto replace_and_push_macro_failed;
  1094. continue;
  1095. } // if
  1096. if (state->tokenval == TOKEN_IDENTIFIER)
  1097. {
  1098. arg = find_macro_arg(state, params);
  1099. if (arg != NULL)
  1100. {
  1101. if (!wantorig)
  1102. {
  1103. wantorig = (lexer(state) == TOKEN_HASHHASH);
  1104. pushback(state);
  1105. } // if
  1106. data = wantorig ? arg->original : arg->definition;
  1107. len = strlen(data);
  1108. } // if
  1109. } // if
  1110. if (!buffer_append(buffer, data, len))
  1111. goto replace_and_push_macro_failed;
  1112. } // while
  1113. final = buffer_flatten(buffer);
  1114. if (!final)
  1115. goto replace_and_push_macro_failed;
  1116. buffer_destroy(buffer);
  1117. pop_source(ctx); // ditch the macro.
  1118. state = ctx->include_stack;
  1119. if (!push_source(ctx, state->filename, final, strlen(final), state->line,
  1120. close_define_include))
  1121. {
  1122. Free(ctx, final);
  1123. return 0;
  1124. } // if
  1125. return 1;
  1126. replace_and_push_macro_failed:
  1127. pop_source(ctx);
  1128. buffer_destroy(buffer);
  1129. return 0;
  1130. } // replace_and_push_macro
  1131. static int handle_macro_args(Context *ctx, const char *sym, const Define *def)
  1132. {
  1133. int retval = 0;
  1134. IncludeState *state = ctx->include_stack;
  1135. Define *params = NULL;
  1136. const int expected = (def->paramcount < 0) ? 0 : def->paramcount;
  1137. int saw_params = 0;
  1138. IncludeState saved; // can't pushback, we need the original token.
  1139. memcpy(&saved, state, sizeof (IncludeState));
  1140. if (lexer(state) != ((Token) '('))
  1141. {
  1142. memcpy(state, &saved, sizeof (IncludeState));
  1143. goto handle_macro_args_failed; // gcc abandons replacement, too.
  1144. } // if
  1145. state->report_whitespace = 1;
  1146. int void_call = 0;
  1147. int paren = 1;
  1148. while (paren > 0)
  1149. {
  1150. Buffer *buffer = buffer_create(128, MallocBridge, FreeBridge, ctx);
  1151. Buffer *origbuffer = buffer_create(128, MallocBridge, FreeBridge, ctx);
  1152. Token t = lexer(state);
  1153. assert(!void_call);
  1154. while (1)
  1155. {
  1156. const char *origexpr = state->token;
  1157. unsigned int origexprlen = state->tokenlen;
  1158. const char *expr = state->token;
  1159. unsigned int exprlen = state->tokenlen;
  1160. if (t == ((Token) '('))
  1161. paren++;
  1162. else if (t == ((Token) ')'))
  1163. {
  1164. paren--;
  1165. if (paren < 1) // end of macro?
  1166. break;
  1167. } // else if
  1168. else if (t == ((Token) ','))
  1169. {
  1170. if (paren == 1) // new macro arg?
  1171. break;
  1172. } // else if
  1173. else if (t == ((Token) ' '))
  1174. {
  1175. // don't add whitespace to the start, so we recognize
  1176. // void calls correctly.
  1177. origexpr = expr = " ";
  1178. origexprlen = (buffer_size(origbuffer) == 0) ? 0 : 1;
  1179. exprlen = (buffer_size(buffer) == 0) ? 0 : 1;
  1180. } // else if
  1181. else if (t == TOKEN_IDENTIFIER)
  1182. {
  1183. const Define *def = find_define_by_token(ctx);
  1184. // don't replace macros with arguments so they replace correctly, later.
  1185. if ((def) && (def->paramcount == 0))
  1186. {
  1187. expr = def->definition;
  1188. exprlen = strlen(def->definition);
  1189. } // if
  1190. } // else if
  1191. else if ((t == TOKEN_INCOMPLETE_COMMENT) || (t == TOKEN_EOI))
  1192. {
  1193. pushback(state);
  1194. fail(ctx, "Unterminated macro list");
  1195. goto handle_macro_args_failed;
  1196. } // else if
  1197. assert(expr != NULL);
  1198. if (!buffer_append(buffer, expr, exprlen))
  1199. goto handle_macro_args_failed;
  1200. if (!buffer_append(origbuffer, origexpr, origexprlen))
  1201. goto handle_macro_args_failed;
  1202. t = lexer(state);
  1203. } // while
  1204. if (buffer_size(buffer) == 0)
  1205. void_call = ((saw_params == 0) && (paren == 0));
  1206. if (saw_params < expected)
  1207. {
  1208. const int origdeflen = (int) buffer_size(origbuffer);
  1209. char *origdefinition = buffer_flatten(origbuffer);
  1210. const int deflen = (int) buffer_size(buffer);
  1211. char *definition = buffer_flatten(buffer);
  1212. Define *p = get_define(ctx);
  1213. if ((!origdefinition) || (!definition) || (!p))
  1214. {
  1215. Free(ctx, origdefinition);
  1216. Free(ctx, definition);
  1217. buffer_destroy(origbuffer);
  1218. buffer_destroy(buffer);
  1219. free_define(ctx, p);
  1220. goto handle_macro_args_failed;
  1221. } // if
  1222. // trim any whitespace from the end of the string...
  1223. int i;
  1224. for (i = deflen - 1; i >= 0; i--)
  1225. {
  1226. if (definition[i] == ' ')
  1227. definition[i] = '\0';
  1228. else
  1229. break;
  1230. } // for
  1231. for (i = origdeflen - 1; i >= 0; i--)
  1232. {
  1233. if (origdefinition[i] == ' ')
  1234. origdefinition[i] = '\0';
  1235. else
  1236. break;
  1237. } // for
  1238. p->identifier = def->parameters[saw_params];
  1239. p->definition = definition;
  1240. p->original = origdefinition;
  1241. p->next = params;
  1242. params = p;
  1243. } // if
  1244. buffer_destroy(buffer);
  1245. buffer_destroy(origbuffer);
  1246. saw_params++;
  1247. } // while
  1248. assert(paren == 0);
  1249. // "a()" should match "#define a()" ...
  1250. if ((expected == 0) && (saw_params == 1) && (void_call))
  1251. {
  1252. assert(params == NULL);
  1253. saw_params = 0;
  1254. } // if
  1255. if (saw_params != expected)
  1256. {
  1257. failf(ctx, "macro '%s' passed %d arguments, but requires %d",
  1258. sym, saw_params, expected);
  1259. goto handle_macro_args_failed;
  1260. } // if
  1261. // this handles arg replacement and the '##' and '#' operators.
  1262. retval = replace_and_push_macro(ctx, def, params);
  1263. handle_macro_args_failed:
  1264. while (params)
  1265. {
  1266. Define *next = params->next;
  1267. params->identifier = NULL;
  1268. free_define(ctx, params);
  1269. params = next;
  1270. } // while
  1271. state->report_whitespace = 0;
  1272. return retval;
  1273. } // handle_macro_args
  1274. static int handle_pp_identifier(Context *ctx)
  1275. {
  1276. if (ctx->recursion_count++ >= 256) // !!! FIXME: gcc can figure this out.
  1277. {
  1278. fail(ctx, "Recursing macros");
  1279. return 0;
  1280. } // if
  1281. IncludeState *state = ctx->include_stack;
  1282. const char *fname = state->filename;
  1283. const unsigned int line = state->line;
  1284. char *sym = (char *) alloca(state->tokenlen+1);
  1285. memcpy(sym, state->token, state->tokenlen);
  1286. sym[state->tokenlen] = '\0';
  1287. // Is this identifier #defined?
  1288. const Define *def = find_define(ctx, sym);
  1289. if (def == NULL)
  1290. return 0; // just send the token through unchanged.
  1291. else if (def->paramcount != 0)
  1292. return handle_macro_args(ctx, sym, def);
  1293. const size_t deflen = strlen(def->definition);
  1294. return push_source(ctx, fname, def->definition, deflen, line, NULL);
  1295. } // handle_pp_identifier
  1296. static int find_precedence(const Token token)
  1297. {
  1298. // operator precedence, left and right associative...
  1299. typedef struct { int precedence; Token token; } Precedence;
  1300. static const Precedence ops[] = {
  1301. { 0, TOKEN_OROR }, { 1, TOKEN_ANDAND }, { 2, ((Token) '|') },
  1302. { 3, ((Token) '^') }, { 4, ((Token) '&') }, { 5, TOKEN_NEQ },
  1303. { 6, TOKEN_EQL }, { 7, ((Token) '<') }, { 7, ((Token) '>') },
  1304. { 7, TOKEN_LEQ }, { 7, TOKEN_GEQ }, { 8, TOKEN_LSHIFT },
  1305. { 8, TOKEN_RSHIFT }, { 9, ((Token) '-') }, { 9, ((Token) '+') },
  1306. { 10, ((Token) '%') }, { 10, ((Token) '/') }, { 10, ((Token) '*') },
  1307. { 11, TOKEN_PP_UNARY_PLUS }, { 11, TOKEN_PP_UNARY_MINUS },
  1308. { 11, ((Token) '!') }, { 11, ((Token) '~') },
  1309. };
  1310. size_t i;
  1311. for (i = 0; i < STATICARRAYLEN(ops); i++)
  1312. {
  1313. if (ops[i].token == token)
  1314. return ops[i].precedence;
  1315. } // for
  1316. return -1;
  1317. } // find_precedence
  1318. // !!! FIXME: we're using way too much stack space here...
  1319. typedef struct RpnTokens
  1320. {
  1321. int isoperator;
  1322. int value;
  1323. } RpnTokens;
  1324. static long interpret_rpn(const RpnTokens *tokens, int tokencount, int *error)
  1325. {
  1326. long stack[128];
  1327. size_t stacksize = 0;
  1328. *error = 1;
  1329. #define NEED_X_TOKENS(x) do { if (stacksize < x) return 0; } while (0)
  1330. #define BINARY_OPERATION(op) do { \
  1331. NEED_X_TOKENS(2); \
  1332. stack[stacksize-2] = stack[stacksize-2] op stack[stacksize-1]; \
  1333. stacksize--; \
  1334. } while (0)
  1335. #define UNARY_OPERATION(op) do { \
  1336. NEED_X_TOKENS(1); \
  1337. stack[stacksize-1] = op stack[stacksize-1]; \
  1338. } while (0)
  1339. while (tokencount-- > 0)
  1340. {
  1341. if (!tokens->isoperator)
  1342. {
  1343. assert(stacksize < STATICARRAYLEN(stack));
  1344. stack[stacksize++] = (long) tokens->value;
  1345. tokens++;
  1346. continue;
  1347. } // if
  1348. // operators.
  1349. switch (tokens->value)
  1350. {
  1351. case '!': UNARY_OPERATION(!); break;
  1352. case '~': UNARY_OPERATION(~); break;
  1353. case TOKEN_PP_UNARY_MINUS: UNARY_OPERATION(-); break;
  1354. case TOKEN_PP_UNARY_PLUS: UNARY_OPERATION(+); break;
  1355. case TOKEN_OROR: BINARY_OPERATION(||); break;
  1356. case TOKEN_ANDAND: BINARY_OPERATION(&&); break;
  1357. case '|': BINARY_OPERATION(|); break;
  1358. case '^': BINARY_OPERATION(^); break;
  1359. case '&': BINARY_OPERATION(&); break;
  1360. case TOKEN_NEQ: BINARY_OPERATION(!=); break;
  1361. case TOKEN_EQL: BINARY_OPERATION(==); break;
  1362. case '<': BINARY_OPERATION(<); break;
  1363. case '>': BINARY_OPERATION(>); break;
  1364. case TOKEN_LEQ: BINARY_OPERATION(<=); break;
  1365. case TOKEN_GEQ: BINARY_OPERATION(>=); break;
  1366. case TOKEN_LSHIFT: BINARY_OPERATION(<<); break;
  1367. case TOKEN_RSHIFT: BINARY_OPERATION(>>); break;
  1368. case '-': BINARY_OPERATION(-); break;
  1369. case '+': BINARY_OPERATION(+); break;
  1370. case '%': BINARY_OPERATION(%); break;
  1371. case '/': BINARY_OPERATION(/); break;
  1372. case '*': BINARY_OPERATION(*); break;
  1373. default: return 0;
  1374. } // switch
  1375. tokens++;
  1376. } // while
  1377. #undef NEED_X_TOKENS
  1378. #undef BINARY_OPERATION
  1379. #undef UNARY_OPERATION
  1380. if (stacksize != 1)
  1381. return 0;
  1382. *error = 0;
  1383. return stack[0];
  1384. } // interpret_rpn
  1385. // http://en.wikipedia.org/wiki/Shunting_yard_algorithm
  1386. // Convert from infix to postfix, then use this for constant folding.
  1387. // Everything that parses should fold down to a constant value: any
  1388. // identifiers that aren't resolved as macros become zero. Anything we
  1389. // don't explicitly expect becomes a parsing error.
  1390. // returns 1 (true), 0 (false), or -1 (error)
  1391. static int reduce_pp_expression(Context *ctx)
  1392. {
  1393. IncludeState *orig_state = ctx->include_stack;
  1394. RpnTokens output[128];
  1395. Token stack[64];
  1396. Token previous_token = TOKEN_UNKNOWN;
  1397. size_t outputsize = 0;
  1398. size_t stacksize = 0;
  1399. int matched = 0;
  1400. int done = 0;
  1401. #define ADD_TO_OUTPUT(op, val) \
  1402. assert(outputsize < STATICARRAYLEN(output)); \
  1403. output[outputsize].isoperator = op; \
  1404. output[outputsize].value = val; \
  1405. outputsize++;
  1406. #define PUSH_TO_STACK(t) \
  1407. assert(stacksize < STATICARRAYLEN(stack)); \
  1408. stack[stacksize] = t; \
  1409. stacksize++;
  1410. while (!done)
  1411. {
  1412. IncludeState *state = ctx->include_stack;
  1413. Token token = lexer(state);
  1414. int isleft = 1;
  1415. int precedence = -1;
  1416. if ( (token == ((Token) '!')) || (token == ((Token) '~')) )
  1417. isleft = 0;
  1418. else if (token == ((Token) '-'))
  1419. {
  1420. if ((isleft = (previous_token == TOKEN_INT_LITERAL)) == 0)
  1421. token = TOKEN_PP_UNARY_MINUS;
  1422. } // else if
  1423. else if (token == ((Token) '+'))
  1424. {
  1425. if ((isleft = (previous_token == TOKEN_INT_LITERAL)) == 0)
  1426. token = TOKEN_PP_UNARY_PLUS;
  1427. } // else if
  1428. if (token != TOKEN_IDENTIFIER)
  1429. ctx->recursion_count = 0;
  1430. switch (token)
  1431. {
  1432. case TOKEN_EOI:
  1433. if (state != orig_state) // end of a substate, or the expr?
  1434. {
  1435. pop_source(ctx);
  1436. continue; // substate, go again with the parent state.
  1437. } // if
  1438. done = 1; // the expression itself is done.
  1439. break;
  1440. case ((Token) '\n'):
  1441. done = 1;
  1442. break; // we're done!
  1443. case TOKEN_IDENTIFIER:
  1444. if (handle_pp_identifier(ctx))
  1445. continue; // go again with new IncludeState.
  1446. if ( (state->tokenlen == 7) &&
  1447. (memcmp(state->token, "defined", 7) == 0) )
  1448. {
  1449. token = lexer(state);
  1450. const int paren = (token == ((Token) '('));
  1451. if (paren) // gcc doesn't let us nest parens here, either.
  1452. token = lexer(state);
  1453. if (token != TOKEN_IDENTIFIER)
  1454. {
  1455. fail(ctx, "operator 'defined' requires an identifier");
  1456. return -1;
  1457. } // if
  1458. const int found = (find_define_by_token(ctx) != NULL);
  1459. if (paren)
  1460. {
  1461. if (lexer(state) != ((Token) ')'))
  1462. {
  1463. fail(ctx, "Unmatched ')'");
  1464. return -1;
  1465. } // if
  1466. } // if
  1467. ADD_TO_OUTPUT(0, found);
  1468. continue;
  1469. } // if
  1470. // can't replace identifier with a number? It becomes zero.
  1471. token = TOKEN_INT_LITERAL;
  1472. ADD_TO_OUTPUT(0, 0);
  1473. break;
  1474. case TOKEN_INT_LITERAL:
  1475. ADD_TO_OUTPUT(0, token_to_int(state));
  1476. break;
  1477. case ((Token) '('):
  1478. PUSH_TO_STACK((Token) '(');
  1479. break;
  1480. case ((Token) ')'):
  1481. matched = 0;
  1482. while (stacksize > 0)
  1483. {
  1484. const Token t = stack[--stacksize];
  1485. if (t == ((Token) '('))
  1486. {
  1487. matched = 1;
  1488. break;
  1489. } // if
  1490. ADD_TO_OUTPUT(1, t);
  1491. } // while
  1492. if (!matched)
  1493. {
  1494. fail(ctx, "Unmatched ')'");
  1495. return -1;
  1496. } // if
  1497. break;
  1498. default:
  1499. precedence = find_precedence(token);
  1500. // bogus token, or two operators together.
  1501. if (precedence < 0)
  1502. {
  1503. pushback(state);
  1504. fail(ctx, "Invalid expression");
  1505. return -1;
  1506. } // if
  1507. else // it's an operator.
  1508. {
  1509. while (stacksize > 0)
  1510. {
  1511. const Token t = stack[stacksize-1];
  1512. const int p = find_precedence(t);
  1513. if ( (p >= 0) &&
  1514. ( ((isleft) && (precedence <= p)) ||
  1515. ((!isleft) && (precedence < p)) ) )
  1516. {
  1517. stacksize--;
  1518. ADD_TO_OUTPUT(1, t);
  1519. } // if
  1520. else
  1521. {
  1522. break;
  1523. } // else
  1524. } // while
  1525. PUSH_TO_STACK(token);
  1526. } // else
  1527. break;
  1528. } // switch
  1529. previous_token = token;
  1530. } // while
  1531. while (stacksize > 0)
  1532. {
  1533. const Token t = stack[--stacksize];
  1534. if (t == ((Token) '('))
  1535. {
  1536. fail(ctx, "Unmatched ')'");
  1537. return -1;
  1538. } // if
  1539. ADD_TO_OUTPUT(1, t);
  1540. } // while
  1541. #undef ADD_TO_OUTPUT
  1542. #undef PUSH_TO_STACK
  1543. // okay, you now have some validated data in reverse polish notation.
  1544. #if DEBUG_PREPROCESSOR
  1545. printf("PREPROCESSOR EXPRESSION RPN:");
  1546. int i = 0;
  1547. for (i = 0; i < outputsize; i++)
  1548. {
  1549. if (!output[i].isoperator)
  1550. printf(" %d", output[i].value);
  1551. else
  1552. {
  1553. switch (output[i].value)
  1554. {
  1555. case TOKEN_OROR: printf(" ||"); break;
  1556. case TOKEN_ANDAND: printf(" &&"); break;
  1557. case TOKEN_NEQ: printf(" !="); break;
  1558. case TOKEN_EQL: printf(" =="); break;
  1559. case TOKEN_LEQ: printf(" <="); break;
  1560. case TOKEN_GEQ: printf(" >="); break;
  1561. case TOKEN_LSHIFT: printf(" <<"); break;
  1562. case TOKEN_RSHIFT: printf(" >>"); break;
  1563. case TOKEN_PP_UNARY_PLUS: printf(" +"); break;
  1564. case TOKEN_PP_UNARY_MINUS: printf(" -"); break;
  1565. default: printf(" %c", output[i].value); break;
  1566. } // switch
  1567. } // else
  1568. } // for
  1569. printf("\n");
  1570. #endif
  1571. int error = 0;
  1572. const long val = interpret_rpn(output, outputsize, &error);
  1573. #if DEBUG_PREPROCESSOR
  1574. printf("PREPROCESSOR RPN RESULT: %ld%s\n", val, error ? " (ERROR)" : "");
  1575. #endif
  1576. if (error)
  1577. {
  1578. fail(ctx, "Invalid expression");
  1579. return -1;
  1580. } // if
  1581. return ((val) ? 1 : 0);
  1582. } // reduce_pp_expression
  1583. static Conditional *handle_pp_if(Context *ctx)
  1584. {
  1585. IncludeState *state = ctx->include_stack;
  1586. const int result = reduce_pp_expression(ctx);
  1587. if (result == -1)
  1588. return NULL;
  1589. Conditional *conditional = get_conditional(ctx);
  1590. assert((conditional != NULL) || (ctx->out_of_memory));
  1591. if (conditional == NULL)
  1592. return NULL;
  1593. Conditional *parent = state->conditional_stack;
  1594. const int chosen = result;
  1595. const int skipping = ( (((parent) && (parent->skipping))) || (!chosen) );
  1596. conditional->type = TOKEN_PP_IF;
  1597. conditional->linenum = state->line - 1;
  1598. conditional->skipping = skipping;
  1599. conditional->chosen = chosen;
  1600. conditional->next = parent;
  1601. state->conditional_stack = conditional;
  1602. return conditional;
  1603. } // handle_pp_if
  1604. static void handle_pp_elif(Context *ctx)
  1605. {
  1606. const int rc = reduce_pp_expression(ctx);
  1607. if (rc == -1)
  1608. return;
  1609. IncludeState *state = ctx->include_stack;
  1610. Conditional *cond = state->conditional_stack;
  1611. if (cond == NULL)
  1612. fail(ctx, "#elif without #if");
  1613. else if (cond->type == TOKEN_PP_ELSE)
  1614. fail(ctx, "#elif after #else");
  1615. else
  1616. {
  1617. const Conditional *parent = cond->next;
  1618. cond->type = TOKEN_PP_ELIF;
  1619. cond->skipping = (parent && parent->skipping) || cond->chosen || !rc;
  1620. if (!cond->chosen)
  1621. cond->chosen = rc;
  1622. } // else
  1623. } // handle_pp_elif
  1624. static void handle_pp_else(Context *ctx)
  1625. {
  1626. IncludeState *state = ctx->include_stack;
  1627. Conditional *cond = state->conditional_stack;
  1628. if (!require_newline(state))
  1629. fail(ctx, "Invalid #else directive");
  1630. else if (cond == NULL)
  1631. fail(ctx, "#else without #if");
  1632. else if (cond->type == TOKEN_PP_ELSE)
  1633. fail(ctx, "#else after #else");
  1634. else
  1635. {
  1636. const Conditional *parent = cond->next;
  1637. cond->type = TOKEN_PP_ELSE;
  1638. cond->skipping = (parent && parent->skipping) || cond->chosen;
  1639. if (!cond->chosen)
  1640. cond->chosen = 1;
  1641. } // else
  1642. } // handle_pp_else
  1643. static void handle_pp_endif(Context *ctx)
  1644. {
  1645. IncludeState *state = ctx->include_stack;
  1646. Conditional *cond = state->conditional_stack;
  1647. if (!require_newline(state))
  1648. fail(ctx, "Invalid #endif directive");
  1649. else if (cond == NULL)
  1650. fail(ctx, "Unmatched #endif");
  1651. else
  1652. {
  1653. state->conditional_stack = cond->next; // pop it.
  1654. put_conditional(ctx, cond);
  1655. } // else
  1656. } // handle_pp_endif
  1657. static void unterminated_pp_condition(Context *ctx)
  1658. {
  1659. IncludeState *state = ctx->include_stack;
  1660. Conditional *cond = state->conditional_stack;
  1661. // !!! FIXME: report the line number where the #if is, not the EOI.
  1662. switch (cond->type)
  1663. {
  1664. case TOKEN_PP_IF: fail(ctx, "Unterminated #if"); break;
  1665. case TOKEN_PP_IFDEF: fail(ctx, "Unterminated #ifdef"); break;
  1666. case TOKEN_PP_IFNDEF: fail(ctx, "Unterminated #ifndef"); break;
  1667. case TOKEN_PP_ELSE: fail(ctx, "Unterminated #else"); break;
  1668. case TOKEN_PP_ELIF: fail(ctx, "Unterminated #elif"); break;
  1669. default: assert(0 && "Shouldn't hit this case"); break;
  1670. } // switch
  1671. // pop this conditional, we'll report the next error next time...
  1672. state->conditional_stack = cond->next; // pop it.
  1673. put_conditional(ctx, cond);
  1674. } // unterminated_pp_condition
  1675. static inline const char *_preprocessor_nexttoken(Preprocessor *_ctx,
  1676. unsigned int *_len, Token *_token)
  1677. {
  1678. Context *ctx = (Context *) _ctx;
  1679. while (1)
  1680. {
  1681. if (ctx->isfail)
  1682. {
  1683. ctx->isfail = 0;
  1684. *_token = TOKEN_PREPROCESSING_ERROR;
  1685. *_len = strlen(ctx->failstr);
  1686. return ctx->failstr;
  1687. } // if
  1688. IncludeState *state = ctx->include_stack;
  1689. if (state == NULL)
  1690. {
  1691. *_token = TOKEN_EOI;
  1692. *_len = 0;
  1693. return NULL; // we're done!
  1694. } // if
  1695. const Conditional *cond = state->conditional_stack;
  1696. const int skipping = ((cond != NULL) && (cond->skipping));
  1697. const Token token = lexer(state);
  1698. if (token != TOKEN_IDENTIFIER)
  1699. ctx->recursion_count = 0;
  1700. if (token == TOKEN_EOI)
  1701. {
  1702. assert(state->bytes_left == 0);
  1703. if (state->conditional_stack != NULL)
  1704. {
  1705. unterminated_pp_condition(ctx);
  1706. continue; // returns an error.
  1707. } // if
  1708. pop_source(ctx);
  1709. continue; // pick up again after parent's #include line.
  1710. } // if
  1711. else if (token == TOKEN_INCOMPLETE_COMMENT)
  1712. {
  1713. fail(ctx, "Incomplete multiline comment");
  1714. continue; // will return at top of loop.
  1715. } // else if
  1716. else if (token == TOKEN_PP_IFDEF)
  1717. {
  1718. handle_pp_ifdef(ctx);
  1719. continue; // get the next thing.
  1720. } // else if
  1721. else if (token == TOKEN_PP_IFNDEF)
  1722. {
  1723. handle_pp_ifndef(ctx);
  1724. continue; // get the next thing.
  1725. } // else if
  1726. else if (token == TOKEN_PP_IF)
  1727. {
  1728. handle_pp_if(ctx);
  1729. continue; // get the next thing.
  1730. } // else if
  1731. else if (token == TOKEN_PP_ELIF)
  1732. {
  1733. handle_pp_elif(ctx);
  1734. continue; // get the next thing.
  1735. } // else if
  1736. else if (token == TOKEN_PP_ENDIF)
  1737. {
  1738. handle_pp_endif(ctx);
  1739. continue; // get the next thing.
  1740. } // else if
  1741. else if (token == TOKEN_PP_ELSE)
  1742. {
  1743. handle_pp_else(ctx);
  1744. continue; // get the next thing.
  1745. } // else if
  1746. // NOTE: Conditionals must be above (skipping) test.
  1747. else if (skipping)
  1748. continue; // just keep dumping tokens until we get end of block.
  1749. else if (token == TOKEN_PP_INCLUDE)
  1750. {
  1751. handle_pp_include(ctx);
  1752. continue; // will return error or use new top of include_stack.
  1753. } // else if
  1754. else if (token == TOKEN_PP_LINE)
  1755. {
  1756. handle_pp_line(ctx);
  1757. continue; // get the next thing.
  1758. } // else if
  1759. else if (token == TOKEN_PP_ERROR)
  1760. {
  1761. handle_pp_error(ctx);
  1762. continue; // will return at top of loop.
  1763. } // else if
  1764. else if (token == TOKEN_PP_DEFINE)
  1765. {
  1766. handle_pp_define(ctx);
  1767. continue; // will return at top of loop.
  1768. } // else if
  1769. else if (token == TOKEN_PP_UNDEF)
  1770. {
  1771. handle_pp_undef(ctx);
  1772. continue; // will return at top of loop.
  1773. } // else if
  1774. else if (token == TOKEN_PP_PRAGMA)
  1775. {
  1776. ctx->parsing_pragma = 1;
  1777. } // else if
  1778. if (token == TOKEN_IDENTIFIER)
  1779. {
  1780. if (handle_pp_identifier(ctx))
  1781. continue; // pushed the include_stack.
  1782. } // else if
  1783. else if (token == ((Token) '\n'))
  1784. {
  1785. print_debug_lexing_position(state);
  1786. if (ctx->parsing_pragma) // let this one through.
  1787. ctx->parsing_pragma = 0;
  1788. else
  1789. {
  1790. // preprocessor is line-oriented, nothing else gets newlines.
  1791. continue; // get the next thing.
  1792. } // else
  1793. } // else if
  1794. assert(!skipping);
  1795. *_token = token;
  1796. *_len = state->tokenlen;
  1797. return state->token;
  1798. } // while
  1799. assert(0 && "shouldn't hit this code");
  1800. *_token = TOKEN_UNKNOWN;
  1801. *_len = 0;
  1802. return NULL;
  1803. } // _preprocessor_nexttoken
  1804. const char *preprocessor_nexttoken(Preprocessor *ctx, unsigned int *len,
  1805. Token *token)
  1806. {
  1807. const char *retval = _preprocessor_nexttoken(ctx, len, token);
  1808. print_debug_token(retval, *len, *token);
  1809. return retval;
  1810. } // preprocessor_nexttoken
  1811. const char *preprocessor_sourcepos(Preprocessor *_ctx, unsigned int *pos)
  1812. {
  1813. Context *ctx = (Context *) _ctx;
  1814. if (ctx->include_stack == NULL)
  1815. {
  1816. *pos = 0;
  1817. return NULL;
  1818. } // if
  1819. *pos = ctx->include_stack->line;
  1820. return ctx->include_stack->filename;
  1821. } // preprocessor_sourcepos
  1822. static void indent_buffer(Buffer *buffer, int n, const int newline)
  1823. {
  1824. static char spaces[4] = { ' ', ' ', ' ', ' ' };
  1825. if (newline)
  1826. {
  1827. while (n--)
  1828. {
  1829. if (!buffer_append(buffer, spaces, sizeof (spaces)))
  1830. return;
  1831. } // while
  1832. } // if
  1833. else
  1834. {
  1835. if (!buffer_append(buffer, spaces, 1))
  1836. return;
  1837. } // else
  1838. } // indent_buffer
  1839. static const MOJOSHADER_preprocessData out_of_mem_data_preprocessor = {
  1840. 1, &MOJOSHADER_out_of_mem_error, 0, 0, 0, 0, 0
  1841. };
  1842. // public API...
  1843. const MOJOSHADER_preprocessData *MOJOSHADER_preprocess(const char *filename,
  1844. const char *source, unsigned int sourcelen,
  1845. const MOJOSHADER_preprocessorDefine *defines,
  1846. unsigned int define_count,
  1847. MOJOSHADER_includeOpen include_open,
  1848. MOJOSHADER_includeClose include_close,
  1849. MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  1850. {
  1851. MOJOSHADER_preprocessData *retval = NULL;
  1852. Preprocessor *pp = NULL;
  1853. ErrorList *errors = NULL;
  1854. Buffer *buffer = NULL;
  1855. Token token = TOKEN_UNKNOWN;
  1856. const char *tokstr = NULL;
  1857. int nl = 1;
  1858. int indent = 0;
  1859. unsigned int len = 0;
  1860. char *output = NULL;
  1861. int errcount = 0;
  1862. size_t total_bytes = 0;
  1863. // !!! FIXME: what's wrong with ENDLINE_STR?
  1864. #ifdef _WINDOWS
  1865. static const char endline[] = { '\r', '\n' };
  1866. #else
  1867. static const char endline[] = { '\n' };
  1868. #endif
  1869. if (!m) m = MOJOSHADER_internal_malloc;
  1870. if (!f) f = MOJOSHADER_internal_free;
  1871. if (!include_open) include_open = MOJOSHADER_internal_include_open;
  1872. if (!include_close) include_close = MOJOSHADER_internal_include_close;
  1873. pp = preprocessor_start(filename, source, sourcelen,
  1874. include_open, include_close,
  1875. defines, define_count, 0, m, f, d);
  1876. if (pp == NULL)
  1877. goto preprocess_out_of_mem;
  1878. errors = errorlist_create(MallocBridge, FreeBridge, pp);
  1879. if (errors == NULL)
  1880. goto preprocess_out_of_mem;
  1881. buffer = buffer_create(4096, MallocBridge, FreeBridge, pp);
  1882. if (buffer == NULL)
  1883. goto preprocess_out_of_mem;
  1884. while ((tokstr = preprocessor_nexttoken(pp, &len, &token)) != NULL)
  1885. {
  1886. int isnewline = 0;
  1887. assert(token != TOKEN_EOI);
  1888. if (preprocessor_outofmemory(pp))
  1889. goto preprocess_out_of_mem;
  1890. // Microsoft's preprocessor is weird.
  1891. // It ignores newlines, and then inserts its own around certain
  1892. // tokens. For example, after a semicolon. This allows HLSL code to
  1893. // be mostly readable, instead of a stream of tokens.
  1894. if ( (token == ((Token) '}')) || (token == ((Token) ';')) )
  1895. {
  1896. if ( (token == ((Token) '}')) && (indent > 0) )
  1897. indent--;
  1898. indent_buffer(buffer, indent, nl);
  1899. buffer_append(buffer, tokstr, len);
  1900. buffer_append(buffer, endline, sizeof (endline));
  1901. isnewline = 1;
  1902. } // if
  1903. else if (token == ((Token) '\n'))
  1904. {
  1905. buffer_append(buffer, endline, sizeof (endline));
  1906. isnewline = 1;
  1907. } // else if
  1908. else if (token == ((Token) '{'))
  1909. {
  1910. buffer_append(buffer, endline, sizeof (endline));
  1911. indent_buffer(buffer, indent, 1);
  1912. buffer_append(buffer, "{", 1);
  1913. buffer_append(buffer, endline, sizeof (endline));
  1914. indent++;
  1915. isnewline = 1;
  1916. } // else if
  1917. else if (token == TOKEN_PREPROCESSING_ERROR)
  1918. {
  1919. unsigned int pos = 0;
  1920. const char *fname = preprocessor_sourcepos(pp, &pos);
  1921. errorlist_add(errors, fname, (int) pos, tokstr);
  1922. } // else if
  1923. else
  1924. {
  1925. indent_buffer(buffer, indent, nl);
  1926. buffer_append(buffer, tokstr, len);
  1927. } // else
  1928. nl = isnewline;
  1929. } // while
  1930. assert(token == TOKEN_EOI);
  1931. total_bytes = buffer_size(buffer);
  1932. output = buffer_flatten(buffer);
  1933. buffer_destroy(buffer);
  1934. buffer = NULL; // don't free this pointer again.
  1935. if (output == NULL)
  1936. goto preprocess_out_of_mem;
  1937. retval = (MOJOSHADER_preprocessData *) m(sizeof (*retval), d);
  1938. if (retval == NULL)
  1939. goto preprocess_out_of_mem;
  1940. memset(retval, '\0', sizeof (*retval));
  1941. errcount = errorlist_count(errors);
  1942. if (errcount > 0)
  1943. {
  1944. retval->error_count = errcount;
  1945. retval->errors = errorlist_flatten(errors);
  1946. if (retval->errors == NULL)
  1947. goto preprocess_out_of_mem;
  1948. } // if
  1949. retval->output = output;
  1950. retval->output_len = total_bytes;
  1951. retval->malloc = m;
  1952. retval->free = f;
  1953. retval->malloc_data = d;
  1954. errorlist_destroy(errors);
  1955. preprocessor_end(pp);
  1956. return retval;
  1957. preprocess_out_of_mem:
  1958. if (retval != NULL)
  1959. f(retval->errors, d);
  1960. f(retval, d);
  1961. f(output, d);
  1962. buffer_destroy(buffer);
  1963. errorlist_destroy(errors);
  1964. preprocessor_end(pp);
  1965. return &out_of_mem_data_preprocessor;
  1966. } // MOJOSHADER_preprocess
  1967. void MOJOSHADER_freePreprocessData(const MOJOSHADER_preprocessData *_data)
  1968. {
  1969. MOJOSHADER_preprocessData *data = (MOJOSHADER_preprocessData *) _data;
  1970. if ((data == NULL) || (data == &out_of_mem_data_preprocessor))
  1971. return;
  1972. MOJOSHADER_free f = (data->free == NULL) ? MOJOSHADER_internal_free : data->free;
  1973. void *d = data->malloc_data;
  1974. int i;
  1975. f((void *) data->output, d);
  1976. for (i = 0; i < data->error_count; i++)
  1977. {
  1978. f((void *) data->errors[i].error, d);
  1979. f((void *) data->errors[i].filename, d);
  1980. } // for
  1981. f(data->errors, d);
  1982. f(data, d);
  1983. } // MOJOSHADER_freePreprocessData
  1984. // end of mojoshader_preprocessor.c ...