ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/config-lexer.l
(Generate patch)

Comparing hopm/trunk/src/config-lexer.l (file contents):
Revision 5198 by michael, Mon Dec 29 16:53:16 2014 UTC vs.
Revision 7742 by michael, Fri Sep 30 18:44:33 2016 UTC

# Line 1 | Line 1
1   /*
2 < * Copyright (C) 2002  Erik Fears
2 > *  Copyright (c) 2002 Erik Fears
3 > *  Copyright (c) 2014-2016 ircd-hybrid development team
4   *
5 < *    QSTRING , ccomment and hashcomment taken from Hybrid7:
6 < *    Copyright (C) 2002 by the past and present ircd coders, and others.
7 < *
8 < * This program is free software; you can redistribute it and/or
8 < * modify it under the terms of the GNU General Public License
9 < * as published by the Free Software Foundation; either version 2
10 < * of the License, or (at your option) any later version.
11 < *
12 < * This program is distributed in the hope that it will be useful,
13 < * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 < * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 < * GNU General Public License for more details.
16 < *
17 < * You should have received a copy of the GNU General Public License
18 < * along with this program; if not, write to
19 < *
20 < *       The Free Software Foundation, Inc.
21 < *       59 Temple Place - Suite 330
22 < *       Boston, MA  02111-1307, USA.
5 > *  This program is free software; you can redistribute it and/or modify
6 > *  it under the terms of the GNU 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,
11 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 + *  GNU General Public License for more details.
14   *
15 + *  You should have received a copy of the GNU General Public License
16 + *  along with this program; if not, write to the Free Software
17 + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 + *  USA
19   */
20  
21   %option case-insensitive
22   %option noyywrap
23   %option nounput
24 + %option never-interactive
25  
26   %{
27   #include <stdio.h>
# Line 34 | Line 29
29  
30   #include "compat.h"
31   #include "config.h"
32 < #include "config-parser.h"
32 > #include "config-parser.h"  /* autogenerated header file */
33 > #include "log.h"
34  
35 + #undef YY_FATAL_ERROR
36 + #define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
37  
38 < void ccomment(void);
38 > #undef YY_INPUT
39 > #define YY_INPUT(buf,result,max_size) \
40 >  if (!(result = conf_yy_input(buf, max_size))) \
41 >    YY_FATAL_ERROR("input in flex scanner failed");
42 > #define MAX_INCLUDE_DEPTH 10
43  
44 < int linenum = 1;
44 >
45 > unsigned int lineno = 1;
46   char linebuf[512];
47 + char conffilebuf[512];
48  
49 < %}
49 > static struct included_file
50 > {
51 >  YY_BUFFER_STATE state;
52 >  unsigned int lineno;
53 >  FILE *file;
54 >  char conffile[512];
55 > } include_stack[MAX_INCLUDE_DEPTH];
56  
57 < string                 \"[^\"\n]*[\"\n]
48 < comment                ("//"|"#").*
49 < whitespace             [ \t\r]*
57 > static unsigned int include_stack_ptr;
58  
51 %%
59  
60 < "/*"                    { ccomment(); }
60 > static void ccomment(void);
61 > static void conf_include(void);
62 > static int conf_eof(void);
63  
64 < {comment}               ;
64 > static int
65 > conf_yy_input(char *lbuf, unsigned int max_size)
66 > {
67 >  return fgets(lbuf, max_size, conf_file) == NULL ? 0 : strlen(lbuf);
68 > }
69 >
70 > static int
71 > conf_yy_fatal_error(const char *msg)
72 > {
73 >  return 0;
74 > }
75 > %}
76  
77 < {string}                {
78 <                           /* QSTRING from Hybrid7. Why re-invent the wheel? */
77 > WS        [[:blank:]]*
78 > DIGIT     [[:digit:]]+
79 > COMMENT   ("//"|"#").*
80 > qstring   \"[^\"\n]*[\"\n]
81 > include   \.include{WS}(\<.*\>|\".*\")
82 >
83 > %%
84 > {include}       { conf_include(); }
85 > "/*"            { ccomment(); }
86 > \n.*            { strlcpy(linebuf, yytext + 1, sizeof(linebuf)); ++lineno; yyless(1); }
87 > {WS}            ;
88 > {COMMENT}       ;
89 > {DIGIT}         { yylval.number = atoi(yytext); return NUMBER; }
90 > {qstring}       { if (yytext[yyleng - 2] == '\\')
91 >                  {
92 >                    yyless(yyleng - 1);  /* Return last quote */
93 >                    yymore();  /* Append next string */
94 >                  }
95 >                  else
96 >                  {
97 >                    yylval.string = yytext + 1;
98 >
99 >                    if (yylval.string[yyleng - 2] != '"')
100 >                      log_printf("CONFIG ->Unterminated character string");
101 >                    else
102 >                    {
103 >                      unsigned int i = 0, j = 0;
104 >
105 >                      yylval.string[yyleng - 2] = '\0';  /* Remove close quote */
106 >
107 >                      for (; yylval.string[i] != '\0'; ++i, ++j)
108 >                      {
109 >                        if (yylval.string[i] != '\\')
110 >                          yylval.string[j] = yylval.string[i];
111 >                        else
112 >                        {
113 >                          ++i;
114 >
115 >                          if (yylval.string[i] == '\0')  /* XXX: should not happen */
116 >                          {
117 >                            log_printf("CONFIG -> Unterminated character string");
118 >                            break;
119 >                          }
120  
121 <                           if(yytext[yyleng-2] == '\\')
61 <                           {
62 <                              yyless(yyleng-1); /* return last quote */
63 <                              yymore();         /* append next string */
64 <                           }
65 <                           else
66 <                           {
67 <                              yylval.string = yytext+1;
68 <                              if(yylval.string[yyleng-2] != '"') ; /* log error */
69 <                              else
70 <                              {
71 <                                 int i,j;
72 <
73 <                                 yylval.string[yyleng-2] = '\0'; /* remove close
74 <                                                                  *  quote
75 <                                                                  */
76 <
77 <                                 for (j=i=0 ;yylval.string[i] != '\0'; i++,j++)
78 <                                 {
79 <                                    if (yylval.string[i] != '\\')
80 <                                    {
81 <                                       yylval.string[j] = yylval.string[i];
82 <                                    }
83 <                                    else
84 <                                    {
85 <                                        i++;
86 <                                        yylval.string[j] = yylval.string[i];
87 <                                    }
88 <                                 }
89 <                                 yylval.string[j] = '\0';
90 <                                 return STRING;
91 <                              }
92 <                           }
93 <            
121 >                          yylval.string[j] = yylval.string[i];
122                          }
123 +                      }
124 +
125 +                      yylval.string[j] = '\0';
126 +                      return STRING;
127 +                    }
128 +                  }
129 +                }
130  
131   AWAY                    { return AWAY;         }
132   BAN_UNKNOWN             { return BAN_UNKNOWN;  }
133   BLACKLIST               { return BLACKLIST;    }
134   CHANNEL                 { return CHANNEL;      }
135 + COMMAND_INTERVAL        { return COMMAND_INTERVAL; }
136 + COMMAND_QUEUE_SIZE      { return COMMAND_QUEUE_SIZE; }
137 + COMMAND_TIMEOUT         { return COMMAND_TIMEOUT; }
138   CONNREGEX               { return CONNREGEX;    }
139   DNS_FDLIMIT             { return DNS_FDLIMIT;  }
140 + DNS_TIMEOUT             { return DNS_TIMEOUT;  }
141   DNSBL_FROM              { return DNSBL_FROM;   }
142   DNSBL_TO                { return DNSBL_TO;     }
143   EXEMPT                  { return EXEMPT;       }
# Line 112 | Line 151 | MAX_READ                { return MAX_REA
151   MODE                    { return MODE;         }
152   NAME                    { return NAME;         }
153   NEGCACHE                { return NEGCACHE;     }
154 + NEGCACHE_REBUILD        { return NEGCACHE_REBUILD; }
155   NICK                    { return NICK;         }
156   NICKSERV                { return NICKSERV;     }
157 + NOTICE                  { return NOTICE;       }
158   OPER                    { return OPER;         }
159   OPM                     { return OPM;          }
160   OPTIONS                 { return OPTIONS;      }
# Line 124 | Line 165 | PORT                    { return PORT;
165   PROTOCOL                { return PROTOCOL;     }
166   READTIMEOUT             { return READTIMEOUT;  }
167   REALNAME                { return REALNAME;     }
168 + RECONNECTINTERVAL       { return RECONNECTINTERVAL; }
169   REPLY                   { return REPLY;        }
170   SCANLOG                 { return SCANLOG;      }
171   SCANNER                 { return SCANNER;      }
# Line 176 | Line 218 | HTTPPOST                {
218                            return PROTOCOLTYPE;
219                          }
220  
221 + HTTPS                   {
222 +                          yylval.number = OPM_TYPE_HTTPS;
223 +                          return PROTOCOLTYPE;
224 +                        }
225 +
226 + HTTPSPOST               {
227 +                          yylval.number = OPM_TYPE_HTTPSPOST;
228 +                          return PROTOCOLTYPE;
229 +                        }
230 +
231   SOCKS4                  {
232                            yylval.number = OPM_TYPE_SOCKS4;
233                            return PROTOCOLTYPE;
# Line 196 | Line 248 | ROUTER                  {
248                            return PROTOCOLTYPE;
249                          }
250  
251 <
252 < [0-9]+                  {
253 <                           yylval.number=atoi(yytext);
202 <                           return NUMBER;
251 > DREAMBOX                {
252 >                          yylval.number = OPM_TYPE_DREAMBOX;
253 >                          return PROTOCOLTYPE;
254                          }
255  
256  
206
207
208
257   TRUE                     {
258                             yylval.number=1;
259                             return NUMBER;
# Line 236 | Line 284 | OFF                      {
284                             return NUMBER;
285                           }
286  
287 <
288 < \n.*                     {
241 <                           strlcpy(linebuf, yytext + 1, sizeof(linebuf));
242 <                           ++linenum;
243 <                           yyless(1);
244 <                         }
245 <
246 < {whitespace}            /* ignore whitespace */;
247 <
248 < .                       return yytext[0];
287 > .                       { return yytext[0]; }
288 > <<EOF>>                 { if (conf_eof()) yyterminate(); }
289  
290   %%
291  
292  
293   /* C-comment ignoring routine -kre*/
294 < void ccomment(void)
294 > static void
295 > ccomment(void)
296   {
297 <  int c;
297 >  int c = 0;
298  
299    /* log(L_NOTICE, "got comment"); */
300    while (1)
301    {
302 <     while ((c = input()) != '*' && c != EOF)
303 <        if (c == '\n') ++linenum;
304 <     if (c == '*')
305 <     {
306 <        while ((c = input()) == '*');
307 <        if (c == '/') break;
308 <     }
302 >    while ((c = input()) != '*' && c != EOF)
303 >      if (c == '\n')
304 >        ++lineno;
305 >
306 >    if (c == '*')
307 >    {
308 >      while ((c = input()) == '*')
309 >        /* Nothing */ ;
310 >      if (c == '/')
311 >        break;
312 >      else if (c == '\n')
313 >        ++lineno;
314 >    }
315 >
316      if (c == EOF)
317      {
318 <       YY_FATAL_ERROR("EOF in comment");
319 <       /* XXX hack alert this disables
320 <        * the stupid unused function warning
321 <        * gcc generates
322 <        */
323 <       if(1 == 0)
324 <          yy_fatal_error("EOF in comment");
325 <       break;
318 >      YY_FATAL_ERROR("EOF in comment");
319 >
320 >      /* XXX hack alert this disables
321 >       * the stupid unused function warning
322 >       * gcc generates
323 >       */
324 >      if (1 == 0)
325 >        yy_fatal_error("EOF in comment");
326 >      break;
327      }
328    }
329   }
330  
331 + static void
332 + conf_include(void)
333 + {
334 +  char *p = NULL;
335 +  char filenamebuf[512];
336 +
337 +  if ((p = strchr(yytext, '<')) == NULL)
338 +    *strchr(p = strchr(yytext, '"') + 1, '"') = '\0';
339 +  else
340 +    *strchr(++p, '>') = '\0';
341 +
342 +  /* do stacking and co. */
343 +  if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
344 +  {
345 +    log_printf("CONFIG -> Includes nested too deep in %s", p);
346 +    return;
347 +  }
348 +
349 +  if (*p == '/')  /* if it is an absolute path */
350 +    snprintf(filenamebuf, sizeof(filenamebuf), "%s", p);
351 +  else
352 +    snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", HOPM_ETCDIR, p);
353 +
354 +  FILE *tmp_fbfile_in = fopen(filenamebuf, "r");
355 +  if (!tmp_fbfile_in)
356 +  {
357 +    log_printf("CONFIG -> Unable to read configuration file '%s': %s",
358 +               filenamebuf, strerror(errno));
359 +    return;
360 +  }
361 +
362 +  struct included_file *file = &include_stack[include_stack_ptr++];
363 +  file->lineno = lineno;
364 +  file->file = conf_file;
365 +  file->state = YY_CURRENT_BUFFER;
366 +  strlcpy(file->conffile, conffilebuf, sizeof(file->conffile));
367 +
368 +  lineno = 1;
369 +  conf_file = tmp_fbfile_in;
370 +  strlcpy(conffilebuf, filenamebuf, sizeof(conffilebuf));
371 +
372 +  yy_switch_to_buffer(yy_create_buffer(NULL, YY_BUF_SIZE));
373 + }
374 +
375 + static int
376 + conf_eof(void)
377 + {
378 +  if (include_stack_ptr == 0)
379 +  {
380 +    lineno = 1;
381 +    return 1;
382 +  }
383 +
384 +  /* switch buffer */
385 +  struct included_file *file = &include_stack[--include_stack_ptr];
386 +
387 +  /* close current file */
388 +  fclose(conf_file);
389 +
390 +  /* switch buffers */
391 +  yy_delete_buffer(YY_CURRENT_BUFFER);
392 +  yy_switch_to_buffer(file->state);
393 +
394 +  /* switch lineno */
395 +  lineno = file->lineno;
396 +
397 +  /* switch file */
398 +  conf_file = file->file;
399 +
400 +  strlcpy(conffilebuf, file->conffile, sizeof(conffilebuf));
401 +  return 0;
402 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)