32 #define mp_assert(cond) arb_assert(cond)
41 #define DEBUG_PRINT(s) fputs((s), stderr)
42 #define DEBUG_PRINT_STRING(name, str) fprintf(stderr, "%s'%s'\n", name, str)
44 #define DEBUG_PRINT(s)
45 #define DEBUG_PRINT_STRING(name, str)
48 #define PRINT(s) fputs((s), stdout)
50 #define IS_CSYM(x) ((x) > 0 && (isalnum(x) || (x) == '_'))
51 #define ABORTED ((Word *) -1)
52 #define MAXPARAM 20 // max. number of parameters to a function
53 #define NEWBUFSIZ (20480*sizeof(char)) // new buffer size
88 "#line %li \"%s/%s\"\n"
89 "#error in aisc_mkpt: %s\n",
96 static void error(
const char *msg) {
101 static
void errorf(const
char *format, ...) {
107 int printed = vsprintf(buffer, format, args);
108 if (printed >= BUFFERSIZE) {
109 fputs(
"buffer overflow\n", stderr);
132 char *part = sp->
atStart ? token+1 : token;
133 char *plus = strchr(part,
'+');
142 sp->
part = strdup(part);
151 char *p = strdup(parts);
152 const char *sep =
",";
153 char *
s = strtok(p, sep);
159 s = strtok(
NULp, sep);
167 bool matches =
false;
169 while (sp && !matches) {
171 matches = strncmp(name, sp->
part, sp->
len) == 0;
174 matches = strstr(name, sp->
part);
232 w = (
Word *) malloc(
sizeof(
Word) + strlen(s) + 1);
319 if (oldw && strcmp(oldw->
string,
"unsigned")==0) {
327 strcpy(w->
string,
"double");
345 #define MAX_COMMENT_SIZE 10000
353 found__ATTR__ =
NULp;
357 while (isspace(*ptr)) ++ptr;
361 while (isalnum(*ptr) || *ptr ==
'_') ++ptr;
368 for (i = 1; from[i] && open>0; ++i) {
370 case '(': open++;
break;
371 case ')': open--;
break;
374 if (open)
return NULp;
388 bool part_is_legal() {
return (pos <= linelen) && ((pos+size) <= linelen); }
390 void set(
size_t newPos,
size_t newSize) {
400 linelen(len != -1
U ? len : strlen(line))
411 void define(
const char *
start,
const char *end) { set(start-line, end-start+1); }
416 memcpy(buffer, line+pos, size);
422 size_t behind_offset = pos+size;
424 return LinePart(line+behind_offset, linelen-behind_offset);
446 bool is_empty()
const {
return !size; }
447 size_t get_size()
const {
return size; }
449 void copyPartsTo(
char *
buffer)
const {
455 next->copyPartsTo(buffer);
463 size(first.get_size())
470 size += 1+mp->get_size();
474 char *
result = (
char *)malloc(get_size()+1);
485 const char *attrName;
492 : attrName(attrName_),
493 attrNameLen(strlen(attrName)),
494 expandName(expandName_),
495 expectParens(expectParens_)
499 void parse_one_attr(
LinePart& part)
const {
500 const char *found = strstr(part.
whole_line(), attrName);
502 const char *behind = found+attrNameLen;
506 if (*openParen ==
'(') {
508 if (closeParen) part.
define(found, closeParen);
510 part.
define(found, openParen);
511 part.
error(
"Could not find matching paren after '%s'");
515 part.
define(found, behind-1);
516 if (expectParens) part.
error(
"Expected to see '(' after '%s'");
524 parse_one_attr(from);
529 if (rest) head->
append(rest);
535 char *
parse(
const char *toParse,
size_t toParseSize)
const {
539 if (found_attributes) {
541 delete found_attributes;
548 if (!found__ATTR__) {
549 if (search__ATTR__) {
553 found__ATTR__ = ATTR_parser.
parse(last_comment, lc_size);
571 promotions = new_promotion;
575 while (last->
next) last = last->
next;
577 last->
next = new_promotion;
584 if (promotions)
fputc(
'\n', stdout);
596 if (promotions)
fputc(
'\n', stdout);
604 char *promotion_found;
607 promotion_found = strstr(last_comment, promotion_tag);
608 while (promotion_found) {
612 char *
eol = strchr(behind_promo,
'\n');
613 if (!eol) eol = strchr(behind_promo, 0);
616 while (eol>behind_promo && eol[-1] ==
' ') --
eol;
621 promotion_found =
NULp;
624 int promo_length = eol-behind_promo;
625 char *to_promote = (
char*)malloc(promo_length+1);
627 memcpy(to_promote, behind_promo, promo_length);
628 to_promote[promo_length] = 0;
633 promotion_found = strstr(eol, promotion_tag);
648 int c, lastc, incomment;
656 if (c ==
'/' && !inquote) {
659 long commentStartLine =
linenum;
669 last_comment[lc_size++] = c;
672 if (lastc ==
'*' && c ==
'/') incomment = 0;
674 error(
"EOF reached in comment");
675 errorAt(commentStartLine,
"comment started here");
692 last_comment[lc_size++] = c;
695 if (lastc !=
'\\' && c ==
'\n') incomment = 0;
696 else if (c < 0)
break;
701 if (c ==
'\n')
return c;
724 if (newline_seen && c ==
'#') {
728 }
while (c >= 0 && (c ==
'\t' || c ==
' '));
734 goto skip_rest_of_line;
737 }
while (c >= 0 && c !=
'\n' && !isdigit(c));
741 if (c >= 0 && isdigit(c)) {
744 for (
int n = 8; n >= 0; --n) {
747 if (c <= 0 || !isdigit(c))
756 while (c >= 0 && c !=
'\n')
761 newline_seen = (c ==
'\n');
763 if (c ==
'\'' || c ==
'\"') {
770 while ((c =
fnextch(f)) >= 0) {
779 if (
linenum != quoteStartLine) {
780 error(
"multiline quotes");
781 errorAt(quoteStartLine,
"quotes opened here");
784 if (inquote==
'\"' && strcmp(buffer,
"C")==0) {
792 if (index<10) buffer[index++] = c;
795 error(
"EOF in a quote");
796 errorAt(quoteStartLine,
"quote started here");
811 #if defined(DEBUG_PRINTS)
812 char *bufStart = buf;
813 #endif // DEBUG_PRINTS
816 while ((c > 0) && isspace(c)) {
826 long bracketStartLine =
linenum;
833 error(
"EOF seen in bracket loop (unbalanced brackets?)");
834 errorAt(bracketStartLine,
"bracket opened here");
841 #if defined(DEBUG_PRINTS)
842 fprintf(stderr,
"inbrack=%i (line=%li)\n", inbrack,
linenum);
843 #endif // DEBUG_PRINTS
847 #if defined(DEBUG_PRINTS)
848 fprintf(stderr,
"inbrack=%i (line=%li)\n", inbrack,
linenum);
849 #endif // DEBUG_PRINTS
893 }
while (*buf !=
';' && *buf !=
'{');
901 static const char *typewords[] = {
902 "char",
"const",
"double",
"enum",
903 "float",
"int",
"long",
"short",
904 "signed",
"struct",
"union",
"unsigned",
905 "void",
"volatile",
NULp
910 for (ss = typewords; *ss; ++ss)
911 if (strcmp(s, *ss) == 0)
922 #define IS_PARM_NAME(w) \
923 (IS_CSYM(*(w)->string) && !is_type_word((w)->string) && \
924 (!(w)->next || *(w)->next->string == ',' || \
925 *(w)->next->string == '['))
935 while (p && p->
next) {
979 if (*buf ==
')' && (--inparen < 0)) {
992 if (*buf ==
',' && inparen == 0) {
999 if (*buf ==
'(') inparen++;
1016 if (
getsym(buf, f) < 0) {
1020 if (*buf ==
',' && !inparen) {
1021 if (!sawsomething) {
1024 for (i = 0; i < np; i++) {
1025 if (!typed[i] &&
foundin(plist, pname[i])) {
1042 else if (*buf ==
';') {
1043 if (!sawsomething) {
1047 for (i = 0; i < np; i++) {
1048 if (!typed[i] &&
foundin(plist, pname[i])) {
1062 else if (strcmp(buf,
"{}") == 0)
break;
1063 else if (strcmp(buf,
"register")) {
1065 if (*buf ==
'(') inparen++;
1066 else if (*buf ==
')') inparen--;
1067 else sawsomething = 1;
1095 #if !defined(AUTO_INT)
1096 int dummy_counter = 1;
1097 char dummy_name[] =
"dummy_xx";
1098 #define DUMMY_COUNTER_POS 6
1101 for (i = 0; i < np; i++) {
1102 #if !defined(AUTO_INT)
1103 int add_dummy_name = 0;
1106 Word *pn_list = pname[i];
1108 bool is_void =
false;
1109 bool is_UNFIXED =
false;
1112 if (pn_list->
string[0]) {
1114 if (strcmp(pn_list->
string,
"void")==0) is_void =
true;
1115 if (strcmp(pn_list->
string,
"UNFIXED")==0) is_UNFIXED =
true;
1117 pn_list = pn_list->
next;
1119 if (cnt==1 && !is_void && !is_UNFIXED) {
1130 while (tlist->
next) tlist = tlist->
next;
1132 tlist->
next = pname[i];
1135 #if !defined(AUTO_INT)
1136 if (add_dummy_name) {
1145 if (i < np - 1)
addword(tlist,
",");
1157 for (
int n = 0; n<np; ++n) {
1167 if (!strchr(
"&*", w->
string[0]))
break;
1186 for (w = wlist; w; w = w->
next) {
1189 if (strcmp(w->
string,
"static") == 0) isstatic = 1;
1190 else if (strcmp(w->
string,
"main") == 0) ismain = 1;
1194 if (ismain && !use_main)
return;
1203 for (w = wlist; w; w = w->
next) {
1205 printf(
"%s,\t", w->
string);
1211 for (; w; w = w->
next) {
1212 if (w->
string[0] ==
'*') {
1217 printf(
"%s,", w->
string);
1222 printf(
"\tlink%i", refs);
1229 if (strcmp(plist->
string,
"void") != 0) {
1231 printf(
"\t@TYPE,\t@IDENT,\t@REF;\n");
1234 int unnamed_counter = 1;
1235 for (w = plist; w; w = w->
next) {
1236 if (w->
string[0] ==
'*') {
1241 if (w->
string[0] ==
',') {
1243 printf(
"\tlink%i;\n", refs);
1248 printf(
"\tterm;\n");
1253 printf(
"\t%s,", w->
string);
1259 printf(
"\tunnamed%i,", unnamed_counter++);
1261 printf(
"\tlink%i;\n", refs);
1265 printf(
"\tterm;\n");
1274 printf(
"/*%8ld */ ", startline);
1279 if (print_extern && !isstatic) {
1283 int spaceBeforeNext = 0;
1286 spaceBeforeNext = 1;
1289 for (w = wlist; w; w = w->
next) {
1290 if (spaceBeforeNext) {
1299 if (use_macro) printf(
" %s((", macro_name);
1303 spaceBeforeNext = 0;
1304 for (w = plist; w; w = w->
next) {
1307 const char *token = w->
string;
1308 char tokStart = token[0];
1310 if (!tokStart)
continue;
1312 if (tokStart ==
',') spaceBeforeNext = 1;
1313 else if (strchr(
"[])", tokStart)) spaceBeforeNext = 0;
1315 int nextSpaceBeforeNext;
1316 if (strchr(
"&*", tokStart)) {
1317 if (spaceBeforeNext) {
1319 if (lastPtrRef->
string[0] ==
'&') spaceBeforeNext = 0;
1321 nextSpaceBeforeNext = tokStart ==
'&';
1324 nextSpaceBeforeNext =
IS_CSYM(tokStart);;
1326 if (spaceBeforeNext) {
1330 spaceBeforeNext = nextSpaceBeforeNext;
1332 fputs(token, stdout);
1336 if (use_macro)
PRINT(
"))");
1340 if (found__ATTR__) {
PRINT(
" ");
PRINT(found__ATTR__); }
1345 static void getdecl(FILE *f,
const char *header) {
1353 int header_printed = 0;
1355 current_file = strdup(header);
1363 bool seen__ATTR =
false;
1371 if (
getsym(buf, f) < 0) {
1381 if (strcmp(buf,
",")==0 ||
1382 strcmp(buf,
"=")==0 ||
1383 strcmp(buf,
"typedef")==0 ||
1384 strcmp(buf,
"[")==0)
1390 if (strcmp(buf,
"{}")==0) {
1391 if (!extern_c_seen)
skipit(buf, f);
1395 if (strcmp(buf,
"extern")==0) {
1405 if (strcmp(buf,
"$") == 0) {
1407 if (promote_extern_c) {
1419 if (strncmp(buf,
"__ATTR__", 8) == 0) {
1427 if (strcmp(buf,
"static") == 0 ||
1428 strcmp(buf,
"inline") == 0 ||
1429 strcmp(buf,
"CONSTEXPR_INLINE") == 0)
1435 if (strcmp(buf,
";") == 0)
goto again;
1438 if (strcmp(buf,
"(")==0) {
1453 for (w=wlist; w->
next && oktoprint; w=w->
next) {
1454 if (w->
string[0]==
':' && w->
string[1]==0) oktoprint = 0;
1462 if (seen__ATTR && oktoprint) {
1463 DEBUG_PRINT(
"attempt to emit seen__ATTR (suppressed)");
1468 if (!header_printed) {
1469 if (aisc) printf(
"\n# %s\n", header);
1470 else printf(
"\n/* %s */\n", header);
1473 emit(wlist, plist, startline);
1491 "\naisc_mkpts - ARB prototype generator"
1492 "\nUsage: %s [options] [files ...]", ourname);
1493 fputs(
"\nSupported options:"
1494 "\n -F part[,part]* only promote declarations for functionnames containing one of the parts"
1495 "\n if 'part' starts with a '^' functionname has to start with rest of part"
1496 "\n -S (like -F) do NOT promote matching declarations (defaults to -S '^TEST_,^NOTEST_')"
1498 "\n Instead of ',' (=or) you may use '+' (=and)"
1500 "\n -G search for ARB macro __ATTR__ in comment behind function header"
1501 "\n -P promote /*AISC_MKPT_PROMOTE:forHeader*/ to header"
1503 "\n -w gen.h add standard include wrapper (needs name of generated header)"
1504 "\n -c \"text\" add text as comment into header"
1506 "\n -C insert 'extern \"C\"'"
1507 "\n -E prefix 'extern \"C\"' at prototype"
1509 "\n -W don't promote types in old style declarations"
1510 "\n -x omit parameter names in prototypes"
1512 "\n -K use K&R prototype macro (default assumes header files are strict ANSI)"
1513 "\n -D define K&R prototype macro"
1514 "\n -p sym use \"sym\" as the prototype macro (default \"P_\")"
1516 "\n -m promote declaration of 'main()' (default is to skip it)"
1517 "\n -a make a function list for aisc_includes (default: generate C prototypes)"
1518 "\n -e put an explicit \"extern\" keyword in declarations"
1519 "\n -n put line numbers of declarations as comments"
1521 "\n -V print version number"
1522 "\n -h print this help"
1525 if (msg) fprintf(stderr,
"\nError: %s", msg);
1526 fputc(
'\n', stderr);
1531 return strcmp(*(
const char **)v0, *(
const char **)v1);
1536 sprintf(buffer,
"option -%c expects an argument", option);
1541 sprintf(buffer,
"unknown option -%c", option);
1546 bool exit_if_noargs =
false;
1548 if (argv[0] && argv[0][0]) {
1549 ourname = strrchr(argv[0],
'/');
1550 if (!ourname) ourname = argv[0];
1552 else ourname =
"mkptypes";
1558 char *iobuf = (
char *)malloc(
NEWBUFSIZ);
1559 while (*argv && **argv ==
'-') {
1560 const char *t = *argv++; --argc; t++;
1562 if (*t ==
'e') print_extern = 1;
1563 else if (*t ==
'C') cansibycplus = 1;
1564 else if (*t ==
'E') promote_extern_c = 1;
1565 else if (*t ==
'W') dont_promote = 1;
1566 else if (*t ==
'a') aisc = 1;
1567 else if (*t ==
'G') search__ATTR__ = 1;
1568 else if (*t ==
'n') donum = 1;
1569 else if (*t ==
'x') no_parm_names = 1;
1570 else if (*t ==
'D') define_macro = 1;
1571 else if (*t ==
'K') use_macro = 1;
1572 else if (*t ==
'P') promote_lines = 1;
1573 else if (*t ==
'm') use_main = 1;
1574 else if (*t ==
'p') {
1575 t = *argv++; --argc;
1581 else if (*t ==
'c') {
1582 t = *argv++; --argc;
1587 else if (*t ==
'w') {
1588 t = *argv++; --argc;
1590 include_wrapper = t;
1593 else if (*t ==
'F') {
1594 t = *argv++; --argc;
1599 else if (*t ==
'S') {
1600 t = *argv++; --argc;
1606 else if (*t ==
'V') {
1607 exit_if_noargs =
true;
1610 else if (*t ==
'h')
Usage();
1616 if (argc == 0 && exit_if_noargs) {
1620 char *include_macro =
NULp;
1622 if (header_comment) {
1623 printf(
"# %s\n#\n", header_comment);
1625 fputs(
"# This file is generated by aisc_mkpt.\n"
1626 "# Any changes you make here will be overwritten later!\n"
1628 "@FUNCTION_TYPE, @FUNCTION, @FUNCTION_REF;", stdout);
1631 fputs(
"/*", stdout);
1632 if (header_comment) printf(
" %s.\n *\n *", header_comment);
1633 fputs(
" This file is generated by aisc_mkpt.\n"
1634 " * Any changes you make here will be overwritten later!\n"
1639 if (include_wrapper) {
1641 include_macro = strdup(include_wrapper);
1642 for (p = 0; include_macro[p]; p++) {
1643 char c = include_macro[p];
1644 c = strchr(
".-", c) ?
'_' : toupper(c);
1645 include_macro[p] = c;
1648 printf(
"#ifndef %s\n"
1659 "# if defined(__STDC__) || defined(__cplusplus)\n"
1660 "# define %s(s) s\n"
1662 "# define %s(s) ()\n"
1665 "# error %s already defined elsewhere\n"
1667 macro_name, macro_name, macro_name, macro_name);
1672 "# error %s is not defined\n"
1674 macro_name, macro_name);
1677 if (search__ATTR__) {
1678 fputs(
"/* define ARB attributes: */\n"
1679 "#ifndef ATTRIBUTES_H\n"
1680 "# include <attributes.h>\n"
1681 "#endif\n\n", stdout);
1684 fputs(
"#ifdef __cplusplus\n"
1686 "#endif\n\n", stdout);
1690 current_dir = getcwd(
NULp, 255);
1692 getdecl(stdin,
"<from stdin>");
1695 const char *filename[1000];
1698 while (argc > 0 && *argv) {
1699 filename[fcount++] = *argv;
1705 for (
int i = 0; i<fcount; ++i) {
1710 FILE *f = fopen(filename[i],
"r");
1712 perror(filename[i]);
1715 if (iobuf) setvbuf(f, iobuf, _IOFBF,
NEWBUFSIZ);
1724 current_file =
NULp;
1731 fputs(
"\n#ifdef __cplusplus\n"
1733 "#endif\n", stdout);
1735 if (use_macro && define_macro) {
1736 printf(
"\n#undef %s\n", macro_name);
1739 if (include_wrapper) {
1742 "#error %s included twice\n"
1743 "#endif /* %s */\n",
1749 free(include_macro);
1763 fprintf(stderr,
"%s 1.1 ARB\n", ourname);
1772 inline const char *test_extract(
const char *
str) {
1773 search__ATTR__ =
true;
1777 strcpy(last_comment, str);
1778 lc_size = strlen(last_comment);
1785 #define TEST_ATTR_____(comment,extracted) TEST_EXPECT_EQUAL(test_extract(comment), extracted)
1787 void TEST_attribute_parser() {
1788 TEST_ATTR_____(
"", (
const char*)
NULp);
1789 TEST_ATTR_____(
"nothing here", (
const char*)
NULp);
1791 TEST_ATTR_____(
"bla bla __ATTR__DEPRECATED(\" my reason \") more content",
"__ATTR__DEPRECATED(\" my reason \")");
1792 TEST_ATTR_____(
"bla bla __ATTR__FORMAT(pos) more content",
"__ATTR__FORMAT(pos)");
1794 TEST_ATTR_____(
"__ATTR__DEPRECATED",
"__ATTR__DEPRECATED");
1795 TEST_ATTR_____(
"__ATTR__FORMAT(pos)",
"__ATTR__FORMAT(pos)");
1796 TEST_ATTR_____(
"bla __ATTR__FORMAT(pos)",
"__ATTR__FORMAT(pos)");
1797 TEST_ATTR_____(
"__ATTR__FORMAT(pos) bla",
"__ATTR__FORMAT(pos)");
1798 TEST_ATTR_____(
" __ATTR__FORMAT(pos) ",
"__ATTR__FORMAT(pos)");
1800 TEST_ATTR_____(
"__ATTR__FORMAT((pos)", (
const char*)
NULp);
1801 TEST_ATTR_____(
"__attribute__(pos", (
const char*)
NULp);
1802 TEST_ATTR_____(
"__ATTR__FORMAT(pos))",
"__ATTR__FORMAT(pos)");
1803 TEST_ATTR_____(
"__ATTR__FORMAT((pos))",
"__ATTR__FORMAT((pos))");
1804 TEST_ATTR_____(
"__ATTR__FORMAT((pos)+((sop)))",
"__ATTR__FORMAT((pos)+((sop)))");
1805 TEST_ATTR_____(
"__ATTR__FORMAT(((pos)))+(sop))",
"__ATTR__FORMAT(((pos)))");
1807 TEST_ATTR_____(
"bla bla __ATTR__DEPRECATED __ATTR__FORMAT(pos) more content",
"__ATTR__DEPRECATED __ATTR__FORMAT(pos)");
1808 TEST_ATTR_____(
"bla __ATTR__DEPRECATED bla more__ATTR__FORMAT(pos)content",
"__ATTR__DEPRECATED __ATTR__FORMAT(pos)");
1810 TEST_ATTR_____(
" goes to header: __ATTR__NORETURN */",
"__ATTR__NORETURN");
1816 #endif // UNIT_TESTS
static int List_len(Word *w)
static int string_comparator(const void *v0, const void *v1)
void define(const char *start, const char *end)
static void addword(Word *w, const char *s)
AliDataPtr format(AliDataPtr data, const size_t wanted_len, GB_ERROR &error)
static char * current_file
AttributeParser(const char *attrName_, bool expandName_, bool expectParens_)
static void addSymParts(SymPart *&symParts, const char *parts)
static SymPart * requiredSymParts
static char * found__ATTR__
static SymPart * makeSymPart(char *token)
static int foundin(Word *w1, Word *w2)
static void search_comment_for_promotion()
static void emit(Word *wlist, Word *plist, long startline)
static int skipit(char *buf, FILE *f)
static int getsym(char *buf, FILE *f)
static SymPart * excludedSymParts
static Word * word_append(Word *w1, Word *w2)
void addExcludedSymParts(const char *parts)
static __ATTR__NORETURN void UnknownOption(char option)
bool wantPrototypeFor(const char *name)
Word * getLastPtrRef(Word *w)
char buffer[MESSAGE_BUFFERSIZE]
static void getdecl(FILE *f, const char *header)
void freeRequiredSymParts()
static HelixNrInfo * start
#define TEST_PUBLISH(testfunction)
static void add_promotion(char *to_promote)
static int search__ATTR__
const char * matchingParen(const char *from)
static const char * header_comment
void freeExcludedSymParts()
static Word * word_alloc(const char *s)
static char last_comment[MAX_COMMENT_SIZE]
static const char * include_wrapper
static Word * typelist(Word *p)
#define DEBUG_PRINT_STRING(name, str)
static char const * macro_name
static void print_promotions()
static char * current_dir
static void error(const char *msg)
bool hasRequiredSymPart(const char *name)
static int is_type_word(char *s)
bool hasExcludedSymPart(const char *name)
static __ATTR__NORETURN void Usage(const char *msg=NULp)
static const char * nextNonWord(const char *ptr)
PartQueue(LinePart first_)
static Word * getparamlist(FILE *f)
void error(const char *format)
static void freeSymParts(SymPart *&symParts)
int ARB_main(int argc, char *argv[])
static const char * nextNonSpace(const char *ptr)
static int promotion_tag_len
static void typefixhack(Word *w)
fputs(TRACE_PREFIX, stderr)
static void errorf(const char *format,...) __attribute__((format(__printf__
LinePart(const char *wholeLine, size_t len=-1U)
static void word_free(Word *&word)
static const char * promotion_tag
#define DUMMY_COUNTER_POS
char * parse(const char *toParse, size_t toParseSize) const
static char const * ourname
static int fnextch(FILE *f)
void copyTo(char *buffer) const
static int ngetc(FILE *f)
const char * whole_line() const
static promotion * promotions
static void clear_found_attribute()
void append(PartQueue *mp)
static bool matchesSymPart(const SymPart *symParts, const char *name)
static void errorAt(long line, const char *msg)
static void search_comment_for_attribute()
void addRequiredSymParts(const char *parts)
static __ATTR__NORETURN void MissingArgumentFor(char option)
static int nextch(FILE *f)
struct PT_short_chain_header __attribute__
static int promote_extern_c
GB_write_int const char s