w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

parser.c
Go to the documentation of this file.
1 /* vim: ts=4 sw=4 sts=4 et tw=78
2  * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
3  * Portions copyright (c) 2011 James R. McKaskill.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  */
9 #include "ffi.h"
10 
11 #define IS_CONST(tok) (IS_LITERAL(tok, "const") || IS_LITERAL(tok, "__const") || IS_LITERAL(tok, "__const__"))
12 #define IS_VOLATILE(tok) (IS_LITERAL(tok, "volatile") || IS_LITERAL(tok, "__volatile") || IS_LITERAL(tok, "__volatile__"))
13 #define IS_RESTRICT(tok) (IS_LITERAL(tok, "restrict") || IS_LITERAL(tok, "__restrict") || IS_LITERAL(tok, "__restrict__"))
14 #define IS_INLINE(tok) (IS_LITERAL(tok, "inline") || IS_LITERAL(tok, "__inline") || IS_LITERAL(tok, "__inline__"))
15 
16 enum etoken {
21 
22  /* the order of these values must match the token strings in lex.c */
23 
26 
30 
37 
41 };
42 
43 struct token {
44  enum etoken type;
46  const char* str;
47  size_t size;
48 };
49 
50 #define IS_LITERAL(TOK, STR) \
51  (((TOK).size == sizeof(STR) - 1) && 0 == memcmp((TOK).str, STR, sizeof(STR) - 1))
52 
53 /* the order of tokens _must_ match the order of the enum etoken enum */
54 
55 static char tok3[][4] = {
56  "...", /* unused ">>=", "<<=", */
57 };
58 
59 static char tok2[][3] = {
60  "<<", ">>", "&&", "||", "<=",
61  ">=", "==", "!=",
62  /* unused "+=", "-=", "*=", "/=", "%=", "&=", "^=", "|=", "++", "--", "->", "::", */
63 };
64 
65 static char tok1[] = {
66  '{', '}', ';', ',', ':',
67  '=', '(', ')', '[', ']',
68  '.', '&', '!', '~', '-',
69  '+', '*', '/', '%', '<',
70  '>', '^', '|', '?', '#'
71 };
72 
73 static int next_token(lua_State* L, struct parser* P, struct token* tok)
74 {
75  size_t i;
76  const char* s = P->next;
77 
78  /* UTF8 BOM */
79  if (s[0] == '\xEF' && s[1] == '\xBB' && s[2] == '\xBF') {
80  s += 3;
81  }
82 
83  /* consume whitespace and comments */
84  for (;;) {
85  /* consume whitespace */
86  while(*s == '\t' || *s == '\n' || *s == ' ' || *s == '\v' || *s == '\r') {
87  if (*s == '\n') {
88  P->line++;
89  }
90  s++;
91  }
92 
93  /* consume comments */
94  if (*s == '/' && *(s+1) == '/') {
95 
96  s = strchr(s, '\n');
97  if (!s) {
98  luaL_error(L, "non-terminated comment");
99  }
100 
101  } else if (*s == '/' && *(s+1) == '*') {
102  s += 2;
103 
104  for (;;) {
105  if (s[0] == '\0') {
106  luaL_error(L, "non-terminated comment");
107  } else if (s[0] == '*' && s[1] == '/') {
108  s += 2;
109  break;
110  } else if (s[0] == '\n') {
111  P->line++;
112  }
113  s++;
114  }
115 
116  } else if (*s == '\0') {
117  tok->type = TOK_NIL;
118  return 0;
119 
120  } else {
121  break;
122  }
123  }
124 
125  P->prev = s;
126 
127  for (i = 0; i < sizeof(tok3) / sizeof(tok3[0]); i++) {
128  if (s[0] == tok3[i][0] && s[1] == tok3[i][1] && s[2] == tok3[i][2]) {
129  tok->type = (enum etoken) (TOK_3_BEGIN + 1 + i);
130  P->next = s + 3;
131  goto end;
132  }
133  }
134 
135  for (i = 0; i < sizeof(tok2) / sizeof(tok2[0]); i++) {
136  if (s[0] == tok2[i][0] && s[1] == tok2[i][1]) {
137  tok->type = (enum etoken) (TOK_2_BEGIN + 1 + i);
138  P->next = s + 2;
139  goto end;
140  }
141  }
142 
143  for (i = 0; i < sizeof(tok1) / sizeof(tok1[0]); i++) {
144  if (s[0] == tok1[i]) {
145  tok->type = (enum etoken) (TOK_1_BEGIN + 1 + i);
146  P->next = s + 1;
147  goto end;
148  }
149  }
150 
151  if (*s == '.' || *s == '-' || ('0' <= *s && *s <= '9')) {
152  /* number */
153  tok->type = TOK_NUMBER;
154 
155  /* split out the negative case so we get the full range of bits for
156  * unsigned (eg to support 0xFFFFFFFF where sizeof(long) == 4)
157  */
158  if (*s == '-') {
159  tok->integer = strtol(s, (char**) &s, 0);
160  } else {
161  tok->integer = strtoul(s, (char**) &s, 0);
162  }
163 
164  while (*s == 'u' || *s == 'U' || *s == 'l' || *s == 'L') {
165  s++;
166  }
167 
168  P->next = s;
169  goto end;
170 
171  } else if (*s == '\'' || *s == '\"') {
172  /* "..." or '...' */
173  char quote = *s;
174  s++; /* jump over " */
175 
176  tok->type = TOK_STRING;
177  tok->str = s;
178 
179  while (*s != quote) {
180 
181  if (*s == '\0' || (*s == '\\' && *(s+1) == '\0')) {
182  return luaL_error(L, "string not finished");
183  }
184 
185  if (*s == '\\') {
186  s++;
187  }
188 
189  s++;
190  }
191 
192  tok->size = s - tok->str;
193  s++; /* jump over " */
194  P->next = s;
195  goto end;
196 
197  } else if (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z') || *s == '_') {
198  /* tokens */
199  tok->type = TOK_TOKEN;
200  tok->str = s;
201 
202  while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z') || *s == '_' || ('0' <= *s && *s <= '9')) {
203  s++;
204  }
205 
206  tok->size = s - tok->str;
207  P->next = s;
208  goto end;
209 
210  } else {
211  return luaL_error(L, "invalid character %d", P->line);
212  }
213 
214 end:
215  /*fprintf(stderr, "token %d %d %.*s %.10s\n", tok->type, (int) tok->size, (tok->type == TOK_TOKEN || tok->type == TOK_STRING) ? (int) tok->size : 0, tok->str, P->next);*/
216  return 1;
217 }
218 
219 #define require_token(L, P, tok) require_token_line(L, P, tok, __FILE__, __LINE__)
220 
221 static void require_token_line(lua_State* L, struct parser* P, struct token* tok, const char* file, int line)
222 {
223  if (!next_token(L, P, tok)) {
224  luaL_error(L, "unexpected end on line %s:%d", file, line);
225  }
226 }
227 
228 static void check_token(lua_State* L, struct parser* P, int type, const char* str, const char* err, ...)
229 {
230  struct token tok;
231  if (!next_token(L, P, &tok) || tok.type != type || (tok.type == TOK_TOKEN && (tok.size != strlen(str) || memcmp(tok.str, str, tok.size) != 0))) {
232  va_list ap;
233  va_start(ap, err);
235  lua_error(L);
236  }
237 }
238 
239 static void put_back(struct parser* P)
240 { P->next = P->prev; }
241 
242 
244 
245 static int g_name_key;
246 static int g_front_name_key;
247 static int g_back_name_key;
248 
249 #ifndef max
250 #define max(a,b) ((a) < (b) ? (b) : (a))
251 #endif
252 
253 #ifndef min
254 #define min(a,b) ((a) < (b) ? (a) : (b))
255 #endif
256 
257 enum test {TEST};
258 
259 /* Parses an enum definition from after the open curly through to the close
260  * curly. Expects the user table to be on the top of the stack
261  */
262 static int parse_enum(lua_State* L, struct parser* P, struct ctype* type)
263 {
264  struct token tok;
265  int value = -1;
266  int ct_usr = lua_gettop(L);
267 
268  for (;;) {
269  require_token(L, P, &tok);
270 
271  assert(lua_gettop(L) == ct_usr);
272 
273  if (tok.type == TOK_CLOSE_CURLY) {
274  break;
275  } else if (tok.type != TOK_TOKEN) {
276  return luaL_error(L, "unexpected token in enum at line %d", P->line);
277  }
278 
279  lua_pushlstring(L, tok.str, tok.size);
280 
281  require_token(L, P, &tok);
282 
283  if (tok.type == TOK_COMMA || tok.type == TOK_CLOSE_CURLY) {
284  /* we have an auto calculated enum value */
285  value++;
286  } else if (tok.type == TOK_ASSIGN) {
287  /* we have an explicit enum value */
289  require_token(L, P, &tok);
290  } else {
291  return luaL_error(L, "unexpected token in enum at line %d", P->line);
292  }
293 
294  assert(lua_gettop(L) == ct_usr + 1);
295 
296  /* add the enum value to the constants table */
298  lua_pushvalue(L, -2);
300  lua_rawset(L, -3);
301  lua_pop(L, 1);
302 
303  assert(lua_gettop(L) == ct_usr + 1);
304 
305  /* add the enum value to the enum usr value table */
307  lua_rawset(L, ct_usr);
308 
309  if (tok.type == TOK_CLOSE_CURLY) {
310  break;
311  } else if (tok.type != TOK_COMMA) {
312  return luaL_error(L, "unexpected token in enum at line %d", P->line);
313  }
314  }
315 
316  type->base_size = sizeof(enum test);
317  type->align_mask = sizeof(enum test) - 1;
318 
319  assert(lua_gettop(L) == ct_usr);
320  return 0;
321 }
322 
323 static void calculate_member_position(lua_State* L, struct parser* P, struct ctype* ct, struct ctype* mt, int* pbit_offset, int* pbitfield_type)
324 {
325  int bit_offset = *pbit_offset;
326 
327  if (ct->type == UNION_TYPE) {
328  size_t msize;
329 
330  if (mt->is_variable_struct || mt->is_variable_array) {
331  luaL_error(L, "NYI: variable sized members in unions");
332  return;
333 
334  } else if (mt->is_bitfield) {
335  msize = (mt->align_mask + 1);
336 #ifdef _WIN32
337  /* MSVC has a bug where it doesn't update the alignment of
338  * a union for bitfield members. */
339  mt->align_mask = 0;
340 #endif
341 
342  } else if (mt->is_array) {
343  msize = mt->array_size * (mt->pointers > 1 ? sizeof(void*) : mt->base_size);
344 
345  } else {
346  msize = mt->pointers ? sizeof(void*) : mt->base_size;
347  }
348 
349  ct->base_size = max(ct->base_size, msize);
350 
351  } else if (mt->is_bitfield) {
352  if (mt->has_member_name && mt->bit_size == 0) {
353  luaL_error(L, "zero length bitfields must be unnamed on line %d", P->line);
354  }
355 
356 #if defined _WIN32
357  /* MSVC uses a seperate storage unit for each size. This is aligned
358  * before the first bitfield. :0 finishes up the storage unit using
359  * the greater alignment of the storage unit or the type used with the
360  * :0. This is equivalent to the :0 always creating a new storage
361  * unit, but not necesserily using it yet.
362  */
363 
364  if (*pbitfield_type == -1 && mt->bit_size == 0) {
365  /* :0 not after a bitfield are ignored */
366  return;
367  }
368 
369  {
370  int different_storage = mt->align_mask != *pbitfield_type;
371  int no_room_left = bit_offset + mt->bit_size > (mt->align_mask + 1) * CHAR_BIT;
372 
373  if (different_storage || no_room_left || !mt->bit_size) {
374  ct->base_size += (bit_offset + CHAR_BIT - 1) / CHAR_BIT;
375  bit_offset = 0;
376  if (*pbitfield_type >= 0) {
377  ct->base_size = ALIGN_UP(ct->base_size, *pbitfield_type);
378  }
379  ct->base_size = ALIGN_UP(ct->base_size, mt->align_mask);
380  }
381  }
382 
383  mt->bit_offset = bit_offset;
384  mt->offset = ct->base_size;
385 
386  *pbitfield_type = mt->align_mask;
387  bit_offset += mt->bit_size;
388 
389 // #elif defined OS_OSX
390 // /* OSX doesn't use containers and bitfields are not aligned. So
391 // * bitfields never add any padding, except for :0 which still forces
392 // * an alignment based off the type used with the :0 */
393 // if (mt->bit_size) {
394 // mt->offset = ct->base_size;
395 // mt->bit_offset = bit_offset;
396 // bit_offset += mt->bit_size;
397 // ct->base_size += bit_offset / CHAR_BIT;
398 // bit_offset = bit_offset % CHAR_BIT;
399 // } else {
400 // ct->base_size += (bit_offset + CHAR_BIT - 1) / CHAR_BIT;
401 // ct->base_size = ALIGN_UP(ct->base_size, mt->align_mask);
402 // bit_offset = 0;
403 // }
404 
405 // if (!mt->has_member_name) {
406 // /* unnamed bitfields don't update the struct alignment */
407 // mt->align_mask = 0;
408 // }
409 
410 #elif defined __GNUC__
411  /* GCC tries to pack bitfields in as close as much as possible, but
412  * still making sure that they don't cross alignment boundaries.
413  * :0 forces an alignment based off the type used with the :0
414  */
415 
416  int bits_used = (ct->base_size - ALIGN_DOWN(ct->base_size, mt->align_mask)) * CHAR_BIT + bit_offset;
417  int need_to_realign = bits_used + mt->bit_size > mt->base_size * CHAR_BIT;
418 
419  if (!mt->is_packed && (!mt->bit_size || need_to_realign)) {
420  ct->base_size += (bit_offset + CHAR_BIT - 1) / CHAR_BIT;
421  ct->base_size = ALIGN_UP(ct->base_size, mt->align_mask);
422  bit_offset = 0;
423  }
424 
425  mt->bit_offset = bit_offset;
426  mt->offset = ct->base_size;
427 
428  bit_offset += mt->bit_size;
429  ct->base_size += bit_offset / CHAR_BIT;
430  bit_offset = bit_offset % CHAR_BIT;
431 
432  /* unnamed bitfields don't update the struct alignment */
433  if (!mt->has_member_name) {
434  mt->align_mask = 0;
435  }
436 #else
437 #error
438 #endif
439 
440  } else {
441  /* finish up the current bitfield storage unit */
442  ct->base_size += (bit_offset + CHAR_BIT - 1) / CHAR_BIT;
443  bit_offset = 0;
444 
445  if (*pbitfield_type >= 0) {
446  ct->base_size = ALIGN_UP(ct->base_size, *pbitfield_type);
447  }
448 
449  *pbitfield_type = -1;
450 
451  ct->base_size = ALIGN_UP(ct->base_size, mt->align_mask);
452  mt->offset = ct->base_size;
453 
454  if (mt->is_variable_array) {
455  ct->is_variable_struct = 1;
456  ct->variable_increment = mt->pointers > 1 ? sizeof(void*) : mt->base_size;
457 
458  } else if (mt->is_variable_struct) {
459  assert(!mt->variable_size_known && !mt->is_array && !mt->pointers);
460  ct->base_size += mt->base_size;
461  ct->is_variable_struct = 1;
462  ct->variable_increment = mt->variable_increment;
463 
464  } else if (mt->is_array) {
465  ct->base_size += mt->array_size * (mt->pointers > 1 ? sizeof(void*) : mt->base_size);
466 
467  } else {
468  ct->base_size += mt->pointers ? sizeof(void*) : mt->base_size;
469  }
470  }
471 
472  /* increase the outer struct/union alignment if needed */
473  if (mt->align_mask > (int) ct->align_mask) {
474  ct->align_mask = mt->align_mask;
475  }
476 
477  if (mt->has_bitfield || mt->is_bitfield) {
478  ct->has_bitfield = 1;
479  }
480 
481  *pbit_offset = bit_offset;
482 }
483 
484 static int copy_submembers(lua_State* L, int to_usr, int from_usr, const struct ctype* ft, int* midx)
485 {
486  struct ctype ct;
487  int i, sublen;
488 
489  from_usr = lua_absindex(L, from_usr);
490  to_usr = lua_absindex(L, to_usr);
491 
492  /* integer keys */
493  sublen = (int) lua_rawlen(L, from_usr);
494  for (i = 1; i <= sublen; i++) {
495  lua_rawgeti(L, from_usr, i);
496 
497  ct = *(const struct ctype*) lua_touserdata(L, -1);
498  ct.offset += ft->offset;
499  lua_getuservalue(L, -1);
500 
501  push_ctype(L, -1, &ct);
502  lua_rawseti(L, to_usr, (*midx)++);
503 
504  lua_pop(L, 2); /* ctype, user value */
505  }
506 
507  /* string keys */
508  lua_pushnil(L);
509  while (lua_next(L, from_usr)) {
510  if (lua_type(L, -2) == LUA_TSTRING) {
511  struct ctype ct = *(const struct ctype*) lua_touserdata(L, -1);
512  ct.offset += ft->offset;
513  lua_getuservalue(L, -1);
514 
515  /* uservalue[sub_mname] = new_sub_mtype */
516  lua_pushvalue(L, -3);
517  push_ctype(L, -2, &ct);
518  lua_rawset(L, to_usr);
519 
520  lua_pop(L, 1); /* remove submember user value */
521  }
522  lua_pop(L, 1);
523  }
524 
525  return 0;
526 }
527 
528 static int add_member(lua_State* L, int ct_usr, int mname, int mbr_usr, const struct ctype* mt, int* midx)
529 {
530  ct_usr = lua_absindex(L, ct_usr);
531  mname = lua_absindex(L, mname);
532 
533  push_ctype(L, mbr_usr, mt);
534 
535  /* usrvalue[mbr index] = pushed mtype */
536  lua_pushvalue(L, -1);
537  lua_rawseti(L, ct_usr, (*midx)++);
538 
539  /* set usrvalue[mname] = pushed mtype */
540  lua_pushvalue(L, mname);
541  lua_pushvalue(L, -2);
542  lua_rawset(L, ct_usr);
543 
544  /* set usrvalue[mtype] = mname */
545  lua_pushvalue(L, -1);
546  lua_pushvalue(L, mname);
547  lua_rawset(L, ct_usr);
548 
549  lua_pop(L, 1);
550 
551  return 0;
552 }
553 
554 /* Parses a struct from after the open curly through to the close curly.
555  */
556 static int parse_struct(lua_State* L, struct parser* P, int tmp_usr, const struct ctype* ct)
557 {
558  struct token tok;
559  int midx = 1;
560  int top = lua_gettop(L);
561 
562  tmp_usr = lua_absindex(L, tmp_usr);
563 
564  /* parse members */
565  for (;;) {
566  struct ctype mbase;
567 
568  assert(lua_gettop(L) == top);
569 
570  /* see if we're at the end of the struct */
571  require_token(L, P, &tok);
572  if (tok.type == TOK_CLOSE_CURLY) {
573  break;
574  } else if (ct->is_variable_struct) {
575  return luaL_error(L, "can't have members after a variable sized member on line %d", P->line);
576  } else {
577  put_back(P);
578  }
579 
580  /* members are of the form
581  * <base type> <arg>, <arg>, <arg>;
582  * eg struct foo bar, *bar2[2];
583  * mbase is 'struct foo'
584  * mtype is '' then '*[2]'
585  * mname is 'bar' then 'bar2'
586  */
587 
588  parse_type(L, P, &mbase);
589 
590  for (;;) {
591  struct token mname;
592  struct ctype mt = mbase;
593 
594  memset(&mname, 0, sizeof(mname));
595 
596  if (ct->is_variable_struct) {
597  return luaL_error(L, "can't have members after a variable sized member on line %d", P->line);
598  }
599 
600  assert(lua_gettop(L) == top + 1);
601  parse_argument(L, P, -1, &mt, &mname, NULL);
602  assert(lua_gettop(L) == top + 2);
603 
604  if (!mt.is_defined && (mt.pointers - mt.is_array) == 0) {
605  return luaL_error(L, "member type is undefined on line %d", P->line);
606  }
607 
608  if (mt.type == VOID_TYPE && (mt.pointers - mt.is_array) == 0) {
609  return luaL_error(L, "member type can not be void on line %d", P->line);
610  }
611 
612  mt.has_member_name = (mname.size > 0);
613  lua_pushlstring(L, mname.str, mname.size);
614 
615  add_member(L, tmp_usr, -1, -2, &mt, &midx);
616 
617  /* pop the usr value from push_argument and the member name */
618  lua_pop(L, 2);
619  assert(lua_gettop(L) == top + 1);
620 
621  require_token(L, P, &tok);
622  if (tok.type == TOK_SEMICOLON) {
623  break;
624  } else if (tok.type != TOK_COMMA) {
625  luaL_error(L, "unexpected token in struct definition on line %d", P->line);
626  }
627  }
628 
629  /* pop the usr value from push_type */
630  lua_pop(L, 1);
631  }
632 
633  assert(lua_gettop(L) == top);
634  return 0;
635 }
636 
637 static int calculate_struct_offsets(lua_State* L, struct parser* P, int ct_usr, struct ctype* ct, int tmp_usr)
638 {
639  int i;
640  int midx = 1;
641  int sz = (int) lua_rawlen(L, tmp_usr);
642  int bit_offset = 0;
643  int bitfield_type = -1;
644 
645  ct_usr = lua_absindex(L, ct_usr);
646  tmp_usr = lua_absindex(L, tmp_usr);
647 
648  for (i = 1; i <= sz; i++) {
649  struct ctype mt;
650 
651  /* get the member type */
652  lua_rawgeti(L, tmp_usr, i);
653  mt = *(const struct ctype*) lua_touserdata(L, -1);
654 
655  /* get the member user table */
656  lua_getuservalue(L, -1);
657 
658  /* get the member name */
659  lua_pushvalue(L, -2);
660  lua_rawget(L, tmp_usr);
661 
662  calculate_member_position(L, P, ct, &mt, &bit_offset, &bitfield_type);
663 
664  if (mt.has_member_name) {
665  assert(!lua_isnil(L, -1));
666  add_member(L, ct_usr, -1, -2, &mt, &midx);
667 
668  } else if (mt.type == STRUCT_TYPE || mt.type == UNION_TYPE) {
669  /* With an unnamed member we copy all of the submembers into our
670  * usr value adjusting the offset as necessary. Note ctypes are
671  * immutable so need to push a new ctype to update the offset.
672  */
673  copy_submembers(L, ct_usr, -2, &mt, &midx);
674 
675  } else {
676  /* We ignore unnamed members that aren't structs or unions. These
677  * are there just to change the padding */
678  }
679 
680  lua_pop(L, 3);
681  }
682 
683  /* finish up the current bitfield storage unit */
684  ct->base_size += (bit_offset + CHAR_BIT - 1) / CHAR_BIT;
685 
686  /* only void is allowed 0 size */
687  if (ct->base_size == 0) {
688  ct->base_size = 1;
689  }
690 
691  ct->base_size = ALIGN_UP(ct->base_size, ct->align_mask);
692  return 0;
693 }
694 
695 /* copy over attributes that could be specified before the typedef eg
696  * __attribute__(packed) const type_t */
697 static void instantiate_typedef(struct parser* P, struct ctype* tt, const struct ctype* ft)
698 {
699  struct ctype pt = *tt;
700  *tt = *ft;
701 
702  tt->const_mask |= pt.const_mask;
703  tt->is_packed = pt.is_packed;
704 
705  if (tt->is_packed) {
706  tt->align_mask = 0;
707  } else {
708  /* Instantiate the typedef in the current packing. This may be
709  * further updated if a pointer is added or another alignment
710  * attribute is applied. If pt.align_mask is already non-zero than an
711  * increased alignment via __declspec(aligned(#)) has been set. */
712  tt->align_mask = max(min(P->align_mask, tt->align_mask), pt.align_mask);
713  }
714 }
715 
716 /* this parses a struct or union starting with the optional
717  * name before the opening brace
718  * leaves the type usr value on the stack
719  */
720 static int parse_record(lua_State* L, struct parser* P, struct ctype* ct)
721 {
722  struct token tok;
723  int top = lua_gettop(L);
724 
725  require_token(L, P, &tok);
726 
727  /* name is optional */
728  if (tok.type == TOK_TOKEN) {
729  /* declaration */
730  lua_pushlstring(L, tok.str, tok.size);
731 
732  assert(lua_gettop(L) == top+1);
733 
734  /* lookup the name to see if we've seen this type before */
736  lua_pushvalue(L, -2);
737  lua_rawget(L, top+2);
738 
739  assert(lua_gettop(L) == top+3);
740 
741  if (lua_isnil(L, -1)) {
742  lua_pop(L, 1); /* pop the nil usr value */
743  lua_newtable(L); /* the new usr table */
744 
745  /* stack layout is:
746  * top+1: record name
747  * top+2: types table
748  * top+3: new usr table
749  */
750 
752  lua_pushvalue(L, top+1);
753  lua_rawset(L, top+3); /* usr[name_key] = name */
754 
755  lua_pushvalue(L, top+1);
756  push_ctype(L, top+3, ct);
757  lua_rawset(L, top+2); /* types[name] = new_ctype */
758 
759  } else {
760  /* get the exsting declared type */
761  const struct ctype* prevt = (const struct ctype*) lua_touserdata(L, top+3);
762 
763  if (prevt->type != ct->type) {
764  lua_getuservalue(L, top+3);
765  push_type_name(L, -1, ct);
766  push_type_name(L, top+3, prevt);
767  luaL_error(L, "type '%s' previously declared as '%s'", lua_tostring(L, -2), lua_tostring(L, -1));
768  }
769 
770  instantiate_typedef(P, ct, prevt);
771 
772  /* replace the ctype with its usr value */
773  lua_getuservalue(L, -1);
774  lua_replace(L, -2);
775  }
776 
777  /* remove the extra name and types table */
778  lua_replace(L, -3);
779  lua_pop(L, 1);
780 
781  assert(lua_gettop(L) == top + 1 && lua_istable(L, -1));
782 
783  /* if a name is given then we may be at the end of the string
784  * eg for ffi.new('struct foo')
785  */
786  if (!next_token(L, P, &tok)) {
787  return 0;
788  }
789 
790  } else {
791  /* create a new unnamed record */
792  int num;
793 
794  /* get the next unnamed number */
796  num = lua_tointeger(L, -1);
797  lua_pop(L, 1);
798 
799  /* increment the unnamed upval */
800  lua_pushinteger(L, num + 1);
802 
803  lua_newtable(L); /* the new usr table - leave on stack */
804 
805  /* usr[name_key] = num */
807  lua_pushfstring(L, "%d", num);
808  lua_rawset(L, -3);
809  }
810 
811  if (tok.type != TOK_OPEN_CURLY) {
812  /* this may just be a declaration or use of the type as an argument or
813  * member */
814  put_back(P);
815  return 0;
816  }
817 
818  if (ct->is_defined) {
819  return luaL_error(L, "redefinition in line %d", P->line);
820  }
821 
822  assert(lua_gettop(L) == top + 1 && lua_istable(L, -1));
823 
824  if (ct->type == ENUM_TYPE) {
825  parse_enum(L, P, ct);
826  } else {
827  /* we do a two stage parse, where we parse the content first and build up
828  * the temp user table. We then iterate over that to calculate the offsets
829  * and fill out ct_usr. This is so we can handle out of order members
830  * (eg vtable) and attributes specified at the end of the struct.
831  */
832  lua_newtable(L);
833  parse_struct(L, P, -1, ct);
834  calculate_struct_offsets(L, P, -2, ct, -1);
835  assert(lua_gettop(L) == top + 2 && lua_istable(L, -1));
836  lua_pop(L, 1);
837  }
838 
839  assert(lua_gettop(L) == top + 1 && lua_istable(L, -1));
840  set_defined(L, -1, ct);
841  assert(lua_gettop(L) == top + 1);
842  return 0;
843 }
844 
845 /* parses single or multi work built in types, and pushes it onto the stack */
846 static int parse_type_name(lua_State* L, struct parser* P)
847 {
848  struct token tok;
849  int flags = 0;
850 
851  enum {
852  UNSIGNED = 0x01,
853  SIGNED = 0x02,
854  LONG = 0x04,
855  SHORT = 0x08,
856  INT = 0x10,
857  CHAR = 0x20,
858  LONG_LONG = 0x40,
859  INT8 = 0x80,
860  INT16 = 0x100,
861  INT32 = 0x200,
862  INT64 = 0x400,
863  DOUBLE = 0x800,
864  FLOAT = 0x1000,
865  COMPLEX = 0x2000,
866  };
867 
868  require_token(L, P, &tok);
869 
870  /* we have to manually decode the builtin types since they can take up
871  * more then one token
872  */
873  for (;;) {
874  if (tok.type != TOK_TOKEN) {
875  break;
876  } else if (IS_LITERAL(tok, "unsigned")) {
877  flags |= UNSIGNED;
878  } else if (IS_LITERAL(tok, "signed")) {
879  flags |= SIGNED;
880  } else if (IS_LITERAL(tok, "short")) {
881  flags |= SHORT;
882  } else if (IS_LITERAL(tok, "char")) {
883  flags |= CHAR;
884  } else if (IS_LITERAL(tok, "long")) {
885  flags |= (flags & LONG) ? LONG_LONG : LONG;
886  } else if (IS_LITERAL(tok, "int")) {
887  flags |= INT;
888  } else if (IS_LITERAL(tok, "__int8")) {
889  flags |= INT8;
890  } else if (IS_LITERAL(tok, "__int16")) {
891  flags |= INT16;
892  } else if (IS_LITERAL(tok, "__int32")) {
893  flags |= INT32;
894  } else if (IS_LITERAL(tok, "__int64")) {
895  flags |= INT64;
896  } else if (IS_LITERAL(tok, "double")) {
897  flags |= DOUBLE;
898  } else if (IS_LITERAL(tok, "float")) {
899  flags |= FLOAT;
900  } else if (IS_LITERAL(tok, "complex") || IS_LITERAL(tok, "_Complex")) {
901  flags |= COMPLEX;
902  } else if (IS_LITERAL(tok, "register")) {
903  /* ignore */
904  } else {
905  break;
906  }
907 
908  if (!next_token(L, P, &tok)) {
909  break;
910  }
911  }
912 
913  if (flags) {
914  put_back(P);
915  }
916 
917  if (flags & CHAR) {
918  if (flags & SIGNED) {
919  lua_pushliteral(L, "int8_t");
920  } else if (flags & UNSIGNED) {
921  lua_pushliteral(L, "uint8_t");
922  } else {
923  lua_pushstring(L, (((char) -1) > 0) ? "uint8_t" : "int8_t");
924  }
925 
926  } else if (flags & INT8) {
927  lua_pushstring(L, (flags & UNSIGNED) ? "uint8_t" : "int8_t");
928  } else if (flags & INT16) {
929  lua_pushstring(L, (flags & UNSIGNED) ? "uint16_t" : "int16_t");
930  } else if (flags & INT32) {
931  lua_pushstring(L, (flags & UNSIGNED) ? "uint32_t" : "int32_t");
932  } else if (flags & (INT64 | LONG_LONG)) {
933  lua_pushstring(L, (flags & UNSIGNED) ? "uint64_t" : "int64_t");
934 
935  } else if (flags & COMPLEX) {
936  if (flags & LONG) {
937  lua_pushliteral(L, "complex long double");
938  } else if (flags & FLOAT) {
939  lua_pushliteral(L, "complex float");
940  } else {
941  lua_pushliteral(L, "complex double");
942  }
943 
944  } else if (flags & DOUBLE) {
945  if (flags & LONG) {
946  lua_pushliteral(L, "long double");
947  } else {
948  lua_pushliteral(L, "double");
949  }
950 
951  } else if (flags & FLOAT) {
952  lua_pushliteral(L, "float");
953 
954  } else if (flags & SHORT) {
955 #define SHORT_TYPE(u) (sizeof(short) == sizeof(int64_t) ? u "int64_t" : sizeof(short) == sizeof(int32_t) ? u "int32_t" : u "int16_t")
956  if (flags & UNSIGNED) {
957  lua_pushstring(L, SHORT_TYPE("u"));
958  } else {
960  }
961 #undef SHORT_TYPE
962 
963  } else if (flags & LONG) {
964 #define LONG_TYPE(u) (sizeof(long) == sizeof(int64_t) ? u "int64_t" : u "int32_t")
965  if (flags & UNSIGNED) {
966  lua_pushstring(L, LONG_TYPE("u"));
967  } else {
968  lua_pushstring(L, LONG_TYPE(""));
969  }
970 #undef LONG_TYPE
971 
972  } else if (flags) {
973 #define INT_TYPE(u) (sizeof(int) == sizeof(int64_t) ? u "int64_t" : sizeof(int) == sizeof(int32_t) ? u "int32_t" : u "int16_t")
974  if (flags & UNSIGNED) {
975  lua_pushstring(L, INT_TYPE("u"));
976  } else {
977  lua_pushstring(L, INT_TYPE(""));
978  }
979 #undef INT_TYPE
980 
981  } else {
982  lua_pushlstring(L, tok.str, tok.size);
983  }
984 
985  return 0;
986 }
987 
988 /* parse_attribute parses a token to see if it is an attribute. It may then
989  * parse some following tokens to decode the attribute setting the appropriate
990  * fields in ct. It will return 1 if the token was used (and possibly some
991  * more following it) or 0 if not. If the token was used, the next token must
992  * be retrieved using next_token/require_token.
993  */
994 static int parse_attribute(lua_State* L, struct parser* P, struct token* tok, struct ctype* ct, struct parser* asmname)
995 {
996  if (tok->type != TOK_TOKEN) {
997  return 0;
998 
999  } else if (asmname && (IS_LITERAL(*tok, "__asm__") || IS_LITERAL(*tok, "__asm"))) {
1000  check_token(L, P, TOK_OPEN_PAREN, NULL, "unexpected token after __asm__ on line %d", P->line);
1001  *asmname = *P;
1002 
1003  require_token(L, P, tok);
1004  while (tok->type == TOK_STRING) {
1005  require_token(L, P, tok);
1006  }
1007 
1008  if (tok->type != TOK_CLOSE_PAREN) {
1009  luaL_error(L, "unexpected token after __asm__ on line %d", P->line);
1010  }
1011  return 1;
1012 
1013  } else if (IS_LITERAL(*tok, "__attribute__") || IS_LITERAL(*tok, "__declspec")) {
1014  int parens = 1;
1015  check_token(L, P, TOK_OPEN_PAREN, NULL, "expected parenthesis after __attribute__ or __declspec on line %d", P->line);
1016 
1017  for (;;) {
1018  require_token(L, P, tok);
1019  if (tok->type == TOK_OPEN_PAREN) {
1020  parens++;
1021  } else if (tok->type == TOK_CLOSE_PAREN) {
1022  if (--parens == 0) {
1023  break;
1024  }
1025 
1026  } else if (tok->type != TOK_TOKEN) {
1027  /* ignore unknown symbols within parentheses */
1028 
1029  } else if (IS_LITERAL(*tok, "align") || IS_LITERAL(*tok, "aligned") || IS_LITERAL(*tok, "__aligned__")) {
1030  unsigned align = 0;
1031  require_token(L, P, tok);
1032 
1033  switch (tok->type) {
1034  case TOK_CLOSE_PAREN:
1036  put_back(P);
1037  break;
1038 
1039  case TOK_OPEN_PAREN:
1040  require_token(L, P, tok);
1041 
1042  if (tok->type != TOK_NUMBER) {
1043  luaL_error(L, "expected align(#) on line %d", P->line);
1044  }
1045 
1046  switch (tok->integer) {
1047  case 1: align = 0; break;
1048  case 2: align = 1; break;
1049  case 4: align = 3; break;
1050  case 8: align = 7; break;
1051  case 16: align = 15; break;
1052  default:
1053  luaL_error(L, "unsupported align size on line %d", P->line);
1054  }
1055 
1056  check_token(L, P, TOK_CLOSE_PAREN, NULL, "expected align(#) on line %d", P->line);
1057  break;
1058 
1059  default:
1060  luaL_error(L, "expected align(#) on line %d", P->line);
1061  }
1062 
1063  /* __attribute__(aligned(#)) is only supposed to increase alignment */
1064  ct->align_mask = max(align, ct->align_mask);
1065 
1066  } else if (IS_LITERAL(*tok, "packed") || IS_LITERAL(*tok, "__packed__")) {
1067  ct->align_mask = 0;
1068  ct->is_packed = 1;
1069 
1070  } else if (IS_LITERAL(*tok, "mode") || IS_LITERAL(*tok, "__mode__")) {
1071 
1072  check_token(L, P, TOK_OPEN_PAREN, NULL, "expected mode(MODE) on line %d", P->line);
1073 
1074  require_token(L, P, tok);
1075  if (tok->type != TOK_TOKEN) {
1076  luaL_error(L, "expected mode(MODE) on line %d", P->line);
1077  }
1078 
1079  if (ct->type == FLOAT_TYPE || ct->type == DOUBLE_TYPE) {
1080  struct {char ch; float v;} af;
1081  struct {char ch; double v;} ad;
1082 
1083  if (IS_LITERAL(*tok, "SF") || IS_LITERAL(*tok, "__SF__")) {
1084  ct->type = FLOAT_TYPE;
1085  ct->base_size = sizeof(float);
1086  ct->align_mask = ALIGNOF(af);
1087 
1088  } else if (IS_LITERAL(*tok, "DF") || IS_LITERAL(*tok, "__DF__")) {
1089  ct->type = DOUBLE_TYPE;
1090  ct->base_size = sizeof(double);
1091  ct->align_mask = ALIGNOF(ad);
1092 
1093  } else {
1094  luaL_error(L, "unexpected mode on line %d", P->line);
1095  }
1096 
1097  } else {
1098  struct {char ch; uint16_t v;} a16;
1099  struct {char ch; uint32_t v;} a32;
1100  struct {char ch; uint64_t v;} a64;
1101 
1102  if (IS_LITERAL(*tok, "QI") || IS_LITERAL(*tok, "__QI__")
1103  || IS_LITERAL(*tok, "byte") || IS_LITERAL(*tok, "__byte__")
1104  ) {
1105  ct->type = INT8_TYPE;
1106  ct->base_size = sizeof(uint8_t);
1107  ct->align_mask = 0;
1108 
1109  } else if (IS_LITERAL(*tok, "HI") || IS_LITERAL(*tok, "__HI__")) {
1110  ct->type = INT16_TYPE;
1111  ct->base_size = sizeof(uint16_t);
1112  ct->align_mask = ALIGNOF(a16);
1113 
1114  } else if (IS_LITERAL(*tok, "SI") || IS_LITERAL(*tok, "__SI__")
1115 #if defined ARCH_X86 || defined ARCH_ARM
1116  || IS_LITERAL(*tok, "word") || IS_LITERAL(*tok, "__word__")
1117  || IS_LITERAL(*tok, "pointer") || IS_LITERAL(*tok, "__pointer__")
1118 #endif
1119  ) {
1120  ct->type = INT32_TYPE;
1121  ct->base_size = sizeof(uint32_t);
1122  ct->align_mask = ALIGNOF(a32);
1123 
1124  } else if (IS_LITERAL(*tok, "DI") || IS_LITERAL(*tok, "__DI__")
1125 #if defined ARCH_X64 || defined ARCH_PPC64
1126  || IS_LITERAL(*tok, "word") || IS_LITERAL(*tok, "__word__")
1127  || IS_LITERAL(*tok, "pointer") || IS_LITERAL(*tok, "__pointer__")
1128 #endif
1129  ) {
1130  ct->type = INT64_TYPE;
1131  ct->base_size = sizeof(uint64_t);
1132  ct->align_mask = ALIGNOF(a64);
1133 
1134  } else {
1135  luaL_error(L, "unexpected mode on line %d", P->line);
1136  }
1137  }
1138 
1139  check_token(L, P, TOK_CLOSE_PAREN, NULL, "expected mode(MODE) on line %d", P->line);
1140 
1141  } else if (IS_LITERAL(*tok, "cdecl") || IS_LITERAL(*tok, "__cdecl__")) {
1142  ct->calling_convention = C_CALL;
1143 
1144  } else if (IS_LITERAL(*tok, "fastcall") || IS_LITERAL(*tok, "__fastcall__")) {
1146 
1147  } else if (IS_LITERAL(*tok, "stdcall") || IS_LITERAL(*tok, "__stdcall__")) {
1149  }
1150  /* ignore unknown tokens within parentheses */
1151  }
1152  return 1;
1153 
1154  } else if (IS_LITERAL(*tok, "__cdecl")) {
1155  ct->calling_convention = C_CALL;
1156  return 1;
1157 
1158  } else if (IS_LITERAL(*tok, "__fastcall")) {
1160  return 1;
1161 
1162  } else if (IS_LITERAL(*tok, "__stdcall")) {
1164  return 1;
1165 
1166  } else if (IS_LITERAL(*tok, "__extension__") || IS_LITERAL(*tok, "extern")) {
1167  /* ignore */
1168  return 1;
1169 
1170  } else {
1171  return 0;
1172  }
1173 }
1174 
1175 /* parses out the base type of a type expression in a function declaration,
1176  * struct definition, typedef etc
1177  *
1178  * leaves the usr value of the type on the stack
1179  */
1180 int parse_type(lua_State* L, struct parser* P, struct ctype* ct)
1181 {
1182  struct token tok;
1183  int top = lua_gettop(L);
1184 
1185  memset(ct, 0, sizeof(*ct));
1186 
1187  require_token(L, P, &tok);
1188 
1189  /* get const/volatile before the base type */
1190  for (;;) {
1191  if (tok.type != TOK_TOKEN) {
1192  return luaL_error(L, "unexpected value before type name on line %d", P->line);
1193 
1194  } else if (IS_CONST(tok)) {
1195  ct->const_mask = 1;
1196  require_token(L, P, &tok);
1197 
1198  } else if (IS_VOLATILE(tok) ||
1199  IS_RESTRICT(tok) ||
1200  IS_LITERAL(tok, "static") ||
1201  IS_INLINE(tok)) {
1202  /* ignored for now */
1203  require_token(L, P, &tok);
1204  } else if (parse_attribute(L, P, &tok, ct, NULL)) {
1205  /* get function attributes before the return type */
1206  require_token(L, P, &tok);
1207 
1208  } else {
1209  break;
1210  }
1211  }
1212 
1213  /* get base type */
1214  if (tok.type != TOK_TOKEN) {
1215  return luaL_error(L, "unexpected value before type name on line %d", P->line);
1216 
1217  } else if (IS_LITERAL(tok, "struct")) {
1218  ct->type = STRUCT_TYPE;
1219  parse_record(L, P, ct);
1220 
1221  } else if (IS_LITERAL(tok, "union")) {
1222  ct->type = UNION_TYPE;
1223  parse_record(L, P, ct);
1224 
1225  } else if (IS_LITERAL(tok, "enum")) {
1226  ct->type = ENUM_TYPE;
1227  parse_record(L, P, ct);
1228 
1229  } else {
1230  put_back(P);
1231 
1232  /* lookup type */
1233  push_upval(L, &types_key);
1234  parse_type_name(L, P);
1235  lua_rawget(L, -2);
1236  lua_remove(L, -2);
1237 
1238  if (lua_isnil(L, -1)) {
1239  lua_pushlstring(L, tok.str, tok.size);
1240  return luaL_error(L, "unknown type %s on line %d", lua_tostring(L, -1), P->line);
1241  }
1242 
1243  instantiate_typedef(P, ct, (const struct ctype*) lua_touserdata(L, -1));
1244 
1245  /* we only want the usr tbl from the ctype in the types tbl */
1246  lua_getuservalue(L, -1);
1247  lua_replace(L, -2);
1248  }
1249 
1250  while (next_token(L, P, &tok)) {
1251  if (tok.type != TOK_TOKEN) {
1252  put_back(P);
1253  break;
1254 
1255  } else if (IS_CONST(tok) || IS_VOLATILE(tok)) {
1256  /* ignore for now */
1257 
1258  } else {
1259  put_back(P);
1260  break;
1261  }
1262  }
1263 
1264  assert(lua_gettop(L) == top + 1 && (lua_istable(L, -1) || lua_isnil(L, -1)));
1265  return 0;
1266 }
1267 
1272 };
1273 
1274 static void append_type_name(luaL_Buffer* B, int usr, const struct ctype* ct, enum name_type type)
1275 {
1276  size_t i;
1277  lua_State* L = B->L;
1278 
1279  usr = lua_absindex(L, usr);
1280 
1281  if (type == FRONT || type == BOTH) {
1282  if (ct->type != FUNCTION_PTR_TYPE && (ct->const_mask & (1 << ct->pointers))) {
1283  luaL_addstring(B, "const ");
1284  }
1285 
1286  if (ct->is_unsigned) {
1287  luaL_addstring(B, "unsigned ");
1288  }
1289 
1290  switch (ct->type) {
1291  case ENUM_TYPE:
1292  luaL_addstring(B, "enum ");
1293  goto get_name;
1294 
1295  case STRUCT_TYPE:
1296  luaL_addstring(B, "struct ");
1297  goto get_name;
1298 
1299  case UNION_TYPE:
1300  luaL_addstring(B, "union ");
1301  goto get_name;
1302 
1303  get_name:
1305  lua_rawget(L, usr);
1306  luaL_addvalue(B);
1307  break;
1308 
1309  case FUNCTION_TYPE:
1310  case FUNCTION_PTR_TYPE:
1312  lua_rawget(L, usr);
1313  luaL_addvalue(B);
1314  break;
1315 
1316  case VOID_TYPE:
1317  luaL_addstring(B, "void");
1318  break;
1319  case BOOL_TYPE:
1320  luaL_addstring(B, "bool");
1321  break;
1322  case DOUBLE_TYPE:
1323  luaL_addstring(B, "double");
1324  break;
1325  case LONG_DOUBLE_TYPE:
1326  luaL_addstring(B, "long double");
1327  break;
1328  case FLOAT_TYPE:
1329  luaL_addstring(B, "float");
1330  break;
1332  luaL_addstring(B, "long complex double");
1333  break;
1334  case COMPLEX_DOUBLE_TYPE:
1335  luaL_addstring(B, "complex double");
1336  break;
1337  case COMPLEX_FLOAT_TYPE:
1338  luaL_addstring(B, "complex float");
1339  break;
1340  case INT8_TYPE:
1341  luaL_addstring(B, "char");
1342  break;
1343  case INT16_TYPE:
1344  luaL_addstring(B, "short");
1345  break;
1346  case INT32_TYPE:
1347  luaL_addstring(B, "int");
1348  break;
1349  case INT64_TYPE:
1350  luaL_addstring(B, "long long");
1351  break;
1352 
1353  case INTPTR_TYPE:
1354  if (sizeof(intptr_t) == sizeof(int32_t)) {
1355  luaL_addstring(B, "long");
1356  } else if (sizeof(intptr_t) == sizeof(int64_t)) {
1357  luaL_addstring(B, "long long");
1358  } else {
1359  luaL_error(L, "internal error - bad type");
1360  }
1361  break;
1362 
1363  default:
1364  luaL_error(L, "internal error - bad type %d", ct->type);
1365  }
1366 
1367  for (i = 0; i < ct->pointers - ct->is_array; i++) {
1368  luaL_addchar(B, '*');
1369  if (ct->const_mask & (1 << (ct->pointers - i - 1))) {
1370  luaL_addstring(B, " const");
1371  }
1372  }
1373  }
1374 
1375  if (type == BOTH || type == BACK) {
1376  if (ct->is_reference) {
1377  luaL_addstring(B, " &");
1378  }
1379 
1380  if (ct->is_variable_array && !ct->variable_size_known) {
1381  luaL_addstring(B, "[?]");
1382  } else if (ct->is_array) {
1383  lua_pushfstring(L, "[%d]", (int) ct->array_size);
1384  luaL_addvalue(B);
1385  }
1386 
1387  if (ct->type == FUNCTION_PTR_TYPE || ct->type == FUNCTION_TYPE) {
1389  lua_rawget(L, usr);
1390  luaL_addvalue(B);
1391  }
1392 
1393  if (ct->is_bitfield) {
1394  lua_pushfstring(L, " : %d", (int) ct->bit_size);
1395  luaL_addvalue(B);
1396  }
1397  }
1398 }
1399 
1400 void push_type_name(lua_State* L, int usr, const struct ctype* ct)
1401 {
1402  luaL_Buffer B;
1403  usr = lua_absindex(L, usr);
1404  luaL_buffinit(L, &B);
1405  append_type_name(&B, usr, ct, BOTH);
1406  luaL_pushresult(&B);
1407 }
1408 
1409 static void push_function_type_strings(lua_State* L, int usr, const struct ctype* ct)
1410 {
1411  size_t i, args;
1412  luaL_Buffer B;
1413  int top = lua_gettop(L);
1414  const struct ctype* ret_ct;
1415 
1416  int arg_ct = top+3;
1417  int arg_usr = top+4;
1418  int ret_usr = top+6;
1419 
1420  usr = lua_absindex(L, usr);
1421 
1422  /* return type */
1423  lua_settop(L, top+4); /* room for two returns and two temp positions */
1424  lua_rawgeti(L, usr, 0);
1425  lua_getuservalue(L, -1);
1426  ret_ct = (const struct ctype*) lua_touserdata(L, -2);
1427 
1428  luaL_buffinit(L, &B);
1429  append_type_name(&B, ret_usr, ret_ct, FRONT);
1430 
1431  if (ret_ct->type != FUNCTION_TYPE && ret_ct->type != FUNCTION_PTR_TYPE) {
1432  luaL_addchar(&B, ' ');
1433  }
1434 
1435  switch (ct->calling_convention) {
1436  case STD_CALL:
1437  luaL_addstring(&B, "(__stdcall *");
1438  break;
1439  case FAST_CALL:
1440  luaL_addstring(&B, "(__fastcall *");
1441  break;
1442  case C_CALL:
1443  luaL_addstring(&B, "(*");
1444  break;
1445  default:
1446  luaL_error(L, "internal error - unknown calling convention");
1447  }
1448 
1449  luaL_pushresult(&B);
1450  lua_replace(L, top+1);
1451 
1452  luaL_buffinit(L, &B);
1453  luaL_addstring(&B, ")(");
1454 
1455  /* arguments */
1456  args = lua_rawlen(L, usr);
1457  for (i = 1; i <= args; i++) {
1458  if (i > 1) {
1459  luaL_addstring(&B, ", ");
1460  }
1461 
1462  /* note push the arg and user value below the indexes used by the buffer
1463  * and use indexes relative to top to avoid problems due to the buffer
1464  * system pushing a variable number of arguments onto the stack */
1465  lua_rawgeti(L, usr, (int) i);
1466  lua_replace(L, arg_ct);
1467  lua_getuservalue(L, arg_ct);
1468  lua_replace(L, arg_usr);
1469  append_type_name(&B, arg_usr, (const struct ctype*) lua_touserdata(L, arg_ct), BOTH);
1470  }
1471 
1472  luaL_addstring(&B, ")");
1473  append_type_name(&B, ret_usr, ret_ct, BACK);
1474  luaL_pushresult(&B);
1475  lua_replace(L, top+2);
1476 
1477  lua_settop(L, top+2);
1478  assert(lua_isstring(L, top+1) && lua_isstring(L, top+2));
1479 }
1480 
1481 /* parses from after the opening paranthesis to after the closing parenthesis */
1482 static void parse_function_arguments(lua_State* L, struct parser* P, int ct_usr, struct ctype* ct)
1483 {
1484  struct token tok;
1485  int args = 0;
1486  int top = lua_gettop(L);
1487 
1488  ct_usr = lua_absindex(L, ct_usr);
1489 
1490  for (;;) {
1491  require_token(L, P, &tok);
1492 
1493  if (tok.type == TOK_CLOSE_PAREN) {
1494  break;
1495  }
1496 
1497  if (args) {
1498  if (tok.type != TOK_COMMA) {
1499  luaL_error(L, "unexpected token in function argument %d on line %d", args, P->line);
1500  }
1501 
1502  require_token(L, P, &tok);
1503  }
1504 
1505  if (tok.type == TOK_VA_ARG) {
1506  ct->has_var_arg = true;
1507  check_token(L, P, TOK_CLOSE_PAREN, "", "unexpected token after ... in function on line %d", P->line);
1508  break;
1509 
1510  } else if (tok.type == TOK_TOKEN) {
1511  struct ctype at;
1512 
1513  put_back(P);
1514  parse_type(L, P, &at);
1515  parse_argument(L, P, -1, &at, NULL, NULL);
1516 
1517  assert(lua_gettop(L) == top + 2);
1518 
1519  /* array arguments are just treated as their base pointer type */
1520  at.is_array = 0;
1521 
1522  /* check for the c style int func(void) and error on other uses of arguments of type void */
1523  if (at.type == VOID_TYPE && at.pointers == 0) {
1524  if (args) {
1525  luaL_error(L, "can't have argument of type void on line %d", P->line);
1526  }
1527 
1528  check_token(L, P, TOK_CLOSE_PAREN, "", "unexpected void in function on line %d", P->line);
1529  lua_pop(L, 2);
1530  break;
1531  }
1532 
1533  push_ctype(L, -1, &at);
1534  lua_rawseti(L, ct_usr, ++args);
1535 
1536  lua_pop(L, 2); /* parse_type and parse_argument at_usr */
1537 
1538  } else {
1539  luaL_error(L, "unexpected token in function argument %d on line %d", args+1, P->line);
1540  }
1541  }
1542 
1543  assert(lua_gettop(L) == top);
1544 }
1545 
1546 static int max_bitfield_size(int type)
1547 {
1548  switch (type) {
1549  case BOOL_TYPE:
1550  return 1;
1551  case INT8_TYPE:
1552  return 8;
1553  case INT16_TYPE:
1554  return 16;
1555  case INT32_TYPE:
1556  case ENUM_TYPE:
1557  return 32;
1558  case INT64_TYPE:
1559  return 64;
1560  default:
1561  return -1;
1562  }
1563 }
1564 
1565 static struct ctype* parse_argument2(lua_State* L, struct parser* P, int ct_usr, struct ctype* ct, struct token* name, struct parser* asmname);
1566 
1567 /* parses from after the first ( in a function declaration or function pointer
1568  * can be one of:
1569  * void foo(...) before ...
1570  * void (foo)(...) before foo
1571  * void (* <>)(...) before <> which is the inner type
1572  */
1573 static struct ctype* parse_function(lua_State* L, struct parser* P, int ct_usr, struct ctype* ct, struct token* name, struct parser* asmname)
1574 {
1575  /* We have a function pointer or a function. The usr table will
1576  * get replaced by the canonical one (if there is one) in
1577  * find_canonical_usr after all the arguments and returns have
1578  * been parsed. */
1579  struct token tok;
1580  int top = lua_gettop(L);
1581  struct ctype* ret;
1582 
1583  lua_newtable(L);
1584  ret = push_ctype(L, ct_usr, ct);
1585  lua_rawseti(L, -2, 0);
1586  ct_usr = lua_gettop(L);
1587 
1588  memset(ct, 0, sizeof(*ct));
1589  ct->base_size = sizeof(void (*)());
1590  ct->align_mask = min(FUNCTION_ALIGN_MASK, P->align_mask);
1591  ct->type = FUNCTION_TYPE;
1592  ct->is_defined = 1;
1593 
1594  if (name->type == TOK_NIL) {
1595  for (;;) {
1596  require_token(L, P, &tok);
1597 
1598  if (tok.type == TOK_STAR) {
1599 
1600  if (ct->type == FUNCTION_TYPE) {
1601  ct->type = FUNCTION_PTR_TYPE;
1602  } else if (ct->pointers == POINTER_MAX) {
1603  luaL_error(L, "maximum number of pointer derefs reached - use a struct to break up the pointers on line %d", P->line);
1604  } else {
1605  ct->pointers++;
1606  ct->const_mask <<= 1;
1607  }
1608 
1609  } else if (parse_attribute(L, P, &tok, ct, asmname)) {
1610  /* parse_attribute sets the appropriate fields */
1611 
1612  } else {
1613  /* call parse_argument to handle the inner contents
1614  * e.g. the <> in "void (* <>) (...)". Note that the
1615  * inner contents can itself be a function, a function
1616  * ptr, array, etc (e.g. "void (*signal(int sig, void
1617  * (*func)(int)))(int)" ).
1618  */
1619  put_back(P);
1620  ct = parse_argument2(L, P, ct_usr, ct, name, asmname);
1621  break;
1622  }
1623  }
1624 
1625  check_token(L, P, TOK_CLOSE_PAREN, NULL, "unexpected token in function on line %d", P->line);
1626  check_token(L, P, TOK_OPEN_PAREN, NULL, "unexpected token in function on line %d", P->line);
1627  }
1628 
1629  parse_function_arguments(L, P, ct_usr, ct);
1630 
1631  /* if we have an inner function then set the outer function ptr as its
1632  * return type and return the inner function
1633  * e.g. for void (* <signal(int, void (*)(int))> )(int) inner is
1634  * surrounded by <>, return type is void (*)(int)
1635  */
1636  if (lua_gettop(L) == ct_usr+1) {
1637  lua_replace(L, ct_usr);
1638  }
1639 
1640  assert(lua_gettop(L) == top + 1 && lua_istable(L, -1));
1641  return ret;
1642 }
1643 
1644 static struct ctype* parse_argument2(lua_State* L, struct parser* P, int ct_usr, struct ctype* ct, struct token* name, struct parser* asmname)
1645 {
1646  struct token tok;
1647  int top = lua_gettop(L);
1648  int ft_usr = 0;
1649 
1650  luaL_checkstack(L, 10, "function too complex");
1651  ct_usr = lua_absindex(L, ct_usr);
1652 
1653  for (;;) {
1654  if (!next_token(L, P, &tok)) {
1655  /* we've reached the end of the string */
1656  break;
1657 
1658  } else if (tok.type == TOK_STAR) {
1659  if (ct->pointers == POINTER_MAX) {
1660  luaL_error(L, "maximum number of pointer derefs reached - use a struct to break up the pointers on line %d", P->line);
1661  }
1662 
1663  ct->pointers++;
1664  ct->const_mask <<= 1;
1665 
1666  /* __declspec(align(#)) may come before the type in a member */
1667  if (!ct->is_packed) {
1668  ct->align_mask = max(min(PTR_ALIGN_MASK, P->align_mask), ct->align_mask);
1669  }
1670 
1671  } else if (tok.type == TOK_REFERENCE) {
1672  ct->is_reference = 1;
1673 
1674  } else if (parse_attribute(L, P, &tok, ct, asmname)) {
1675  /* parse attribute has filled out appropriate fields in type */
1676 
1677  } else if (tok.type == TOK_OPEN_PAREN) {
1678  ct = parse_function(L, P, ct_usr, ct, name, asmname);
1679  ft_usr = lua_gettop(L);
1680 
1681  } else if (tok.type == TOK_OPEN_SQUARE) {
1682  /* array */
1683  if (ct->pointers == POINTER_MAX) {
1684  luaL_error(L, "maximum number of pointer derefs reached - use a struct to break up the pointers");
1685  }
1686  ct->is_array = 1;
1687  ct->pointers++;
1688  ct->const_mask <<= 1;
1689  require_token(L, P, &tok);
1690 
1691  if (ct->pointers == 1 && !ct->is_defined) {
1692  luaL_error(L, "array of undefined type on line %d", P->line);
1693  }
1694 
1695  if (ct->is_variable_struct || ct->is_variable_array) {
1696  luaL_error(L, "can't have an array of a variably sized type on line %d", P->line);
1697  }
1698 
1699  if (tok.type == TOK_QUESTION) {
1700  ct->is_variable_array = 1;
1701  ct->variable_increment = (ct->pointers > 1) ? sizeof(void*) : ct->base_size;
1702  check_token(L, P, TOK_CLOSE_SQUARE, "", "invalid character in array on line %d", P->line);
1703 
1704  } else if (tok.type == TOK_CLOSE_SQUARE) {
1705  ct->array_size = 0;
1706 
1707  } else if (tok.type == TOK_TOKEN && IS_RESTRICT(tok)) {
1708  /* odd gcc extension foo[__restrict] for arguments */
1709  ct->array_size = 0;
1710  check_token(L, P, TOK_CLOSE_SQUARE, "", "invalid character in array on line %d", P->line);
1711 
1712  } else {
1713  int64_t asize;
1714  put_back(P);
1715  asize = calculate_constant(L, P);
1716  if (asize < 0) {
1717  luaL_error(L, "array size can not be negative on line %d", P->line);
1718  }
1719  ct->array_size = (size_t) asize;
1720  check_token(L, P, TOK_CLOSE_SQUARE, "", "invalid character in array on line %d", P->line);
1721  }
1722 
1723  } else if (tok.type == TOK_COLON) {
1724  int64_t bsize = calculate_constant(L, P);
1725 
1726  if (ct->pointers || bsize < 0 || bsize > max_bitfield_size(ct->type)) {
1727  luaL_error(L, "invalid bitfield on line %d", P->line);
1728  }
1729 
1730  ct->is_bitfield = 1;
1731  ct->bit_size = (unsigned) bsize;
1732 
1733  } else if (tok.type != TOK_TOKEN) {
1734  /* we've reached the end of the declaration */
1735  put_back(P);
1736  break;
1737 
1738  } else if (IS_CONST(tok)) {
1739  ct->const_mask |= 1;
1740 
1741  } else if (IS_VOLATILE(tok) || IS_RESTRICT(tok)) {
1742  /* ignored for now */
1743 
1744  } else {
1745  *name = tok;
1746  }
1747  }
1748 
1749  assert((ft_usr == 0 && lua_gettop(L) == top) || (lua_gettop(L) == top + 1 && ft_usr == top + 1 && (lua_istable(L, -1) || lua_isnil(L, -1))));
1750  return ct;
1751 }
1752 
1753 static void find_canonical_usr(lua_State* L, int ct_usr, const struct ctype *ct)
1754 {
1755  struct ctype rt;
1756  int top = lua_gettop(L);
1757  int types;
1758 
1759  if (ct->type != FUNCTION_PTR_TYPE && ct->type != FUNCTION_TYPE) {
1760  return;
1761  }
1762 
1763  luaL_checkstack(L, 10, "function too complex");
1764  ct_usr = lua_absindex(L, ct_usr);
1765 
1766  /* check to see if we already have the canonical usr table */
1768  lua_rawget(L, ct_usr);
1769  if (!lua_isnil(L, -1)) {
1770  lua_pop(L, 1);
1771  assert(top == lua_gettop(L));
1772  return;
1773  }
1774  lua_pop(L, 1);
1775 
1776  assert(top == lua_gettop(L));
1777 
1778  /* first canonize the return type */
1779  lua_rawgeti(L, ct_usr, 0);
1780  rt = *(struct ctype*) lua_touserdata(L, -1);
1781  lua_getuservalue(L, -1);
1782  find_canonical_usr(L, -1, &rt);
1783  push_ctype(L, -1, &rt);
1784  lua_rawseti(L, ct_usr, 0);
1785  lua_pop(L, 2); /* return ctype and usr */
1786 
1787  assert(top == lua_gettop(L));
1788 
1789  /* look up the type string in the types table */
1790  push_upval(L, &types_key);
1791  types = lua_gettop(L);
1792 
1793  push_function_type_strings(L, ct_usr, ct);
1794  lua_pushvalue(L, -2);
1795  lua_pushvalue(L, -2);
1796  lua_concat(L, 2);
1797 
1798  lua_pushvalue(L, -1);
1799  lua_rawget(L, types);
1800 
1801  assert(lua_gettop(L) == types + 4 && types == top + 1);
1802  /* stack: types, front, back, both, looked up value */
1803 
1804  if (lua_isnil(L, -1)) {
1805  lua_pop(L, 1);
1806 
1808  lua_pushvalue(L, -4);
1809  lua_rawset(L, ct_usr);
1810 
1812  lua_pushvalue(L, -3);
1813  lua_rawset(L, ct_usr);
1814 
1816  lua_pushvalue(L, -2);
1817  lua_rawset(L, ct_usr);
1818 
1819  lua_pushvalue(L, -1);
1820  push_ctype(L, ct_usr, ct);
1821  lua_rawset(L, types);
1822  } else {
1823  lua_getuservalue(L, -1);
1824  lua_replace(L, ct_usr);
1825  lua_pop(L, 1);
1826  }
1827 
1828  lua_pop(L, 4);
1829  assert(top == lua_gettop(L) && types == top + 1);
1830 }
1831 
1832 
1833 /* parses after the main base type of a typedef, function argument or
1834  * struct/union member
1835  * eg for const void* bar[3] the base type is void with the subtype so far of
1836  * const, this parses the "* bar[3]" and updates the type argument
1837  *
1838  * ct_usr and type must be as filled out by parse_type
1839  *
1840  * pushes the updated user value on the top of the stack
1841  */
1842 void parse_argument(lua_State* L, struct parser* P, int ct_usr, struct ctype* ct, struct token* pname, struct parser* asmname)
1843 {
1844  struct token tok, name;
1845  int top = lua_gettop(L);
1846 
1847  memset(&name, 0, sizeof(name));
1848  parse_argument2(L, P, ct_usr, ct, &name, asmname);
1849 
1850  for (;;) {
1851  if (!next_token(L, P, &tok)) {
1852  break;
1853  } else if (parse_attribute(L, P, &tok, ct, asmname)) {
1854  /* parse_attribute sets the appropriate fields */
1855  } else {
1856  put_back(P);
1857  break;
1858  }
1859  }
1860 
1861  if (lua_gettop(L) == top) {
1862  lua_pushvalue(L, ct_usr);
1863  }
1864 
1865  find_canonical_usr(L, -1, ct);
1866 
1867  if (pname) {
1868  *pname = name;
1869  }
1870 }
1871 
1872 static void parse_typedef(lua_State* L, struct parser* P)
1873 {
1874  struct token tok;
1875  struct ctype base_type;
1876  int top = lua_gettop(L);
1877 
1878  parse_type(L, P, &base_type);
1879 
1880  for (;;) {
1881  struct ctype arg_type = base_type;
1882  struct token name;
1883 
1884  memset(&name, 0, sizeof(name));
1885 
1886  assert(lua_gettop(L) == top + 1);
1887  parse_argument(L, P, -1, &arg_type, &name, NULL);
1888  assert(lua_gettop(L) == top + 2);
1889 
1890  if (!name.size) {
1891  luaL_error(L, "Can't have a typedef without a name on line %d", P->line);
1892  } else if (arg_type.is_variable_array) {
1893  luaL_error(L, "Can't typedef a variable length array on line %d", P->line);
1894  }
1895 
1896  push_upval(L, &types_key);
1897  lua_pushlstring(L, name.str, name.size);
1898  push_ctype(L, -3, &arg_type);
1899  lua_rawset(L, -3);
1900  lua_pop(L, 2); /* types and parse_argument usr tbl */
1901 
1902  require_token(L, P, &tok);
1903 
1904  if (tok.type == TOK_SEMICOLON) {
1905  break;
1906  } else if (tok.type != TOK_COMMA) {
1907  luaL_error(L, "Unexpected character in typedef on line %d", P->line);
1908  }
1909  }
1910 
1911  lua_pop(L, 1); /* parse_type usr tbl */
1912  assert(lua_gettop(L) == top);
1913 }
1914 
1915 static bool is_hex(char ch)
1916 { return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F'); }
1917 
1918 static bool is_digit(char ch)
1919 { return '0' <= ch && ch <= '9'; }
1920 
1921 static int from_hex(char ch)
1922 {
1923  if (ch >= 'a') {
1924  return ch - 'a' + 10;
1925  } else if (ch >= 'A') {
1926  return ch - 'A' + 10;
1927  } else {
1928  return ch - '0';
1929  }
1930 }
1931 
1932 static void push_strings(lua_State* L, struct parser* P)
1933 {
1934  luaL_Buffer B;
1935  luaL_buffinit(L, &B);
1936 
1937  for (;;) {
1938  const char *p, *e;
1939  char *t, *s;
1940  struct token tok;
1941 
1942  require_token(L, P, &tok);
1943  if (tok.type != TOK_STRING) {
1944  break;
1945  }
1946 
1947  p = tok.str;
1948  e = p + tok.size;
1949 
1950  t = luaL_prepbuffsize(&B, tok.size);
1951  s = t;
1952 
1953  while (p < e) {
1954  if (*p == '\\') {
1955  if (++p == e) {
1956  luaL_error(L, "parse error in string");
1957  }
1958  switch (*p) {
1959  case '\\': *(t++) = '\\'; p++; break;
1960  case '\"': *(t++) = '\"'; p++; break;
1961  case '\'': *(t++) = '\''; p++; break;
1962  case 'n': *(t++) = '\n'; p++; break;
1963  case 'r': *(t++) = '\r'; p++; break;
1964  case 'b': *(t++) = '\b'; p++; break;
1965  case 't': *(t++) = '\t'; p++; break;
1966  case 'f': *(t++) = '\f'; p++; break;
1967  case 'a': *(t++) = '\a'; p++; break;
1968  case 'v': *(t++) = '\v'; p++; break;
1969  case 'e': *(t++) = 0x1B; p++; break;
1970  case 'x':
1971  {
1972  uint8_t u;
1973  p++;
1974  if (p + 2 > e || !is_hex(p[0]) || !is_hex(p[1])) {
1975  luaL_error(L, "parse error in string");
1976  }
1977  u = (from_hex(p[0]) << 4) | from_hex(p[1]);
1978  *(t++) = *(char*) &u;
1979  p += 2;
1980  break;
1981  }
1982  default:
1983  {
1984  uint8_t u;
1985  const char* e2 = min(p + 3, e);
1986  if (!is_digit(*p)) {
1987  luaL_error(L, "parse error in string");
1988  }
1989  u = *p - '0';
1990  p++;
1991  while (is_digit(*p) && p < e2) {
1992  u = 10*u + *p-'0';
1993  p++;
1994  }
1995  *(t++) = *(char*) &u;
1996  break;
1997  }
1998  }
1999  } else {
2000  *(t++) = *(p++);
2001  }
2002  }
2003 
2004  luaL_addsize(&B, t-s);
2005  }
2006 
2007  luaL_pushresult(&B);
2008 }
2009 
2011  struct parser* P,
2012  const struct ctype* type,
2013  const struct token* name)
2014 {
2016 
2017  check_token(L, P, TOK_SEMICOLON, "", "expected ; after constant definition on line %d", P->line);
2018 
2020  lua_pushlstring(L, name->str, name->size);
2021 
2022  switch (type->type) {
2023  case INT8_TYPE:
2024  case INT16_TYPE:
2025  case INT32_TYPE:
2026  if (type->is_unsigned)
2027  lua_pushinteger(L, (unsigned int) val);
2028  else
2029  lua_pushinteger(L, (int) val);
2030  break;
2031 
2032  default:
2033  luaL_error(L, "expected a valid 8-, 16-, or 32-bit signed or unsigned integer type after 'static const' on line %d", P->line);
2034  }
2035 
2036  lua_rawset(L, -3);
2037  lua_pop(L, 2); /*constants and type*/
2038 }
2039 
2040 #define END 0
2041 #define PRAGMA_POP 1
2042 
2043 static int parse_root(lua_State* L, struct parser* P)
2044 {
2045  int top = lua_gettop(L);
2046  struct token tok;
2047 
2048  while (next_token(L, P, &tok)) {
2049  /* we can have:
2050  * struct definition
2051  * enum definition
2052  * union definition
2053  * struct/enum/union declaration
2054  * typedef
2055  * function declaration
2056  * pragma pack
2057  */
2058 
2059  assert(lua_gettop(L) == top);
2060 
2061  if (tok.type == TOK_SEMICOLON) {
2062  /* empty semicolon in root continue on */
2063 
2064  } else if (tok.type == TOK_POUND) {
2065 
2066  check_token(L, P, TOK_TOKEN, "pragma", "unexpected pre processor directive on line %d", P->line);
2067  check_token(L, P, TOK_TOKEN, "pack", "unexpected pre processor directive on line %d", P->line);
2068  check_token(L, P, TOK_OPEN_PAREN, "", "invalid pack directive on line %d", P->line);
2069 
2070  require_token(L, P, &tok);
2071 
2072  if (tok.type == TOK_NUMBER) {
2073  if (tok.integer != 1 && tok.integer != 2 && tok.integer != 4 && tok.integer != 8 && tok.integer != 16) {
2074  luaL_error(L, "pack directive with invalid pack size on line %d", P->line);
2075  }
2076 
2077  P->align_mask = (unsigned) (tok.integer - 1);
2078  check_token(L, P, TOK_CLOSE_PAREN, "", "invalid pack directive on line %d", P->line);
2079 
2080  } else if (tok.type == TOK_TOKEN && IS_LITERAL(tok, "push")) {
2081  int line = P->line;
2082  unsigned previous_alignment = P->align_mask;
2083 
2084  check_token(L, P, TOK_CLOSE_PAREN, "", "invalid pack directive on line %d", P->line);
2085 
2086  if (parse_root(L, P) != PRAGMA_POP) {
2087  luaL_error(L, "reached end of string without a pragma pop to match the push on line %d", line);
2088  }
2089 
2090  P->align_mask = previous_alignment;
2091 
2092  } else if (tok.type == TOK_TOKEN && IS_LITERAL(tok, "pop")) {
2093  check_token(L, P, TOK_CLOSE_PAREN, "", "invalid pack directive on line %d", P->line);
2094  return PRAGMA_POP;
2095 
2096  } else {
2097  luaL_error(L, "invalid pack directive on line %d", P->line);
2098  }
2099 
2100 
2101  } else if (tok.type != TOK_TOKEN) {
2102  return luaL_error(L, "unexpected character on line %d", P->line);
2103 
2104  } else if (IS_LITERAL(tok, "__extension__")) {
2105  /* ignore */
2106  continue;
2107 
2108  } else if (IS_LITERAL(tok, "extern")) {
2109  /* ignore extern as data and functions can only be extern */
2110  continue;
2111 
2112  } else if (IS_LITERAL(tok, "typedef")) {
2113  parse_typedef(L, P);
2114 
2115  } else {
2116  /* type declaration, type definition, or function declaration */
2117  struct ctype type;
2118  struct token name;
2119  struct parser asmname;
2120 
2121  memset(&name, 0, sizeof(name));
2122  memset(&asmname, 0, sizeof(asmname));
2123 
2124  put_back(P);
2125  parse_type(L, P, &type);
2126 
2127  for (;;) {
2128  parse_argument(L, P, -1, &type, &name, &asmname);
2129 
2130  if (name.size) {
2131  /* global/function declaration */
2132 
2133  /* set asmname_tbl[name] = asmname */
2134  if (asmname.next) {
2136  lua_pushlstring(L, name.str, name.size);
2137  push_strings(L, &asmname);
2138  lua_rawset(L, -3);
2139  lua_pop(L, 1); /* asmname upval */
2140  }
2141 
2143  lua_pushlstring(L, name.str, name.size);
2144  push_ctype(L, -3, &type);
2145  lua_rawset(L, -3);
2146  lua_pop(L, 1); /* functions upval */
2147  } else {
2148  /* type declaration/definition - already been processed */
2149  }
2150 
2151  lua_pop(L, 1);
2152 
2153  if (!next_token(L, P, &tok)) {
2154  break;
2155  }
2156 
2157  if (tok.type == TOK_COMMA) {
2158  continue;
2159  }
2160 
2161  if (tok.type == TOK_OPEN_CURLY) {
2162  int line = P->line;
2163  int remaining = 1;
2164  while (remaining > 0 && next_token(L, P, &tok)) {
2165  if (tok.type == TOK_CLOSE_CURLY) {
2166  remaining--;
2167  } else if (tok.type == TOK_OPEN_CURLY) {
2168  remaining++;
2169  }
2170  }
2171  if (remaining > 0) {
2172  luaL_error(L, "missing closing bracket for line %d", line);
2173  }
2174  } else if (tok.type == TOK_ASSIGN) {
2176  } else if (tok.type != TOK_SEMICOLON) {
2177  luaL_error(L, "missing semicolon on line %d", P->line);
2178  }
2179  break;
2180  }
2181 
2182  lua_pop(L, 1);
2183  }
2184  }
2185 
2186  return END;
2187 }
2188 
2190 {
2191  struct parser P;
2192 
2193  P.line = 1;
2194  P.prev = P.next = luaL_checkstring(L, 1);
2195  P.align_mask = DEFAULT_ALIGN_MASK;
2196 
2197  if (parse_root(L, &P) == PRAGMA_POP) {
2198  luaL_error(L, "pragma pop without an associated push on line %d", P.line);
2199  }
2200 
2201  return 0;
2202 }
2203 
2204 /* calculate_constant handles operator precedence by having a number of
2205  * recursive commands each of which computes the result at that level of
2206  * precedence and above. calculate_constant1 is the highest precedence
2207  */
2208 
2209 static int64_t string_to_int(const char* str, size_t size)
2210 {
2211  const char* end = str + size;
2212  char c = *str++;
2213  if (str < end)
2214  {
2215  if (c == '\\') {
2216  c = *str++;
2217  switch (c) {
2218  case '\'': c = '\''; break;
2219  case '\"': c = '\"'; break;
2220  case '\?': c = '\?'; break;
2221  case '\\': c = '\\'; break;
2222  case 'a': c = '\a'; break;
2223  case 'b': c = '\b'; break;
2224  case 'f': c = '\f'; break;
2225  case 'n': c = '\n'; break;
2226  case 'r': c = '\r'; break;
2227  case 't': c = '\t'; break;
2228  case 'v': c = '\v'; break;
2229  case 'e': c = 27; break;
2230  case 'x':
2231  c = 0;
2232  while (str < end) {
2233  char d = *str++;
2234  c *= 16;
2235  if (d >= '0' && d <= '9') c += (d - '0');
2236  else c += (d - 'a' + 10);
2237  }
2238  break;
2239  default:
2240  c = c - '0';
2241  while (str < end) {
2242  char d = *str++;
2243  c = c*8 + (d - '0');
2244  }
2245  break;
2246  }
2247  }
2248  }
2249  return c;
2250 }
2251 
2252 static int try_cast(lua_State* L)
2253 {
2254  struct parser* P = (struct parser*) lua_touserdata(L, 1);
2255  struct ctype ct;
2256  struct token name, tok;
2257  memset(&name, 0, sizeof(name));
2258 
2259  parse_type(L, P, &ct);
2260  parse_argument(L, P, -1, &ct, &name, NULL);
2261 
2262  require_token(L, P, &tok);
2263  if (tok.type != TOK_CLOSE_PAREN || name.size) {
2264  return luaL_error(L, "invalid cast");
2265  }
2266 
2267  if (ct.pointers/* || ct.type != INT32_TYPE*/) {
2268  return luaL_error(L, "unsupported cast on line %d", P->line);
2269  }
2270 
2271  return 0;
2272 }
2273 
2274 static int64_t calculate_constant2(lua_State* L, struct parser* P, struct token* tok);
2275 
2276 /* () */
2278 {
2279  int64_t ret;
2280 
2281  if (tok->type == TOK_NUMBER) {
2282  ret = tok->integer;
2283  next_token(L, P, tok);
2284  return ret;
2285 
2286  } else if (tok->type == TOK_TOKEN) {
2287  /* look up name in constants table */
2289  lua_pushlstring(L, tok->str, tok->size);
2290  lua_rawget(L, -2);
2291  lua_remove(L, -2); /* constants table */
2292 
2293  if (!lua_isnumber(L, -1)) {
2294  lua_pushlstring(L, tok->str, tok->size);
2295  luaL_error(L, "use of undefined constant %s on line %d", lua_tostring(L, -1), P->line);
2296  }
2297 
2298  ret = (int64_t) lua_tonumber(L, -1);
2299  lua_pop(L, 1);
2300  next_token(L, P, tok);
2301  return ret;
2302 
2303  } else if (tok->type == TOK_OPEN_PAREN) {
2304  struct parser before_cast = *P;
2305  int top = lua_gettop(L);
2306 
2307  /* see if this is a numeric cast, which we ignore */
2310  if (!lua_pcall(L, 1, 0, 0)) {
2311  next_token(L, P, tok);
2312  return calculate_constant2(L, P, tok);
2313  }
2314  lua_settop(L, top);
2315 
2316  *P = before_cast;
2317  ret = calculate_constant(L, P);
2318 
2319  require_token(L, P, tok);
2320  if (tok->type != TOK_CLOSE_PAREN) {
2321  luaL_error(L, "error whilst parsing constant at line %d", P->line);
2322  }
2323 
2324  next_token(L, P, tok);
2325  return ret;
2326 
2327  } else if (tok->type == TOK_STRING) {
2328  ret = string_to_int(tok->str, tok->size);
2329 
2330  next_token(L, P, tok);
2331  return ret;
2332 
2333  } else {
2334  return luaL_error(L, "unexpected token whilst parsing constant at line %d", P->line);
2335  }
2336 }
2337 
2338 /* ! and ~, unary + and -, and sizeof */
2340 {
2341  if (tok->type == TOK_LOGICAL_NOT) {
2342  require_token(L, P, tok);
2343  return !calculate_constant2(L, P, tok);
2344 
2345  } else if (tok->type == TOK_BITWISE_NOT) {
2346  require_token(L, P, tok);
2347  return ~~calculate_constant2(L, P, tok);
2348 
2349  } else if (tok->type == TOK_PLUS) {
2350  require_token(L, P, tok);
2351  return calculate_constant2(L, P, tok);
2352 
2353  } else if (tok->type == TOK_MINUS) {
2354  require_token(L, P, tok);
2355  return -calculate_constant2(L, P, tok);
2356 
2357  } else if (tok->type == TOK_TOKEN &&
2358  (IS_LITERAL(*tok, "sizeof")
2359  || IS_LITERAL(*tok, "alignof")
2360  || IS_LITERAL(*tok, "__alignof__")
2361  || IS_LITERAL(*tok, "__alignof"))) {
2362 
2363  bool issize = IS_LITERAL(*tok, "sizeof");
2364  struct ctype type;
2365 
2366  require_token(L, P, tok);
2367  if (tok->type != TOK_OPEN_PAREN) {
2368  luaL_error(L, "invalid sizeof at line %d", P->line);
2369  }
2370 
2371  parse_type(L, P, &type);
2372  parse_argument(L, P, -1, &type, NULL, NULL);
2373  lua_pop(L, 2);
2374 
2375  require_token(L, P, tok);
2376  if (tok->type != TOK_CLOSE_PAREN) {
2377  luaL_error(L, "invalid sizeof at line %d", P->line);
2378  }
2379 
2380  next_token(L, P, tok);
2381 
2382  return issize ? ctype_size(L, &type) : type.align_mask + 1;
2383 
2384  } else {
2385  return calculate_constant1(L, P, tok);
2386  }
2387 }
2388 
2389 /* binary * / and % (left associative) */
2391 {
2393 
2394  for (;;) {
2395  if (tok->type == TOK_MULTIPLY) {
2396  require_token(L, P, tok);
2397  left *= calculate_constant2(L, P, tok);
2398 
2399  } else if (tok->type == TOK_DIVIDE) {
2400  require_token(L, P, tok);
2401  left /= calculate_constant2(L, P, tok);
2402 
2403  } else if (tok->type == TOK_MODULUS) {
2404  require_token(L, P, tok);
2405  left %= calculate_constant2(L, P, tok);
2406 
2407  } else {
2408  return left;
2409  }
2410  }
2411 }
2412 
2413 /* binary + and - (left associative) */
2415 {
2417 
2418  for (;;) {
2419  if (tok->type == TOK_PLUS) {
2420  require_token(L, P, tok);
2421  left += calculate_constant3(L, P, tok);
2422 
2423  } else if (tok->type == TOK_MINUS) {
2424  require_token(L, P, tok);
2425  left -= calculate_constant3(L, P, tok);
2426 
2427  } else {
2428  return left;
2429  }
2430  }
2431 }
2432 
2433 /* binary << and >> (left associative) */
2435 {
2437 
2438  for (;;) {
2439  if (tok->type == TOK_LEFT_SHIFT) {
2440  require_token(L, P, tok);
2441  left <<= calculate_constant4(L, P, tok);
2442 
2443  } else if (tok->type == TOK_RIGHT_SHIFT) {
2444  require_token(L, P, tok);
2445  left >>= calculate_constant4(L, P, tok);
2446 
2447  } else {
2448  return left;
2449  }
2450  }
2451 }
2452 
2453 /* binary <, <=, >, and >= (left associative) */
2455 {
2457 
2458  for (;;) {
2459  if (tok->type == TOK_LESS) {
2460  require_token(L, P, tok);
2461  left = (left < calculate_constant5(L, P, tok));
2462 
2463  } else if (tok->type == TOK_LESS_EQUAL) {
2464  require_token(L, P, tok);
2465  left = (left <= calculate_constant5(L, P, tok));
2466 
2467  } else if (tok->type == TOK_GREATER) {
2468  require_token(L, P, tok);
2469  left = (left > calculate_constant5(L, P, tok));
2470 
2471  } else if (tok->type == TOK_GREATER_EQUAL) {
2472  require_token(L, P, tok);
2473  left = (left >= calculate_constant5(L, P, tok));
2474 
2475  } else {
2476  return left;
2477  }
2478  }
2479 }
2480 
2481 /* binary ==, != (left associative) */
2483 {
2485 
2486  for (;;) {
2487  if (tok->type == TOK_EQUAL) {
2488  require_token(L, P, tok);
2489  left = (left == calculate_constant6(L, P, tok));
2490 
2491  } else if (tok->type == TOK_NOT_EQUAL) {
2492  require_token(L, P, tok);
2493  left = (left != calculate_constant6(L, P, tok));
2494 
2495  } else {
2496  return left;
2497  }
2498  }
2499 }
2500 
2501 /* binary & (left associative) */
2503 {
2505 
2506  for (;;) {
2507  if (tok->type == TOK_BITWISE_AND) {
2508  require_token(L, P, tok);
2509  left = (left & calculate_constant7(L, P, tok));
2510 
2511  } else {
2512  return left;
2513  }
2514  }
2515 }
2516 
2517 /* binary ^ (left associative) */
2519 {
2521 
2522  for (;;) {
2523  if (tok->type == TOK_BITWISE_XOR) {
2524  require_token(L, P, tok);
2525  left = (left ^ calculate_constant8(L, P, tok));
2526 
2527  } else {
2528  return left;
2529  }
2530  }
2531 }
2532 
2533 /* binary | (left associative) */
2535 {
2537 
2538  for (;;) {
2539  if (tok->type == TOK_BITWISE_OR) {
2540  require_token(L, P, tok);
2541  left = (left | calculate_constant9(L, P, tok));
2542 
2543  } else {
2544  return left;
2545  }
2546  }
2547 }
2548 
2549 /* binary && (left associative) */
2551 {
2553 
2554  for (;;) {
2555  if (tok->type == TOK_LOGICAL_AND) {
2556  require_token(L, P, tok);
2557  left = (left && calculate_constant10(L, P, tok));
2558 
2559  } else {
2560  return left;
2561  }
2562  }
2563 }
2564 
2565 /* binary || (left associative) */
2567 {
2569 
2570  for (;;) {
2571  if (tok->type == TOK_LOGICAL_OR) {
2572  require_token(L, P, tok);
2573  left = (left || calculate_constant11(L, P, tok));
2574 
2575  } else {
2576  return left;
2577  }
2578  }
2579 }
2580 
2581 /* ternary ?: (right associative) */
2583 {
2585 
2586  if (tok->type == TOK_QUESTION) {
2587  int64_t middle, right;
2588  require_token(L, P, tok);
2590  if (tok->type != TOK_COLON) {
2591  luaL_error(L, "invalid ternery (? :) in constant on line %d", P->line);
2592  }
2593  require_token(L, P, tok);
2595  return left ? middle : right;
2596 
2597  } else {
2598  return left;
2599  }
2600 }
2601 
2603 {
2604  struct token tok;
2605  int64_t ret;
2606  require_token(L, P, &tok);
2607  ret = calculate_constant13(L, P, &tok);
2608 
2609  if (tok.type != TOK_NIL) {
2610  put_back(P);
2611  }
2612 
2613  return ret;
2614 }
2615 
2616 
2617 
2618 
long __cdecl strtol(char const *_String, char **_EndPtr, int _Radix)
unsigned long __cdecl strtoul(char const *_String, char **_EndPtr, int _Radix)
#define CHAR_BIT
Definition: ChkTeX.h:91
#define type(a)
Definition: aptex-macros.h:171
#define name
middle
Definition: bibtex-3.c:951
static char mbase
Definition: bmpfont.h:25
#define ap
void set_defined(lua_State *L, int ct_usr, struct ctype *ct)
Definition: ctype.c:52
struct ctype * push_ctype(lua_State *L, int ct_usr, const struct ctype *ct)
Definition: ctype.c:86
size_t ctype_size(lua_State *L, const struct ctype *ct)
Definition: ctype.c:116
int v
Definition: dviconv.c:10
int functions_key
Definition: ffi.c:25
void set_upval(lua_State *L, int *key)
Definition: ffi.c:37
int next_unnamed_key
Definition: ffi.c:27
int types_key
Definition: ffi.c:22
void push_upval(lua_State *L, int *key)
Definition: ffi.c:31
int constants_key
Definition: ffi.c:21
int asmname_key
Definition: ffi.c:29
#define ALIGN_UP(PTR, MASK)
Definition: ffi.h:236
#define lua_absindex(L, idx)
Definition: ffi.h:82
#define DEFAULT_ALIGN_MASK
Definition: ffi.h:243
#define ALIGN_DOWN(PTR, MASK)
Definition: ffi.h:234
#define POINTER_MAX
Definition: ffi.h:316
#define ALIGNED_DEFAULT
Definition: ffi.h:251
@ STD_CALL
Definition: ffi.h:286
@ C_CALL
Definition: ffi.h:285
@ FAST_CALL
Definition: ffi.h:287
#define FUNCTION_ALIGN_MASK
Definition: ffi.h:242
#define PTR_ALIGN_MASK
Definition: ffi.h:241
#define ALIGNOF(S)
Definition: ffi.h:318
@ ENUM_TYPE
Definition: ffi.h:305
@ INT64_TYPE
Definition: ffi.h:303
@ COMPLEX_FLOAT_TYPE
Definition: ffi.h:296
@ VOID_TYPE
Definition: ffi.h:292
@ COMPLEX_LONG_DOUBLE_TYPE
Definition: ffi.h:298
@ UNION_TYPE
Definition: ffi.h:306
@ INT32_TYPE
Definition: ffi.h:302
@ BOOL_TYPE
Definition: ffi.h:299
@ INT16_TYPE
Definition: ffi.h:301
@ FUNCTION_TYPE
Definition: ffi.h:308
@ LONG_DOUBLE_TYPE
Definition: ffi.h:295
@ INTPTR_TYPE
Definition: ffi.h:304
@ FLOAT_TYPE
Definition: ffi.h:293
@ COMPLEX_DOUBLE_TYPE
Definition: ffi.h:297
@ FUNCTION_PTR_TYPE
Definition: ffi.h:309
@ DOUBLE_TYPE
Definition: ffi.h:294
@ INT8_TYPE
Definition: ffi.h:300
@ STRUCT_TYPE
Definition: ffi.h:307
static void
Definition: fpif.c:118
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
paragraph P
#define c(n)
Definition: gpos-common.c:150
#define d(n)
Definition: gpos-common.c:151
#define strchr
Definition: gsftopk.c:59
#define memcmp(s1, s2, n)
Definition: gsftopk.c:66
unsigned short CHAR
Definition: hbf.c:169
char * get_name(struct header_list **what)
Definition: header.c:149
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
long INT32
Definition: jmorecfg.h:161
short INT16
Definition: jmorecfg.h:155
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
@ right
Definition: annotate.c:15
#define INT32
Definition: gd_topal.c:107
#define INT16
Definition: gd_topal.c:99
int int double double double char double char * top
Definition: gdfx.h:19
unsigned short uint16_t
Definition: stdint.h:79
signed __int64 int64_t
Definition: stdint.h:89
unsigned int uint32_t
Definition: stdint.h:80
signed int intptr_t
Definition: stdint.h:118
signed int int32_t
Definition: stdint.h:77
unsigned char uint8_t
Definition: stdint.h:78
unsigned __int64 uint64_t
Definition: stdint.h:90
int num
Definition: disdvi.c:621
static unsigned long mt[624]
Definition: mt19937ar.c:53
#define CHAR
Definition: sfnt.h:29
signed short SHORT
Definition: sfnt.h:37
#define LONG
Definition: sfnt.h:31
#define INT
Definition: cid_basefont.h:6
static int ret
Definition: convert.c:72
char quote
Definition: exvar.h:12
double DOUBLE
Definition: types.h:28
#define SHORT
Definition: ttf.h:12
char args[100]
Definition: fixwrites.c:7
long LONG
Definition: common.h:146
int INT
Definition: common.h:144
arg_type
Definition: usprintf.c:37
#define size_t
Definition: glob.c:257
@ err
Definition: mtxline.h:24
#define align(x, k)
Definition: obcommon.h:49
static const char * types
Definition: package.cpp:76
static int sz
Definition: pdftocairo.cc:114
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
#define B(x, y)
static int size
Definition: ppmlabel.c:24
bstring c int memset(void *s, int c, int length)
#define flags
#define lua_rawlen
Definition: lua.h:363
int lua_getuservalue(lua_State *L, int idx)
Definition: lapi.c:724
void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.c:413
int lua_gettop(lua_State *L)
Definition: lapi.c:167
int lua_isstring(lua_State *L, int idx)
Definition: lapi.c:283
void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.c:466
void lua_concat(lua_State *L, int n)
Definition: lapi.c:1140
const char * lua_pushfstring(lua_State *L, const char *fmt,...)
Definition: lapi.c:519
void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.c:237
int lua_rawget(lua_State *L, int idx)
Definition: lapi.c:647
int lua_type(lua_State *L, int idx)
Definition: lapi.c:251
int lua_isnumber(lua_State *L, int idx)
Definition: lapi.c:276
void lua_pushnil(lua_State *L)
Definition: lapi.c:450
void lua_settop(lua_State *L, int idx)
Definition: lapi.c:172
const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.c:491
const char * lua_pushvfstring(lua_State *L, const char *fmt, va_list argp)
Definition: lapi.c:508
int lua_error(lua_State *L)
Definition: lapi.c:1114
int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.c:658
void lua_rawset(lua_State *L, int idx)
Definition: lapi.c:801
void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.c:817
void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.c:565
const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
Definition: lapi.c:479
int lua_next(lua_State *L, int idx)
Definition: lapi.c:1123
char * luaL_prepbuffsize(luaL_Buffer *B, size_t sz)
Definition: lauxlib.c:505
void luaL_addstring(luaL_Buffer *B, const char *s)
Definition: lauxlib.c:537
int luaL_error(lua_State *L, const char *fmt,...)
Definition: lauxlib.c:223
void luaL_pushresult(luaL_Buffer *B)
Definition: lauxlib.c:542
void luaL_checkstack(lua_State *L, int space, const char *msg)
Definition: lauxlib.c:368
void luaL_addvalue(luaL_Buffer *B)
Definition: lauxlib.c:558
void luaL_buffinit(lua_State *L, luaL_Buffer *B)
Definition: lauxlib.c:569
#define luaL_addchar(B, c)
Definition: lauxlib.h:157
#define luaL_addsize(B, s)
Definition: lauxlib.h:161
#define luaL_checkstring(L, n)
Definition: lauxlib.h:124
#define lua_replace(L, idx)
Definition: lua.h:372
#define lua_tointeger(L, i)
Definition: lua.h:341
#define lua_istable(L, n)
Definition: lua.h:352
#define lua_pushcfunction(L, f)
Definition: lua.h:349
#define lua_tonumber(L, i)
Definition: lua.h:340
#define lua_pushliteral(L, s)
Definition: lua.h:360
#define LUA_TSTRING
Definition: lua.h:67
#define lua_pcall(L, n, r, f)
Definition: lua.h:277
#define lua_remove(L, idx)
Definition: lua.h:370
#define lua_isnil(L, n)
Definition: lua.h:354
#define lua_newtable(L)
Definition: lua.h:345
#define lua_pop(L, n)
Definition: lua.h:343
#define lua_tostring(L, i)
Definition: lua.h:365
int parse_type(lua_State *L, struct parser *P, struct ctype *ct)
Definition: parser.c:1180
test
Definition: parser.c:257
@ TEST
Definition: parser.c:257
static int64_t calculate_constant5(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2434
#define IS_VOLATILE(tok)
Definition: parser.c:12
static int g_name_key
Definition: parser.c:245
static int64_t calculate_constant10(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2534
static struct ctype * parse_function(lua_State *L, struct parser *P, int ct_usr, struct ctype *ct, struct token *name, struct parser *asmname)
Definition: parser.c:1573
static int parse_struct(lua_State *L, struct parser *P, int tmp_usr, const struct ctype *ct)
Definition: parser.c:556
static int parse_root(lua_State *L, struct parser *P)
Definition: parser.c:2043
static void append_type_name(luaL_Buffer *B, int usr, const struct ctype *ct, enum name_type type)
Definition: parser.c:1274
static void check_token(lua_State *L, struct parser *P, int type, const char *str, const char *err,...)
Definition: parser.c:228
static int64_t calculate_constant3(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2390
static int try_cast(lua_State *L)
Definition: parser.c:2252
static int64_t calculate_constant6(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2454
#define END
Definition: parser.c:2040
static void push_strings(lua_State *L, struct parser *P)
Definition: parser.c:1932
static int g_front_name_key
Definition: parser.c:246
static void put_back(struct parser *P)
Definition: parser.c:239
static int from_hex(char ch)
Definition: parser.c:1921
static int add_member(lua_State *L, int ct_usr, int mname, int mbr_usr, const struct ctype *mt, int *midx)
Definition: parser.c:528
static char tok1[]
Definition: parser.c:65
static int parse_type_name(lua_State *L, struct parser *P)
Definition: parser.c:846
#define require_token(L, P, tok)
Definition: parser.c:219
static int parse_enum(lua_State *L, struct parser *P, struct ctype *type)
Definition: parser.c:262
static int calculate_struct_offsets(lua_State *L, struct parser *P, int ct_usr, struct ctype *ct, int tmp_usr)
Definition: parser.c:637
static int64_t calculate_constant13(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2582
static void find_canonical_usr(lua_State *L, int ct_usr, const struct ctype *ct)
Definition: parser.c:1753
#define IS_INLINE(tok)
Definition: parser.c:14
static int64_t string_to_int(const char *str, size_t size)
Definition: parser.c:2209
#define IS_LITERAL(TOK, STR)
Definition: parser.c:50
static int64_t calculate_constant12(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2566
static int64_t calculate_constant2(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2339
static void parse_constant_assignemnt(lua_State *L, struct parser *P, const struct ctype *type, const struct token *name)
Definition: parser.c:2010
static int64_t calculate_constant1(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2277
static int next_token(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:73
#define SHORT_TYPE(u)
static int max_bitfield_size(int type)
Definition: parser.c:1546
name_type
Definition: parser.c:1268
@ BOTH
Definition: parser.c:1269
@ FRONT
Definition: parser.c:1270
@ BACK
Definition: parser.c:1271
static Bool__ is_hex(char ch)
Definition: parser.c:1915
static void push_function_type_strings(lua_State *L, int usr, const struct ctype *ct)
Definition: parser.c:1409
#define IS_CONST(tok)
Definition: parser.c:11
static void parse_typedef(lua_State *L, struct parser *P)
Definition: parser.c:1872
etoken
Definition: parser.c:16
@ TOK_CLOSE_PAREN
Definition: parser.c:33
@ TOK_LESS_EQUAL
Definition: parser.c:28
@ TOK_RIGHT_SHIFT
Definition: parser.c:28
@ TOK_AMPERSAND
Definition: parser.c:34
@ TOK_GREATER_EQUAL
Definition: parser.c:29
@ TOK_3_BEGIN
Definition: parser.c:24
@ TOK_COLON
Definition: parser.c:32
@ TOK_LOGICAL_AND
Definition: parser.c:28
@ TOK_REFERENCE
Definition: parser.c:38
@ TOK_PLUS
Definition: parser.c:35
@ TOK_BITWISE_AND
Definition: parser.c:40
@ TOK_MULTIPLY
Definition: parser.c:39
@ TOK_LEFT_SHIFT
Definition: parser.c:28
@ TOK_GREATER
Definition: parser.c:36
@ TOK_OPEN_PAREN
Definition: parser.c:33
@ TOK_EQUAL
Definition: parser.c:29
@ TOK_NOT_EQUAL
Definition: parser.c:29
@ TOK_COMMA
Definition: parser.c:32
@ TOK_LOGICAL_NOT
Definition: parser.c:34
@ TOK_STRING
Definition: parser.c:19
@ TOK_LESS
Definition: parser.c:35
@ TOK_ASSIGN
Definition: parser.c:33
@ TOK_DOT
Definition: parser.c:34
@ TOK_BITWISE_NOT
Definition: parser.c:34
@ TOK_NIL
Definition: parser.c:17
@ TOK_DIVIDE
Definition: parser.c:35
@ TOK_CLOSE_SQUARE
Definition: parser.c:33
@ TOK_1_BEGIN
Definition: parser.c:31
@ TOK_OPEN_SQUARE
Definition: parser.c:33
@ TOK_LOGICAL_OR
Definition: parser.c:28
@ TOK_2_BEGIN
Definition: parser.c:27
@ TOK_VA_ARG
Definition: parser.c:25
@ TOK_NUMBER
Definition: parser.c:18
@ TOK_MINUS
Definition: parser.c:34
@ TOK_OPEN_CURLY
Definition: parser.c:32
@ TOK_STAR
Definition: parser.c:35
@ TOK_POUND
Definition: parser.c:36
@ TOK_MODULUS
Definition: parser.c:35
@ TOK_BITWISE_XOR
Definition: parser.c:36
@ TOK_TOKEN
Definition: parser.c:20
@ TOK_SEMICOLON
Definition: parser.c:32
@ TOK_QUESTION
Definition: parser.c:36
@ TOK_BITWISE_OR
Definition: parser.c:36
@ TOK_CLOSE_CURLY
Definition: parser.c:32
static int64_t calculate_constant9(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2518
static void require_token_line(lua_State *L, struct parser *P, struct token *tok, const char *file, int line)
Definition: parser.c:221
int64_t calculate_constant(lua_State *L, struct parser *P)
Definition: parser.c:2602
static int64_t calculate_constant11(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2550
static int parse_record(lua_State *L, struct parser *P, struct ctype *ct)
Definition: parser.c:720
static int64_t calculate_constant7(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2482
int ffi_cdef(lua_State *L)
Definition: parser.c:2189
static void parse_function_arguments(lua_State *L, struct parser *P, int ct_usr, struct ctype *ct)
Definition: parser.c:1482
static struct ctype * parse_argument2(lua_State *L, struct parser *P, int ct_usr, struct ctype *ct, struct token *name, struct parser *asmname)
Definition: parser.c:1644
#define min(a, b)
Definition: parser.c:254
static char tok2[][3]
Definition: parser.c:59
static int copy_submembers(lua_State *L, int to_usr, int from_usr, const struct ctype *ft, int *midx)
Definition: parser.c:484
void parse_argument(lua_State *L, struct parser *P, int ct_usr, struct ctype *ct, struct token *pname, struct parser *asmname)
Definition: parser.c:1842
static int parse_attribute(lua_State *L, struct parser *P, struct token *tok, struct ctype *ct, struct parser *asmname)
Definition: parser.c:994
static Bool__ is_digit(char ch)
Definition: parser.c:1918
static char tok3[][4]
Definition: parser.c:55
void push_type_name(lua_State *L, int usr, const struct ctype *ct)
Definition: parser.c:1400
static void calculate_member_position(lua_State *L, struct parser *P, struct ctype *ct, struct ctype *mt, int *pbit_offset, int *pbitfield_type)
Definition: parser.c:323
#define INT_TYPE(u)
#define IS_RESTRICT(tok)
Definition: parser.c:13
static int g_back_name_key
Definition: parser.c:247
#define PRAGMA_POP
Definition: parser.c:2041
#define LONG_TYPE(u)
static void instantiate_typedef(struct parser *P, struct ctype *tt, const struct ctype *ft)
Definition: parser.c:697
static int64_t calculate_constant4(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2414
static int64_t calculate_constant8(lua_State *L, struct parser *P, struct token *tok)
Definition: parser.c:2502
#define max(a, b)
Definition: parser.c:250
lft_cell * left
Definition: routines.h:73
#define str(s)
Definition: sh6.c:399
ShellFileEnvironment e
Definition: sh6.c:388
#define uint32_t
Definition: stdint.in.h:168
#define uint64_t
Definition: stdint.in.h:215
#define uint16_t
Definition: stdint.in.h:161
#define int64_t
Definition: stdint.in.h:194
#define uint8_t
Definition: stdint.in.h:154
Definition: usprintf.c:39
Definition: ffi.h:327
unsigned is_bitfield
Definition: ffi.h:361
unsigned variable_size_known
Definition: ffi.h:360
size_t base_size
Definition: ffi.h:328
unsigned is_variable_struct
Definition: ffi.h:359
unsigned pointers
Definition: ffi.h:348
unsigned calling_convention
Definition: ffi.h:356
size_t array_size
Definition: ffi.h:339
unsigned type
Definition: ffi.h:350
unsigned align_mask
Definition: ffi.h:347
unsigned is_array
Definition: ffi.h:352
unsigned const_mask
Definition: ffi.h:349
unsigned is_unsigned
Definition: ffi.h:365
unsigned has_var_arg
Definition: ffi.h:357
size_t offset
Definition: ffi.h:346
unsigned is_packed
Definition: ffi.h:364
unsigned bit_size
Definition: ffi.h:334
unsigned is_defined
Definition: ffi.h:353
unsigned bit_offset
Definition: ffi.h:336
unsigned has_bitfield
Definition: ffi.h:362
unsigned is_variable_array
Definition: ffi.h:358
size_t variable_increment
Definition: ffi.h:344
unsigned is_reference
Definition: ffi.h:351
Definition: filedef.h:30
Definition: bdf.c:133
Definition: ffi.h:208
const char * next
Definition: ffi.h:210
Definition: dvips.h:235
Definition: parser.c:43
size_t size
Definition: parser.c:47
const char * str
Definition: parser.c:46
int64_t integer
Definition: parser.c:45
enum etoken type
Definition: parser.c:44
Definition: object.c:319
Definition: strexpr.c:21
ch
Definition: t4ht.c:1443
*job_name strlen((char *) job_name) - 4)
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
@ L
Definition: ubidiimp.h:45
Definition: obx.h:51
@ msize
Definition: preamble.c:50
#define va_start(pvar)
Definition: varargs.h:30
char * va_list
Definition: varargs.h:22
PATTERN * pt
Definition: vlna.c:74
static const char * tok(parser_state *p)
Definition: y.tab.c:10456
#define end(cp)
Definition: zic.c:71