Fix usage help text in wayland-scanner
[profile/ivi/wayland.git] / wayland / scanner.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <ctype.h>
23 #include <expat.h>
24
25 #include "wayland-util.h"
26
27 static const char copyright[] =
28         "/*\n"
29         " * Copyright © 2010 Kristian Høgsberg\n"
30         " *\n"
31         " * Permission to use, copy, modify, distribute, and sell this software and its\n"
32         " * documentation for any purpose is hereby granted without fee, provided that\n"
33         " * the above copyright notice appear in all copies and that both that copyright\n"
34         " * notice and this permission notice appear in supporting documentation, and\n"
35         " * that the name of the copyright holders not be used in advertising or\n"
36         " * publicity pertaining to distribution of the software without specific,\n"
37         " * written prior permission.  The copyright holders make no representations\n"
38         " * about the suitability of this software for any purpose.  It is provided \"as\n"
39         " * is\" without express or implied warranty.\n"
40         " *\n"
41         " * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\n"
42         " * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO\n"
43         " * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR\n"
44         " * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\n"
45         " * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n"
46         " * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n"
47         " * OF THIS SOFTWARE.\n"
48         " */\n";
49
50 static int
51 usage(int ret)
52 {
53         fprintf(stderr, "usage: ./scanner [client-header|server-header|code]\n");
54         exit(ret);
55 }
56
57 #define XML_BUFFER_SIZE 4096
58
59 struct protocol {
60         char *name;
61         char *uppercase_name;
62         struct wl_list interface_list;
63 };
64
65 struct interface {
66         char *name;
67         char *uppercase_name;
68         int version;
69         struct wl_list request_list;
70         struct wl_list event_list;
71         struct wl_list enumeration_list;
72         struct wl_list link;
73 };
74
75 struct message {
76         char *name;
77         char *uppercase_name;
78         struct wl_list arg_list;
79         struct wl_list link;
80         int destructor;
81 };
82
83 enum arg_type {
84         NEW_ID,
85         INT,
86         UNSIGNED,
87         STRING,
88         OBJECT,
89         ARRAY,
90         FD
91 };
92
93 struct arg {
94         char *name;
95         enum arg_type type;
96         char *interface_name;
97         struct wl_list link;
98 };
99
100 struct enumeration {
101         char *name;
102         char *uppercase_name;
103         struct wl_list entry_list;
104         struct wl_list link;
105 };
106
107 struct entry {
108         char *name;
109         char *uppercase_name;
110         char *value;
111         struct wl_list link;
112 };
113
114 struct parse_context {
115         struct protocol *protocol;
116         struct interface *interface;
117         struct message *message;
118         struct enumeration *enumeration;
119 };
120
121 static char *
122 uppercase_dup(const char *src)
123 {
124         char *u;
125         int i;
126
127         u = strdup(src);
128         for (i = 0; u[i]; i++)
129                 u[i] = toupper(u[i]);
130         u[i] = '\0';
131
132         return u;
133 }
134
135 static void
136 start_element(void *data, const char *element_name, const char **atts)
137 {
138         struct parse_context *ctx = data;
139         struct interface *interface;
140         struct message *message;
141         struct arg *arg;
142         struct enumeration *enumeration;
143         struct entry *entry;
144         const char *name, *type, *interface_name, *value;
145         int i, version;
146
147         name = NULL;
148         type = NULL;
149         version = 0;
150         interface_name = NULL;
151         value = NULL;
152         for (i = 0; atts[i]; i += 2) {
153                 if (strcmp(atts[i], "name") == 0)
154                         name = atts[i + 1];
155                 if (strcmp(atts[i], "version") == 0)
156                         version = atoi(atts[i + 1]);
157                 if (strcmp(atts[i], "type") == 0)
158                         type = atts[i + 1];
159                 if (strcmp(atts[i], "value") == 0)
160                         value = atts[i + 1];
161                 if (strcmp(atts[i], "interface") == 0)
162                         interface_name = atts[i + 1];
163         }
164
165         if (strcmp(element_name, "protocol") == 0) {
166                 if (name == NULL) {
167                         fprintf(stderr, "no protocol name given\n");
168                         exit(EXIT_FAILURE);
169                 }
170
171                 ctx->protocol->name = strdup(name);
172                 ctx->protocol->uppercase_name = uppercase_dup(name);
173         } else if (strcmp(element_name, "interface") == 0) {
174                 if (name == NULL) {
175                         fprintf(stderr, "no interface name given\n");
176                         exit(EXIT_FAILURE);
177                 }
178
179                 if (version == 0) {
180                         fprintf(stderr, "no interface version given\n");
181                         exit(EXIT_FAILURE);
182                 }
183
184                 interface = malloc(sizeof *interface);
185                 interface->name = strdup(name);
186                 interface->uppercase_name = uppercase_dup(name);
187                 interface->version = version;
188                 wl_list_init(&interface->request_list);
189                 wl_list_init(&interface->event_list);
190                 wl_list_init(&interface->enumeration_list);
191                 wl_list_insert(ctx->protocol->interface_list.prev,
192                                &interface->link);
193                 ctx->interface = interface;
194         } else if (strcmp(element_name, "request") == 0 ||
195                    strcmp(element_name, "event") == 0) {
196                 if (name == NULL) {
197                         fprintf(stderr, "no request name given\n");
198                         exit(EXIT_FAILURE);
199                 }
200
201                 message = malloc(sizeof *message);
202                 message->name = strdup(name);
203                 message->uppercase_name = uppercase_dup(name);
204                 wl_list_init(&message->arg_list);
205
206                 if (strcmp(element_name, "request") == 0)
207                         wl_list_insert(ctx->interface->request_list.prev,
208                                        &message->link);
209                 else
210                         wl_list_insert(ctx->interface->event_list.prev,
211                                        &message->link);
212
213                 if (type != NULL && strcmp(type, "destructor") == 0)
214                         message->destructor = 1;
215                 else
216                         message->destructor = 0;
217
218                 ctx->message = message;
219         } else if (strcmp(element_name, "arg") == 0) {
220                 arg = malloc(sizeof *arg);
221                 arg->name = strdup(name);
222
223                 if (strcmp(type, "int") == 0)
224                         arg->type = INT;
225                 else if (strcmp(type, "uint") == 0)
226                         arg->type = UNSIGNED;
227                 else if (strcmp(type, "string") == 0)
228                         arg->type = STRING;
229                 else if (strcmp(type, "array") == 0)
230                         arg->type = ARRAY;
231                 else if (strcmp(type, "fd") == 0)
232                         arg->type = FD;
233                 else if (strcmp(type, "new_id") == 0) {
234                         if (interface_name == NULL) {
235                                 fprintf(stderr, "no interface name given\n");
236                                 exit(EXIT_FAILURE);
237                         }
238                         arg->type = NEW_ID;
239                         arg->interface_name = strdup(interface_name);
240                 } else if (strcmp(type, "object") == 0) {
241                         if (interface_name == NULL) {
242                                 fprintf(stderr, "no interface name given\n");
243                                 exit(EXIT_FAILURE);
244                         }
245                         arg->type = OBJECT;
246                         arg->interface_name = strdup(interface_name);
247                 } else {
248                         fprintf(stderr, "unknown type: %s\n", type);
249                         exit(EXIT_FAILURE);
250                 }
251
252                 wl_list_insert(ctx->message->arg_list.prev, &arg->link);
253         } else if (strcmp(element_name, "enum") == 0) {
254                 if (name == NULL) {
255                         fprintf(stderr, "no enum name given\n");
256                         exit(EXIT_FAILURE);
257                 }
258
259                 enumeration = malloc(sizeof *enumeration);
260                 enumeration->name = strdup(name);
261                 enumeration->uppercase_name = uppercase_dup(name);
262                 wl_list_init(&enumeration->entry_list);
263
264                 wl_list_insert(ctx->interface->enumeration_list.prev,
265                                &enumeration->link);
266
267                 ctx->enumeration = enumeration;
268         } else if (strcmp(element_name, "entry") == 0) {
269                 entry = malloc(sizeof *entry);
270                 entry->name = strdup(name);
271                 entry->uppercase_name = uppercase_dup(name);
272                 entry->value = strdup(value);
273                 wl_list_insert(ctx->enumeration->entry_list.prev,
274                                &entry->link);
275         }
276 }
277
278 static void
279 emit_opcodes(struct wl_list *message_list, struct interface *interface)
280 {
281         struct message *m;
282         int opcode;
283
284         if (wl_list_empty(message_list))
285                 return;
286
287         opcode = 0;
288         wl_list_for_each(m, message_list, link)
289                 printf("#define WL_%s_%s\t%d\n",
290                        interface->uppercase_name, m->uppercase_name, opcode++);
291
292         printf("\n");
293 }
294
295 static void
296 emit_type(struct arg *a)
297 {
298         switch (a->type) {
299         default:
300         case INT:
301         case FD:
302                 printf("int ");
303                 break;
304         case NEW_ID:
305         case UNSIGNED:
306                 printf("uint32_t ");
307                 break;
308         case STRING:
309                 printf("const char *");
310                 break;
311         case OBJECT:
312                 printf("struct wl_%s *", a->interface_name);
313                 break;
314         case ARRAY:
315                 printf("struct wl_array *");
316                 break;
317         }
318 }
319
320 static void
321 emit_stubs(struct wl_list *message_list, struct interface *interface)
322 {
323         struct message *m;
324         struct arg *a, *ret;
325         int has_destructor, has_destroy;
326
327         /* We provide a hand written constructor for the display object */
328         if (strcmp(interface->name, "display") != 0)
329                 printf("static inline struct wl_%s *\n"
330                        "wl_%s_create(struct wl_display *display, uint32_t id)\n"
331                        "{\n"
332                        "\treturn (struct wl_%s *)\n"
333                        "\t\twl_proxy_create_for_id(display, &wl_%s_interface, id);\n"
334                        "}\n\n",
335                        interface->name,
336                        interface->name,
337                        interface->name,
338                        interface->name);
339
340         printf("static inline void\n"
341                "wl_%s_set_user_data(struct wl_%s *%s, void *user_data)\n"
342                "{\n"
343                "\twl_proxy_set_user_data((struct wl_proxy *) %s, user_data);\n"
344                "}\n\n",
345                interface->name, interface->name, interface->name,
346                interface->name);
347
348         printf("static inline void *\n"
349                "wl_%s_get_user_data(struct wl_%s *%s)\n"
350                "{\n"
351                "\treturn wl_proxy_get_user_data((struct wl_proxy *) %s);\n"
352                "}\n\n",
353                interface->name, interface->name, interface->name,
354                interface->name);
355
356         has_destructor = 0;
357         has_destroy = 0;
358         wl_list_for_each(m, message_list, link) {
359                 if (m->destructor)
360                         has_destructor = 1;
361                 if (strcmp(m->name, "destroy)") == 0)
362                         has_destroy = 1;
363         }
364
365         if (!has_destructor && has_destroy) {
366                 fprintf(stderr,
367                         "interface %s has method named destroy but"
368                         "no destructor", interface->name);
369                 exit(EXIT_FAILURE);
370         }
371
372         /* And we have a hand-written display destructor */
373         if (!has_destructor && strcmp(interface->name, "display") != 0)
374                 printf("static inline void\n"
375                        "wl_%s_destroy(struct wl_%s *%s)\n"
376                        "{\n"
377                        "\twl_proxy_destroy("
378                        "(struct wl_proxy *) %s);\n"
379                        "}\n\n",
380                        interface->name, interface->name, interface->name,
381                        interface->name);
382
383         if (wl_list_empty(message_list))
384                 return;
385
386         wl_list_for_each(m, message_list, link) {
387                 ret = NULL;
388                 wl_list_for_each(a, &m->arg_list, link) {
389                         if (a->type == NEW_ID)
390                                 ret = a;
391                 }
392
393                 if (ret)
394                         printf("static inline struct wl_%s *\n",
395                                ret->interface_name);
396                 else
397                         printf("static inline void\n");
398
399                 printf("wl_%s_%s(struct wl_%s *%s",
400                        interface->name, m->name,
401                        interface->name, interface->name);
402
403                 wl_list_for_each(a, &m->arg_list, link) {
404                         if (a->type == NEW_ID)
405                                 continue;
406                         printf(", ");
407                         emit_type(a);
408                         printf("%s", a->name);
409                 }
410
411                 printf(")\n"
412                        "{\n");
413                 if (ret)
414                         printf("\tstruct wl_proxy *%s;\n\n"
415                                "\t%s = wl_proxy_create("
416                                "(struct wl_proxy *) %s,\n"
417                                "\t\t\t     &wl_%s_interface);\n"
418                                "\tif (!%s)\n"
419                                "\t\treturn NULL;\n\n",
420                                ret->name,
421                                ret->name,
422                                interface->name, ret->interface_name,
423                                ret->name);
424
425                 printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
426                        "\t\t\t WL_%s_%s",
427                        interface->name,
428                        interface->uppercase_name,
429                        m->uppercase_name);
430
431                 wl_list_for_each(a, &m->arg_list, link) {
432                         printf(", ");
433                                 printf("%s", a->name);
434                 }
435                 printf(");\n");
436
437                 if (m->destructor)
438                         printf("\n\twl_proxy_destroy("
439                                "(struct wl_proxy *) %s);\n",
440                                interface->name);
441
442                 if (ret)
443                         printf("\n\treturn (struct wl_%s *) %s;\n",
444                                ret->interface_name, ret->name);
445
446                 printf("}\n\n");
447         }
448 }
449
450 static const char *indent(int n)
451 {
452         const char *whitespace[] = {
453                 "\t\t\t\t\t\t\t\t\t\t\t\t",
454                 "\t\t\t\t\t\t\t\t\t\t\t\t ",
455                 "\t\t\t\t\t\t\t\t\t\t\t\t  ",
456                 "\t\t\t\t\t\t\t\t\t\t\t\t   ",
457                 "\t\t\t\t\t\t\t\t\t\t\t\t    ",
458                 "\t\t\t\t\t\t\t\t\t\t\t\t     ",
459                 "\t\t\t\t\t\t\t\t\t\t\t\t      ",
460                 "\t\t\t\t\t\t\t\t\t\t\t\t       "
461         };
462
463         return whitespace[n % 8] + 12 - n / 8;
464 }
465
466 static void
467 emit_enumerations(struct interface *interface)
468 {
469         struct enumeration *e;
470         struct entry *entry;
471
472         wl_list_for_each(e, &interface->enumeration_list, link) {
473                 printf("#ifndef WL_%s_%s_ENUM\n",
474                        interface->uppercase_name, e->uppercase_name);
475                 printf("#define WL_%s_%s_ENUM\n",
476                        interface->uppercase_name, e->uppercase_name);
477                 printf("enum wl_%s_%s {\n", interface->name, e->name);
478                 wl_list_for_each(entry, &e->entry_list, link)
479                         printf("\tWL_%s_%s_%s = %s,\n",
480                                interface->uppercase_name,
481                                e->uppercase_name,
482                                entry->uppercase_name, entry->value);
483                 printf("};\n");
484                 printf("#endif /* WL_%s_%s_ENUM */\n\n",
485                        interface->uppercase_name, e->uppercase_name);
486         }
487 }
488
489 static void
490 emit_structs(struct wl_list *message_list, struct interface *interface)
491 {
492         struct message *m;
493         struct arg *a;
494         int is_interface, n;
495
496         if (wl_list_empty(message_list))
497                 return;
498
499         is_interface = message_list == &interface->request_list;
500         printf("struct wl_%s_%s {\n", interface->name,
501                is_interface ? "interface" : "listener");
502
503         wl_list_for_each(m, message_list, link) {
504                 printf("\tvoid (*%s)(", m->name);
505
506                 n = strlen(m->name) + 17;
507                 if (is_interface) {
508                         printf("struct wl_client *client,\n"
509                                "%sstruct wl_%s *%s",
510                                indent(n),
511                                interface->name, interface->name);
512                 } else {
513                         printf("void *data,\n"),
514                         printf("%sstruct wl_%s *%s",
515                                indent(n), interface->name, interface->name);
516                 }
517
518                 wl_list_for_each(a, &m->arg_list, link) {
519                         printf(",\n%s", indent(n));
520
521                         emit_type(a);
522                         printf("%s", a->name);
523                 }
524
525                 printf(");\n");
526         }
527
528         printf("};\n\n");
529
530         if (!is_interface) {
531             printf("static inline int\n"
532                    "wl_%s_add_listener(struct wl_%s *%s,\n"
533                    "%sconst struct wl_%s_listener *listener, void *data)\n"
534                    "{\n"
535                    "\treturn wl_proxy_add_listener((struct wl_proxy *) %s,\n"
536                    "%s(void (**)(void)) listener, data);\n"
537                    "}\n\n",
538                    interface->name, interface->name, interface->name,
539                    indent(17 + strlen(interface->name)),
540                    interface->name,
541                    interface->name,
542                    indent(37));
543         }
544 }
545
546 static const char client_prototypes[] =
547         "struct wl_proxy;\n\n"
548
549         "extern void\n"
550         "wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);\n"
551
552         "extern struct wl_proxy *\n"
553         "wl_proxy_create(struct wl_proxy *factory,\n"
554         "\t\tconst struct wl_interface *interface);\n"
555
556         "extern struct wl_proxy *\n"
557         "wl_proxy_create_for_id(struct wl_display *display,\n"
558         "\t\t       const struct wl_interface *interface, uint32_t id);\n"
559
560         "extern void\n"
561         "wl_proxy_destroy(struct wl_proxy *proxy);\n\n"
562
563         "extern int\n"
564         "wl_proxy_add_listener(struct wl_proxy *proxy,\n"
565         "\t\t      void (**implementation)(void), void *data);\n\n"
566
567         "extern void\n"
568         "wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);\n\n"
569
570         "extern void *\n"
571         "wl_proxy_get_user_data(struct wl_proxy *proxy);\n\n";
572
573
574 static void
575 emit_header(struct protocol *protocol, int server)
576 {
577         struct interface *i;
578         const char *s = server ? "SERVER" : "CLIENT";
579
580         printf("%s\n\n"
581                "#ifndef %s_%s_PROTOCOL_H\n"
582                "#define %s_%s_PROTOCOL_H\n"
583                "\n"
584                "#ifdef  __cplusplus\n"
585                "extern \"C\" {\n"
586                "#endif\n"
587                "\n"
588                "#include <stdint.h>\n"
589                "#include <stddef.h>\n"
590                "#include \"wayland-util.h\"\n\n"
591                "struct wl_client;\n\n",
592                copyright,
593                protocol->uppercase_name, s,
594                protocol->uppercase_name, s);
595
596         wl_list_for_each(i, &protocol->interface_list, link)
597                 printf("struct wl_%s;\n", i->name);
598         printf("\n");
599
600         if (!server)
601                 printf(client_prototypes);
602
603         wl_list_for_each(i, &protocol->interface_list, link) {
604                 printf("extern const struct wl_interface "
605                        "wl_%s_interface;\n",
606                        i->name);
607         }
608         printf("\n");
609
610         wl_list_for_each(i, &protocol->interface_list, link) {
611
612                 emit_enumerations(i);
613
614                 if (server) {
615                         emit_structs(&i->request_list, i);
616                         emit_opcodes(&i->event_list, i);
617                 } else {
618                         emit_structs(&i->event_list, i);
619                         emit_opcodes(&i->request_list, i);
620                         emit_stubs(&i->request_list, i);
621                 }
622         }
623
624         printf("#ifdef  __cplusplus\n"
625                "}\n"
626                "#endif\n"
627                "\n"
628                "#endif\n");
629 }
630
631 static void
632 emit_messages(struct wl_list *message_list,
633               struct interface *interface, const char *suffix)
634 {
635         struct message *m;
636         struct arg *a;
637
638         if (wl_list_empty(message_list))
639                 return;
640
641         printf("static const struct wl_message "
642                "%s_%s[] = {\n",
643                interface->name, suffix);
644
645         wl_list_for_each(m, message_list, link) {
646                 printf("\t{ \"%s\", \"", m->name);
647                 wl_list_for_each(a, &m->arg_list, link) {
648                         switch (a->type) {
649                         default:
650                         case INT:
651                                 printf("i");
652                                 break;
653                         case NEW_ID:
654                                 printf("n");
655                                 break;
656                         case UNSIGNED:
657                                 printf("u");
658                                 break;
659                         case STRING:
660                                 printf("s");
661                                 break;
662                         case OBJECT:
663                                 printf("o");
664                                 break;
665                         case ARRAY:
666                                 printf("a");
667                                 break;
668                         case FD:
669                                 printf("h");
670                                 break;
671                         }
672                 }
673                 printf("\" },\n");
674         }
675
676         printf("};\n\n");
677 }
678
679 static void
680 emit_code(struct protocol *protocol)
681 {
682         struct interface *i;
683
684         printf("%s\n\n"
685                "#include <stdlib.h>\n"
686                "#include <stdint.h>\n"
687                "#include \"wayland-util.h\"\n\n",
688                copyright);
689
690         wl_list_for_each(i, &protocol->interface_list, link) {
691
692                 emit_messages(&i->request_list, i, "requests");
693                 emit_messages(&i->event_list, i, "events");
694
695                 printf("WL_EXPORT const struct wl_interface "
696                        "wl_%s_interface = {\n"
697                        "\t\"%s\", %d,\n",
698                        i->name, i->name, i->version);
699
700                 if (!wl_list_empty(&i->request_list))
701                         printf("\tARRAY_LENGTH(%s_requests), %s_requests,\n",
702                                i->name, i->name);
703                 else
704                         printf("\t0, NULL,\n");
705
706                 if (!wl_list_empty(&i->event_list))
707                         printf("\tARRAY_LENGTH(%s_events), %s_events,\n",
708                                i->name, i->name);
709                 else
710                         printf("\t0, NULL,\n");
711
712                 printf("};\n\n");
713         }
714 }
715
716 int main(int argc, char *argv[])
717 {
718         struct parse_context ctx;
719         struct protocol protocol;
720         XML_Parser parser;
721         int len;
722         void *buf;
723
724         if (argc != 2)
725                 usage(EXIT_FAILURE);
726
727         wl_list_init(&protocol.interface_list);
728         ctx.protocol = &protocol;
729
730         parser = XML_ParserCreate(NULL);
731         XML_SetUserData(parser, &ctx);
732         if (parser == NULL) {
733                 fprintf(stderr, "failed to create parser\n");
734                 exit(EXIT_FAILURE);
735         }
736
737         XML_SetElementHandler(parser, start_element, NULL);
738         do {
739                 buf = XML_GetBuffer(parser, XML_BUFFER_SIZE);
740                 len = fread(buf, 1, XML_BUFFER_SIZE, stdin);
741                 if (len < 0) {
742                         fprintf(stderr, "fread: %s\n", strerror(errno));
743                         exit(EXIT_FAILURE);
744                 }
745                 XML_ParseBuffer(parser, len, len == 0);
746
747         } while (len > 0);
748
749         XML_ParserFree(parser);
750
751         if (strcmp(argv[1], "client-header") == 0) {
752                 emit_header(&protocol, 0);
753         } else if (strcmp(argv[1], "server-header") == 0) {
754                 emit_header(&protocol, 1);
755         } else if (strcmp(argv[1], "code") == 0) {
756                 emit_code(&protocol);
757         }
758
759         return 0;
760 }