2 *------------------------------------------------------------------
3 * lex.c - API generator lexical analyzer
5 * Copyright (c) 1996-2009 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
29 #include "tools/vppapigen/gram.h"
30 #include <vppinfra/clib.h>
31 #include <vppinfra/fifo.h>
32 #include <vppinfra/format.h>
34 FILE *ifp, *ofp, *pythonfp, *jsonfp;
35 char *vlib_app_name = "vpp";
39 char *current_filename;
40 int current_filename_allocated;
41 unsigned long input_crc;
42 unsigned long message_crc;
44 char *push_input_fifo;
45 char saved_ungetc_char;
46 char have_ungetc_char;
49 * lexer variable definitions
52 static const char *version = "0.1";
53 static int the_lexer_linenumber = 1;
54 static enum lex_state the_lexer_state = START_STATE;
59 static void usage (char *);
60 static int name_check (const char *, YYSTYPE *);
61 static int name_compare (const char *, const char *);
63 extern YYSTYPE yylval;
65 unsigned int crc32c_table[256] = {
66 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
67 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
68 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
69 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
70 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
71 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
72 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
73 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
74 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
75 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
76 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
77 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
78 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
79 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
80 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
81 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
82 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
83 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
84 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
85 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
86 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
87 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
88 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
89 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
90 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
91 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
92 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
93 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
94 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
95 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
96 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
97 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
98 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
99 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
100 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
101 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
102 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
103 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
104 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
105 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
106 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
107 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
108 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
109 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
110 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
111 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
112 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
113 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
114 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
115 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
116 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
117 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
118 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
119 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
120 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
121 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
122 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
123 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
124 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
125 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
126 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
127 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
128 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
129 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
132 static inline unsigned long CRC8 (unsigned long crc,
135 return ((crc >> 8) ^ crc32c_table[(crc ^ d) & 0xFF]);
137 static inline unsigned long CRC16 (unsigned long crc,
140 crc = CRC8 (crc, d & 0xff);
142 crc = CRC8 (crc, d & 0xff);
148 crc_eliding_c_comments (const char *buf, unsigned long crc)
153 cSBACKSLASH, /* "...\ */
155 cCBACKSLASH, /* '...\ */
157 cSLASH_SLASH, /* //... */
158 cSLASH_STAR, /* / *... */
163 unsigned char c = *p++;
170 case cSTRING: case cSBACKSLASH:
171 case cCHAR: case cCBACKSLASH:
172 case cSLASH: case cSLASH_SLASH: case cSLASH_STAR: case cSTAR:
173 fprintf (stderr, "Inopportune EOF: %s\n", buf);
179 case cOTHER: ss = cSTRING; break; /* start string */
180 case cSTRING: ss = cOTHER; break; /* end string */
181 case cSBACKSLASH: ss = cSTRING; break;
183 case cCBACKSLASH: ss = cCHAR; break;
184 case cSLASH: crc = CRC8 (crc, '/'); ss = cOTHER; break;
185 case cSLASH_SLASH: continue; /* in comment */
186 case cSLASH_STAR: continue; /* in comment */
187 case cSTAR: ss = cSLASH_STAR; continue; /* in comment */
193 case cSTRING: ss = cSBACKSLASH; break;
194 case cSBACKSLASH: ss = cSTRING; break;
195 case cCHAR: ss = cCBACKSLASH; break;
196 case cCBACKSLASH: ss = cCHAR; break;
197 case cSLASH: crc = CRC8 (crc, '/'); ; ss = cOTHER; break;
198 case cSLASH_SLASH: continue; /* in comment */
199 case cSLASH_STAR: continue; /* in comment */
200 case cSTAR: ss = cSLASH_STAR; continue; /* in comment */
205 case cOTHER: ss = cSLASH; continue; /* potential comment */
207 case cSBACKSLASH: ss = cSTRING; break;
209 case cCBACKSLASH: ss = cCHAR; break;
210 case cSLASH: ss = cSLASH_SLASH; continue; /* start comment */
211 case cSLASH_SLASH: continue; /* in comment */
212 case cSLASH_STAR: continue; /* in comment */
213 case cSTAR: ss = cOTHER; continue; /* end of comment */
220 case cSBACKSLASH: ss = cSTRING; break;
222 case cCBACKSLASH: ss = cCHAR; break;
223 case cSLASH: ss = cSLASH_STAR; continue; /* start comment */
224 case cSLASH_SLASH: continue; /* in comment */
225 case cSLASH_STAR: ss = cSTAR; continue; /* potential end */
226 case cSTAR: continue; /* still potential end of comment */
229 case '\n': case '\r': case ' ': case '\t': case '\014':
231 case cOTHER: continue; /* ignore all whitespace */
233 case cSBACKSLASH: ss = cSTRING; break;
235 case cCBACKSLASH: ss = cCHAR; break;
236 case cSLASH: c = '/'; ss = cOTHER; break;
238 if (c == '\n' || c == '\r') ss = cOTHER; /* end comment */
240 case cSLASH_STAR: continue; /* in comment */
241 case cSTAR: ss = cSLASH_STAR; continue; /* in comment */
247 case cSBACKSLASH: ss = cSTRING; break;
249 case cCBACKSLASH: ss = cCHAR; break;
250 case cSLASH: crc = CRC8 (crc, '/'); ss = cOTHER; break;
251 case cSLASH_SLASH: continue; /* in comment */
252 case cSLASH_STAR: continue; /* in comment */
253 case cSTAR: ss = cSLASH_STAR; continue; /* in comment */
263 int main (int argc, char **argv)
271 while (curarg < argc) {
272 if (!strncmp (argv [curarg], "--verbose", 3)) {
273 fprintf (stderr, "%s version %s\n", argv [0], version);
278 if (!strncmp (argv [curarg], "--yydebug", 3)) {
284 if (!strncmp (argv [curarg], "--dump", 3)) {
290 if (!strncmp (argv[curarg], "--show-name", 3)) {
293 show_name = argv[curarg];
297 fprintf(stderr, "Missing filename after --show-name \n");
302 if (!strncmp (argv [curarg], "--input", 3)) {
305 input_filename = argv[curarg];
306 if (!strcmp (argv [curarg], "-"))
309 ifp = fopen (argv [curarg], "r");
311 fprintf (stderr, "Couldn't open input file %s\n",
317 fprintf(stderr, "Missing filename after --input\n");
322 if (!strncmp (argv [curarg], "--output", 3)) {
325 ofp = fopen (argv[curarg], "w");
327 fprintf (stderr, "Couldn't open output file %s\n",
331 ofile = argv[curarg];
334 fprintf(stderr, "Missing filename after --output\n");
339 if (!strncmp (argv [curarg], "--python", 8)) {
342 if (!strcmp(argv[curarg], "-")) {
345 pythonfp = fopen(argv[curarg], "w");
346 pythonfile = argv[curarg];
348 if (pythonfp == NULL) {
349 fprintf (stderr, "Couldn't open python output file %s\n",
355 fprintf(stderr, "Missing filename after --python\n");
360 if (!strncmp (argv [curarg], "--json", 6)) {
363 if (!strcmp(argv[curarg], "-")) {
366 jsonfp = fopen(argv[curarg], "w");
367 jsonfile = argv[curarg];
369 if (jsonfp == NULL) {
370 fprintf (stderr, "Couldn't open JSON output file %s\n",
376 fprintf(stderr, "Missing filename after --json\n");
381 if (!strncmp (argv [curarg], "--app", 4)) {
384 vlib_app_name = argv[curarg];
387 fprintf(stderr, "Missing app name after --app\n");
399 if (pythonfp == NULL) {
402 if (jsonfp == NULL) {
406 fprintf(stderr, "No input file specified...\n");
410 input_filename = show_name;
413 starttime = time (0);
415 if (yyparse() == 0) {
419 printf ("Output written to %s\n", ofile);
423 printf ("Python bindings written to %s\n", pythonfile);
427 printf ("JSON bindings written to %s\n", jsonfile);
436 printf ("Removing %s\n", ofile);
440 printf ("Removing %s\n", pythonfile);
444 printf ("Removing %s\n", jsonfile);
455 static void usage (char *progname)
458 "usage: %s --input <filename> [--output <filename>] "
459 "[--json <filename>] [--python <filename>]\n%s",
461 " [--yydebug] [--dump-tree]\n");
468 void yyerror (char *s)
470 fprintf (stderr, "%s:%d %s\n", current_filename, the_lexer_linenumber, s);
473 static char namebuf [MAXNAME];
476 getc_char (FILE *ifp)
480 if (have_ungetc_char) {
481 have_ungetc_char = 0;
482 return saved_ungetc_char;
485 if (clib_fifo_elts (push_input_fifo)) {
486 clib_fifo_sub1(push_input_fifo, rv);
489 return ((char)(getc(ifp) & 0x7f));
494 return clib_fifo_elts (fifo);
498 ungetc_char (char c, FILE *ifp)
500 saved_ungetc_char = c;
501 have_ungetc_char = 1;
504 void autoreply (void *np_arg)
507 node_t *np = (node_t *)np_arg;
510 vec_reset_length (s);
512 s = format (0, " define %s_reply\n", (char *)(np->data[0]));
513 s = format (s, "{\n");
514 s = format (s, " u32 context;\n");
515 s = format (s, " i32 retval;\n");
516 s = format (s, "};\n");
518 for (i = 0; i < vec_len (s); i++)
519 clib_fifo_add1 (push_input_fifo, s[i]);
523 * yylex (well, yylex_1: The real yylex below does crc-hackery)
525 static int yylex_1 (void)
529 enum { LP_INITIAL_WHITESPACE, LP_LINE_NUMBER,
530 LP_PRE_FILENAME_WHITESPACE, LP_FILENAME,
533 } lp_substate = LP_INITIAL_WHITESPACE;
536 switch (the_lexer_state) {
538 * START state -- looking for something interesting
547 the_lexer_linenumber++;
551 the_lexer_state = LINE_PRAGMA_STATE;
552 lp_substate = LP_INITIAL_WHITESPACE;
589 the_lexer_state = STRING_STATE;
594 the_lexer_state = HELPER_STATE;
603 the_lexer_state = CPP_COMMENT_STATE;
605 } else if (c == '*') {
606 the_lexer_state = C_COMMENT_STATE;
609 fprintf (stderr, "unknown token /%c at line %d\n",
610 c, the_lexer_linenumber);
619 /* Note fallthrough... */
622 if (isalpha (c) || c == '_') {
625 the_lexer_state = NAME_STATE;
627 } else if (isdigit(c)) {
630 the_lexer_state = NUMBER_STATE;
634 fprintf (stderr, "unknown token %c at line %d\n",
635 c, the_lexer_linenumber);
640 * NAME state -- eat the rest of a name
647 if (!isalnum (c) && c != '_') {
648 ungetc_char (c, ifp);
649 namebuf [nameidx] = 0;
650 the_lexer_state = START_STATE;
651 return (name_check (namebuf, &yylval));
653 if (nameidx >= (MAXNAME-1)) {
654 fprintf(stderr, "lex input buffer overflow...\n");
657 namebuf [nameidx++] = c;
661 * NUMBER state -- eat the rest of a number
669 ungetc_char (c, ifp);
670 namebuf [nameidx] = 0;
671 the_lexer_state = START_STATE;
672 yylval = (void *) atol(namebuf);
675 if (nameidx >= (MAXNAME-1)) {
676 fprintf(stderr, "lex input buffer overflow...\n");
679 namebuf [nameidx++] = c;
683 * C_COMMENT state -- eat a peach
685 case C_COMMENT_STATE:
694 the_lexer_state = START_STATE;
699 the_lexer_linenumber++;
703 * CPP_COMMENT state -- eat a plum
706 case CPP_COMMENT_STATE:
711 the_lexer_linenumber++;
712 the_lexer_state = START_STATE;
726 namebuf[nameidx++] = c;
730 namebuf[nameidx] = 0;
731 yylval = (YYSTYPE) sxerox (namebuf);
732 the_lexer_state = START_STATE;
737 the_lexer_linenumber++;
739 if (nameidx >= (MAXNAME-1)) {
740 fprintf(stderr, "lex input buffer overflow...\n");
743 namebuf[nameidx++] = c;
757 namebuf[nameidx] = c;
761 namebuf[nameidx] = 0;
762 yylval = (YYSTYPE) sxerox (namebuf);
763 the_lexer_state = START_STATE;
764 return (HELPER_STRING);
768 the_lexer_linenumber++;
771 * CPP makes it approximately impossible to
772 * type "#define FOO 123", so we provide a
773 * lexical trick to achieve that result
779 if (nameidx >= (MAXNAME-1)) {
780 fprintf(stderr, "lex input buffer overflow...\n");
783 namebuf[nameidx++] = c;
788 case LINE_PRAGMA_STATE:
789 /* We're only interested in lines of the form # 259 "foo.c" 17 */
791 switch (lp_substate) {
793 case LP_INITIAL_WHITESPACE: /* no number seen yet */
797 if (c >= '0' && c <= '9') {
798 namebuf[nameidx++] = c;
799 lp_substate = LP_LINE_NUMBER;
800 } else if (c == '\n') {
802 } else if (c != ' ' && c != '\t') {
805 lp_substate = LP_OTHER;
809 case LP_LINE_NUMBER: /* eating linenumber */
813 if (c >= '0' && c <= '9') {
814 namebuf[nameidx++] = c;
815 } else if (c == ' ' || c == '\t') {
816 namebuf[nameidx++] = 0;
817 the_lexer_linenumber = atol(namebuf);
818 lp_substate = LP_PRE_FILENAME_WHITESPACE;
819 } else if (c == '\n') {
822 lp_substate = LP_OTHER;
826 case LP_PRE_FILENAME_WHITESPACE: /* awaiting filename */
832 lp_substate = LP_FILENAME;
834 } else if (c == ' ' || c == '\t') {
836 } else if (c == '\n') {
839 lp_substate = LP_OTHER;
843 case LP_FILENAME: /* eating filename */
849 lp_substate = LP_POST_FILENAME;
850 namebuf[nameidx] = 0;
851 } else if (c == '\n') {
852 goto lp_end_of_line; /* syntax error... */
854 namebuf[nameidx++] = c;
858 case LP_POST_FILENAME: /* ignoring rest of line */
865 if (lp_substate == LP_POST_FILENAME) {
866 if (current_filename_allocated) {
867 current_filename_allocated = 0;
868 free(current_filename);
871 if (!strcmp(namebuf, "<stdin>")) {
872 current_filename = input_filename;
874 current_filename = sxerox(namebuf);
875 current_filename_allocated = 1;
879 the_lexer_state = START_STATE;
886 fprintf (stderr, "LEXER BUG!\n");
893 * Parse a token and side-effect input_crc
894 * in a whitespace- and comment-insensitive fashion.
899 * Accumulate a crc32-based signature while processing the
900 * input file. The goal is to come up with a magic number
901 * which changes precisely when the original input file changes
902 * but which ignores whitespace changes.
904 unsigned long crc = input_crc;
905 int node_type = yylex_1 ();
906 unsigned long crc2 = message_crc;
907 int use_helper_string = 0;
916 use_helper_string = 1;
919 /* Other node types have no "substate" */
920 /* This code is written in this curious fashion because we
921 * want the generated CRC to be independent of the particular
922 * values a particular version of lex/bison assigned to various states.
925 case RPAR: code = 258; break;
926 case LPAR: code = 259; break;
927 case SEMI: code = 260; break;
928 case LBRACK: code = 261; break;
929 case RBRACK: code = 262; break;
930 case BARF: code = 265; break;
931 case TPACKED: code = 266; break;
932 case DEFINE: code = 267; break;
933 case LCURLY: code = 268; break;
934 case RCURLY: code = 269; break;
935 case UNION: code = 271; break;
936 case COMMA: code = 273; break;
937 case NOVERSION: code = 274; break;
938 case MANUAL_PRINT: code = 275; break;
939 case MANUAL_ENDIAN: code = 276; break;
940 case TYPEONLY: code = 278; break;
941 case DONT_TRACE: code = 279; break;
942 case AUTOREPLY: code = 280; break;
943 case DOT: code = 281; break;
944 case VL_API_VERSION: code = 282; break;
946 case EOF: code = ~0; break; /* hysterical compatibility */
949 fprintf(stderr, "yylex: node_type %d missing state CRC cookie\n",
954 if (use_helper_string)
956 /* We know these types accumulated token text into namebuf */
957 /* HELPER_STRING may still contain C comments. Argh. */
958 crc = crc_eliding_c_comments (namebuf, crc);
959 crc2 = crc_eliding_c_comments (namebuf, crc2);
962 crc = CRC16 (crc, code);
963 crc2 = CRC16 (crc2, code);
972 * name_check -- see if the name we just ate
973 * matches a known keyword. If so, set yylval
974 * to a new instance of <subclass of node>, and return PARSER_MACRO
976 * Otherwise, set yylval to sxerox (s) and return NAME
979 static struct keytab {
981 enum node_subclass subclass_id;
983 /* Keep the table sorted, binary search used below! */
985 {"autoreply", NODE_AUTOREPLY},
986 {"define", NODE_DEFINE},
987 {"dont_trace", NODE_DONT_TRACE},
993 {"manual_endian", NODE_MANUAL_ENDIAN},
994 {"manual_print", NODE_MANUAL_PRINT},
995 {"noversion", NODE_NOVERSION},
996 {"packed", NODE_PACKED},
997 {"typeonly", NODE_TYPEONLY},
1002 {"union", NODE_UNION},
1003 {"uword", NODE_UWORD},
1004 {"vl_api_version", NODE_VERSION},
1007 static int name_check (const char *s, YYSTYPE *token_value)
1009 enum node_subclass subclass_id;
1013 for (top = 0, bot = (sizeof(keytab) / sizeof(struct keytab))-1;
1015 mid = (top + bot) / 2;
1016 result = name_compare (s, keytab[mid].name);
1019 else if (result > 0)
1022 subclass_id = keytab[mid].subclass_id;
1024 switch (subclass_id) {
1035 *token_value = make_node(subclass_id);
1039 *token_value = make_node(subclass_id);
1044 *token_value = make_node(subclass_id);
1047 case NODE_MANUAL_PRINT:
1048 *token_value = (YYSTYPE) NODE_FLAG_MANUAL_PRINT;
1049 return (MANUAL_PRINT);
1051 case NODE_MANUAL_ENDIAN:
1052 *token_value = (YYSTYPE) NODE_FLAG_MANUAL_ENDIAN;
1053 return (MANUAL_ENDIAN);
1056 *token_value = (YYSTYPE) NODE_FLAG_TYPEONLY;
1059 case NODE_DONT_TRACE:
1060 *token_value = (YYSTYPE) NODE_FLAG_DONT_TRACE;
1063 case NODE_AUTOREPLY:
1064 *token_value = (YYSTYPE) NODE_FLAG_AUTOREPLY;
1067 case NODE_NOVERSION:
1071 return(VL_API_VERSION);
1077 fprintf (stderr, "fatal: keytab botch!\n");
1082 *token_value = (YYSTYPE) sxerox (s);
1090 char *sxerox (const char *s)
1092 int len = strlen (s);
1095 rv = (char *) malloc (len+1);
1097 fprintf(stderr, "Out of memory...");
1109 int name_compare (const char *s1, const char *s2)
1113 while (*s1 && *s2) {