Updated footer comment
[idzebra-moved-to-github.git] / dfa / readfile.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1994-2009 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 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
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20
21 #include <stdio.h>
22 #include <assert.h>
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include <idzebra/util.h>
29 #include <dfa.h>
30 #include "lexer.h"
31
32 #define MAXLINE 512
33
34 static FILE *inf;
35 static FILE *outf;
36 static const char *inf_name;
37 static int line_no;
38 static int err_no;
39
40 static void
41     prep        (char **s),
42     read_defs   (void),
43     read_rules  (struct DFA *dfap),
44     read_tail   (void);
45
46 static char
47     *read_line  (void);
48
49 static void prep (char **s)
50 {
51     static char expr_buf[MAXLINE+1];
52     char *dst = expr_buf;
53     const char *src = *s;
54     int c;
55
56     while ((c = *src++))
57         *dst++ = c;
58
59     *dst = '\0';
60     *s = expr_buf;
61 }
62
63 static char *read_line (void)
64 {
65     static char linebuf[MAXLINE+1];
66     ++line_no;
67     return fgets (linebuf, MAXLINE, inf);
68 }
69
70 static void read_defs (void)
71 {
72     const char *s;
73     while ((s=read_line()))
74     {
75         if (*s == '%' && s[1] == '%')
76             return;
77         else if (*s == '\0' || isspace (*s))
78             fputs (s, outf);
79     }
80     error ("missing rule section");
81 }
82
83 static void read_rules (struct DFA *dfa)
84 {
85     char *s;
86     const char *sc;
87     int i;
88     int no = 0;
89
90     fputs ("\n#ifndef YY_BREAK\n#define YY_BREAK break;\n#endif\n", outf);
91     fputs ("void lexact (int no)\n{\n", outf);
92     fputs (  "\tswitch (no)\n\t{\n", outf);
93     while ((s=read_line()))
94     {
95         if (*s == '%' && s[1] == '%')
96             break;
97         else if (*s == '\0' || isspace (*s))
98             /* copy rest of line to output */
99             fputs (s, outf);
100         else
101         { 
102             /* preprocess regular expression */
103             prep (&s);                   
104             /* now parse regular expression */
105             sc = s;
106             i = dfa_parse (dfa, &sc);
107             if (i)
108             {
109                 fprintf (stderr, "%s #%d: regular expression syntax error\n",
110                         inf_name, line_no);
111                 assert (0);
112                 err_no++;
113             }
114             else
115             {
116                 if (no)
117                     fputs ("\t\tYY_BREAK\n", outf);
118                 no++;
119                 fprintf (outf, "\tcase %d:\n#line %d\n\t\t", no, line_no);
120             }
121             while (*sc == '\t' || *sc == ' ')
122                 sc++;
123             fputs (sc, outf);
124         }
125     }
126     fputs ("\tYY_BREAK\n\t}\n}\n", outf);
127     if (!no)
128         error ("no regular expressions in rule section");
129 }
130
131 static void read_tail (void)
132 {
133     const char *s;
134     while ((s=read_line()))
135         fputs (s, outf);
136 }
137
138 int read_file (const char *s, struct DFA *dfa)
139 {
140     inf_name = s;
141     if (!(inf=fopen (s,"r")))
142     {
143         error ("cannot open `%s'", s);
144         return -1;
145     }
146
147     if (!(outf=fopen ("lex.yy.c", "w")))
148     {
149         error ("cannot open `%s'", "lex.yy.c");
150         return -2;
151     }
152
153     line_no = 0;
154     err_no = 0;
155
156     read_defs ();
157     read_rules (dfa);
158     read_tail ();
159
160     fclose (outf);
161     fclose (inf);
162     return err_no;
163 }
164 /*
165  * Local variables:
166  * c-basic-offset: 4
167  * c-file-style: "Stroustrup"
168  * indent-tabs-mode: nil
169  * End:
170  * vim: shiftwidth=4 tabstop=8 expandtab
171  */
172