modules/rpsl/syntax.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. syntax_init
  2. yywrap
  3. yyerror
  4. syntax_error
  5. yy_input
  6. syntax_check_by_offset
  7. syntax_check_by_name
  8. main

   1 /******************
   2   Copyright (c) 2002                                        RIPE NCC
   3 
   4   All Rights Reserved
   5 
   6   Permission to use, copy, modify, and distribute this software and its
   7   documentation for any purpose and without fee is hereby granted,
   8   provided that the above copyright notice appear in all copies and that
   9   both that copyright notice and this permission notice appear in
  10   supporting documentation, and that the name of the author not be
  11   used in advertising or publicity pertaining to distribution of the
  12   software without specific, written prior permission.
  13 
  14   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  16   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  17   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  18   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  19   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20   ***************************************/
  21 
  22 /* could use per-lexer locks for speed, but it's probably unnecessary */
  23 
  24 #include <string.h>
  25 #include <sys/types.h>
  26 #include <regex.h>
  27 #include <stdlib.h>
  28 #include <pthread.h>
  29 #include <stdarg.h>
  30 #include <stdio.h>
  31 #include <glib.h>
  32 #include <assert.h>
  33 #include "syntax.h"
  34 #include "syntax_tab.h"
  35 
  36 #define SYNTAX_TAB_LEN (sizeof(syntax_tab)/sizeof(syntax_tab[0]))
  37 
  38 static void
  39 syntax_init()
     /* [<][>][^][v][top][bottom][index][help] */
  40 {
  41     int i;
  42     int regcomp_ret;
  43 
  44     for (i=0; i<SYNTAX_TAB_LEN; i++) {
  45         if (syntax_tab[i].core_regex_pattern != NULL) {
  46             syntax_tab[i].core_regex = g_new(regex_t, 1);
  47             regcomp_ret = regcomp(syntax_tab[i].core_regex,
  48                                   syntax_tab[i].core_regex_pattern,
  49                                   REG_EXTENDED | REG_ICASE | REG_NOSUB);
  50             assert(regcomp_ret == 0);
  51         }
  52         if (syntax_tab[i].core_reserved_regex_pattern != NULL) {
  53             syntax_tab[i].core_reserved_regex = g_new(regex_t, 1);
  54             regcomp_ret = regcomp(syntax_tab[i].core_reserved_regex,
  55                                   syntax_tab[i].core_reserved_regex_pattern,
  56                                   REG_EXTENDED | REG_ICASE | REG_NOSUB);
  57             assert(regcomp_ret == 0);
  58         }
  59         if (syntax_tab[i].front_end_regex_pattern != NULL) {
  60             syntax_tab[i].front_end_regex = g_new(regex_t, 1);
  61             regcomp_ret = regcomp(syntax_tab[i].front_end_regex,
  62                                   syntax_tab[i].front_end_regex_pattern,
  63                                   REG_EXTENDED | REG_ICASE | REG_NOSUB);
  64             assert(regcomp_ret == 0);
  65         }
  66         if (syntax_tab[i].front_end_reserved_regex_pattern != NULL) {
  67             syntax_tab[i].front_end_reserved_regex = g_new(regex_t, 1);
  68             regcomp_ret = regcomp(syntax_tab[i].front_end_reserved_regex,
  69                                  syntax_tab[i].front_end_reserved_regex_pattern,
  70                                  REG_EXTENDED | REG_ICASE | REG_NOSUB);
  71             assert(regcomp_ret == 0);
  72         }
  73     }
  74 }
  75 
  76 int 
  77 yywrap()
     /* [<][>][^][v][top][bottom][index][help] */
  78 {
  79     return 1;
  80 }
  81 
  82 /* array of errors (initialize before parsing) */
  83 GPtrArray *parse_errors;
  84 
  85 /* parse error */
  86 void
  87 yyerror(const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
  88 {
  89     gchar *copy;
  90 
  91     copy = g_strdup(s);
  92     g_ptr_array_add(parse_errors, copy);
  93 }
  94 
  95 /* syntax error (formatted parse error) */
  96 void
  97 syntax_error(const char *fmt, ...)
     /* [<][>][^][v][top][bottom][index][help] */
  98 {
  99     va_list args;
 100     guint len;
 101     gchar *buf;
 102 
 103     va_start(args, fmt);
 104     len = g_printf_string_upper_bound(fmt, args);
 105     buf = g_new(char, len+1);
 106     vsnprintf(buf, len+1, fmt, args);
 107     va_end(args);
 108     yyerror(buf);
 109     g_free(buf);
 110 }
 111 
 112 /* taken from _lex & yacc_ p.157, by Levine, Mason, & Brown (corrected) */
 113 static const char *syntax_inputptr;
 114 static const char *syntax_inputlim;
 115 
 116 #undef min
 117 #define min(a, b)  (((a) < (b)) ? (a) : (b))
 118 
 119 void
 120 yy_input (char *buf, int *result, int max_size)
     /* [<][>][^][v][top][bottom][index][help] */
 121 {
 122     int n = min(max_size, syntax_inputlim - syntax_inputptr);
 123 
 124     if (n > 0) {
 125         memcpy(buf, syntax_inputptr, n);
 126         syntax_inputptr += n;
 127     }
 128     *result = n;
 129 }
 130 
 131 static pthread_once_t init_control = PTHREAD_ONCE_INIT;
 132 
 133 /* returns an array of strings with error descriptions (may be empty) */
 134 GPtrArray *
 135 syntax_check_by_offset (int offset, syntax_check_t type, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 138     GPtrArray *errors;
 139     GString *tmp;
 140 
 141     pthread_once(&init_control, syntax_init);
 142 
 143     errors = g_ptr_array_new();
 144     tmp = g_string_new("");
 145 
 146     if (type == SYNTAX_CHECK_CORE) {
 147         if (syntax_tab[offset].core_regex_pattern != NULL) {
 148             if (regexec(syntax_tab[offset].core_regex, s, 0, NULL, 0) != 0) {
 149                 g_string_sprintf(tmp, "Syntax error in \"%s\"", s);
 150                 g_ptr_array_add(errors, g_strdup(tmp->str));
 151                 goto syntax_check_by_offset_exit;
 152             }
 153         }
 154         if (syntax_tab[offset].core_reserved_regex_pattern != NULL) {
 155             if (regexec(syntax_tab[offset].core_reserved_regex, s, 
 156                         0, NULL, 0) == 0) 
 157             {
 158                 g_string_sprintf(tmp, "\"%s\" is a reserved word", s);
 159                 g_ptr_array_add(errors, g_strdup(tmp->str));
 160                 goto syntax_check_by_offset_exit;
 161             }
 162         }
 163         if (syntax_tab[offset].core_parser != NULL) {
 164             pthread_mutex_lock(&mutex);
 165             (syntax_tab[offset].core_parser_reset)();
 166             syntax_inputptr = s;
 167             syntax_inputlim = s + strlen(s);
 168             parse_errors = errors;
 169             (syntax_tab[offset].core_parser)();
 170             pthread_mutex_unlock(&mutex);
 171             if (errors->len > 0) {
 172                 goto syntax_check_by_offset_exit;
 173             } 
 174         }
 175     } else {
 176         if (syntax_tab[offset].front_end_regex_pattern != NULL) {
 177             if (regexec(syntax_tab[offset].front_end_regex, s, 0, NULL, 0)!=0) {
 178                 g_string_sprintf(tmp, "Syntax error in \"%s\"", s);
 179                 g_ptr_array_add(errors, g_strdup(tmp->str));
 180                 goto syntax_check_by_offset_exit;
 181             }
 182         }
 183         if (syntax_tab[offset].front_end_reserved_regex_pattern != NULL) {
 184             if (regexec(syntax_tab[offset].front_end_reserved_regex, s, 
 185                         0, NULL, 0) == 0) 
 186             {
 187                 g_string_sprintf(tmp, "\"%s\" is a reserved word", s);
 188                 g_ptr_array_add(errors, g_strdup(tmp->str));
 189                 goto syntax_check_by_offset_exit;
 190             }
 191         }
 192         if (syntax_tab[offset].front_end_parser != NULL) {
 193             pthread_mutex_lock(&mutex);
 194             (syntax_tab[offset].front_end_parser_reset)();
 195             syntax_inputptr = s;
 196             syntax_inputlim = s + strlen(s);
 197             parse_errors = errors;
 198             (syntax_tab[offset].front_end_parser)();
 199             pthread_mutex_unlock(&mutex);
 200             if (errors->len > 0) {
 201                 goto syntax_check_by_offset_exit;
 202             } 
 203         }
 204     }
 205 
 206 syntax_check_by_offset_exit:
 207     g_string_free(tmp, TRUE);
 208     return errors;
 209 }
 210 
 211 GPtrArray *
 212 syntax_check_by_name (const char *name, syntax_check_t type, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214     int i;
 215     GPtrArray *errors;
 216 
 217     for (i=0; i<SYNTAX_TAB_LEN; i++) {
 218         if (strcasecmp(syntax_tab[i].name, name) == 0) {
 219             return syntax_check_by_offset(i, type, s);
 220         }
 221     }
 222     errors = g_ptr_array_new();
 223     g_ptr_array_add(errors, 
 224                     "Internal error: check of unknown syntax requested");
 225     return errors;
 226 }
 227 
 228 #ifdef UNIT_TEST
 229 int main()
     /* [<][>][^][v][top][bottom][index][help] */
 230 {
 231     int i, j;
 232     GPtrArray *errors;
 233 
 234     /* call all syntax checks */
 235     for (i=0; i<SYNTAX_TAB_LEN; i++) {
 236         errors = syntax_check_by_offset(i, SYNTAX_CHECK_CORE, "");
 237         for (j=0; j<errors->len; j++) {
 238             g_free(g_ptr_array_index(errors, j));
 239         }
 240         g_ptr_array_free(errors, TRUE);
 241         errors = syntax_check_by_offset(i, SYNTAX_CHECK_FRONT_END, "");
 242         for (j=0; j<errors->len; j++) {
 243             g_free(g_ptr_array_index(errors, j));
 244         }
 245         g_ptr_array_free(errors, TRUE);
 246     }
 247 }
 248 #endif /* UNIT_TEST */
 249 
 250 /*
 251 int parse_error_count = 0;
 252 
 253 int main()
 254 {
 255     char buf[256];
 256     syntax_init();
 257     printf("check filter: ");
 258     gets(buf);
 259     printf("result=%d\n", syntax_check_by_name("filter", SYNTAX_CHECK_FRONT_END, buf));
 260 }
 261 */
 262 

/* [<][>][^][v][top][bottom][index][help] */