Tue Aug 17 15:27:33 2004 Jonathan Blandford <jrb@redhat.com>
[jelmer/krb5-auth-dialog.git] / etpo / lexer.l
1 %{
2 /*
3  * Copyright (C) 2004 Red Hat, Inc.
4  *
5  * This is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Library General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 #include "config.h"
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23 #include <ftw.h>
24 #include <getopt.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <glib.h>
30 #include "grammar.h"
31 %}
32 %x QUOTED
33 %%
34 error_table|et          { yylval.sval = g_strdup(yytext);
35                           return ERROR_TABLE_START; };
36 end                     { return ERROR_TABLE_END; };
37 error_code|ec           { yylval.sval = g_strdup(yytext);
38                           return ERROR_CODE_START; };
39 ,                       { return COMMA; };
40 \\\n                    { };
41 <INITIAL>[\r\n]         { };
42 <INITIAL>[A-Za-z0-9_-]+ { yylval.sval = g_strdup(yytext);
43                           return TOKEN; };
44 <INITIAL>[ \t]          { };
45 <INITIAL>\"             { BEGIN(QUOTED);
46                           yylval.sval = g_strdup("");
47                           return QUOTE; };
48 <QUOTED>\"              { BEGIN(INITIAL);
49                           return QUOTE; };
50 <QUOTED>[^\"]+          { yylval.sval = g_strdup(yytext);
51                           return LITERAL; };
52 <QUOTED>\n              { yylval.sval = g_strdup(yytext);
53                           return LITERAL; };
54 <*>^#.*$                { };
55 %%
56
57 /* Complete list of filenames, an iterator for that list, and the contents of
58  * the current item. */
59 static GList *filenames = NULL, *filename = NULL;
60 const char *currentfile = NULL;
61
62 int
63 yyerror(void)
64 {
65         g_print("Syntax error (%s).\n", currentfile);
66         exit(1);
67 }
68
69 /* Callback for ftw().  Adds the filename being examined to the global list of
70  * filenames. */
71 static int
72 fn(const char *file, const struct stat *st, int flag)
73 {
74         int i;
75         if (flag == FTW_F) {
76                 i = strlen(file);
77                 if ((i > 3) &&
78                     (strncmp(file + strlen(file) - 3, ".et", 3) == 0)) {
79                         filenames = g_list_append(filenames, g_strdup(file));
80                 }
81         }
82         return 0;
83 }
84
85 /* Open the next filename in the list of files, if we have a list and we
86  * haven't reached its end. */
87 int
88 yywrap(void)
89 {
90         if ((filename != NULL) && (g_list_next(filename) != NULL)) {
91                 fclose(yyin);
92                 filename = g_list_next(filename);
93                 currentfile = filename->data;
94                 yyin = fopen(currentfile, "r");
95                 return 0;
96         }
97         return 1;
98 }
99
100 /* Spew forth a gettext .pot header. */
101 static void
102 header(void)
103 {
104         const char *boilerplate = "const char *dummy = {\n";
105         printf(boilerplate);
106 }
107
108 static void
109 tail(void)
110 {
111         const char *boilerplate = "};\n";
112         printf(boilerplate);
113 }
114
115 int
116 main(int argc, char **argv)
117 {
118         int i;
119         /* Call getopt.  We don't provide any options just now, but this lets
120          * us handle "--help" and "-h" queries simply. */
121         while ((i = getopt(argc, argv, "")) != -1) {
122                 switch (i) {
123                 default:
124                         printf("Usage: etpo [directory ...]\n");
125                         return 2;
126                         break;
127                 }
128         }
129         /* Assume that each non-option argument is a directory. */
130         for (i = optind; i < argc; i++) {
131                 if (ftw(argv[i], fn, 10) != 0) {
132                         perror("ftw");
133                         return 1;
134                 }
135         }
136         /* Spew out a header. */
137         header();
138         if (g_list_length(filenames) > 0) {
139                 /* Open the first file and start parsing it. */
140                 filename = filenames;
141                 currentfile = filename->data;
142                 yyin = fopen(currentfile, "r");
143                 yyparse();
144                 fclose(yyin);
145         } else {
146                 /* Start parsing stdin. */
147                 currentfile = "<stdin>";
148                 yyin = stdin;
149         }
150         tail();
151         return 0;
152 }