Changeset 925:e5a09fab5ef3 in freeDiameter for libfdcore/fdd.l
- Timestamp:
- Mar 2, 2013, 10:03:04 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdcore/fdd.l
r918 r925 67 67 /* %option noinput ? */ 68 68 #define YY_NO_INPUT 69 70 /* Additional for files inclusion */ 71 #include <glob.h> 72 #include <string.h> 73 74 #define MAX_NESTED_CONF_FILES 5 75 76 struct nested_conffiles_t { 77 YY_BUFFER_STATE parent_level_state; 78 glob_t filelist; 79 int current_file; 80 } nested_conffiles[MAX_NESTED_CONF_FILES]; 81 82 int current_nested_level = 0; 83 84 int globerrfct(const char *epath, int eerrno) 85 { 86 TRACE_DEBUG_ERROR("Failed to scan %s: %s\n", epath, strerror(eerrno)); 87 return 1; 88 } 89 69 90 %} 70 91 … … 73 94 %option nounput 74 95 96 %x in_include 97 75 98 /* Quoted string. Multilines do not match. */ 76 99 qstring \"[^\"\n]*\" 77 100 78 101 %% 79 80 102 <*>\n { 81 103 /* Update the line count */ … … 87 109 <*>([[:space:]]{-}[\n])+ ; /* Eat all spaces, not new lines */ 88 110 <*>#.*$ ; /* Eat all comments */ 111 112 113 include BEGIN(in_include); 114 /* Following an "include" keyword */ 115 <in_include>{ 116 {qstring} { /* Name of the file to include. This is directly sent to glob. */ 117 int globerror=0; 118 char * buf = strdup(yytext+1); 119 if (buf[yyleng-2] != '"') 120 { 121 TRACE_DEBUG_ERROR("Unterminated string: %s\n", yytext); 122 return LEX_ERROR; 123 } 124 buf[yyleng-2] = '\0'; 125 126 if (current_nested_level >= MAX_NESTED_CONF_FILES) 127 { 128 TRACE_DEBUG_ERROR("Too many recursion levels in configuration files includes\n"); 129 return LEX_ERROR; 130 } 131 132 /* glob the include */ 133 globerror = glob(buf, GLOB_ERR, globerrfct, &nested_conffiles[current_nested_level].filelist); 134 135 if (globerror == GLOB_NOSPACE) 136 { 137 TRACE_DEBUG_ERROR("Not enough memory to parse include directive.\n"); 138 return LEX_ERROR; 139 } 140 if (globerror == GLOB_ABORTED) 141 { 142 TRACE_DEBUG_ERROR("An error was encountered in include directive.\n"); 143 return LEX_ERROR; 144 } 145 if (globerror == GLOB_NOMATCH) 146 { 147 globfree(&nested_conffiles[current_nested_level].filelist); 148 goto nomatch; 149 } 150 if (globerror) 151 { 152 TRACE_DEBUG_ERROR("Unexpected error in glob (%d).\n", globerror); 153 return LEX_ERROR; 154 } 155 156 /* We have a list of files to include. */ 157 158 /* save the current buffer for returning when this include has been parsed */ 159 nested_conffiles[current_nested_level].parent_level_state = YY_CURRENT_BUFFER; 160 161 /* Start with the first match */ 162 nested_conffiles[current_nested_level].current_file = 0; 163 164 yyin = fopen( nested_conffiles[current_nested_level].filelist.gl_pathv[0], "r" ); 165 166 if ( ! yyin ) 167 { 168 TRACE_DEBUG_ERROR("Error in %s: %s", nested_conffiles[current_nested_level].filelist.gl_pathv[0], strerror(errno)); 169 return LEX_ERROR; 170 } 171 172 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE )); 173 174 /* In case of recursive includes */ 175 current_nested_level++; 176 177 nomatch: 178 BEGIN(INITIAL); 179 } 180 } 181 182 <<EOF>> { 183 if (current_nested_level == 0) 184 { 185 /* We are at the end of parsing */ 186 yyterminate(); 187 } 188 189 /* Otherwise we are doing an include statement */ 190 --current_nested_level; 191 yy_delete_buffer(YY_CURRENT_BUFFER); 192 193 /* Go to next file, if any */ 194 nested_conffiles[current_nested_level].current_file++; 195 if ( nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file] == NULL ) 196 { 197 /* We have finished with this list of includes */ 198 globfree(&nested_conffiles[current_nested_level].filelist); 199 yy_switch_to_buffer(nested_conffiles[current_nested_level].parent_level_state); 200 } 201 else 202 { 203 /* Proceed to next included file */ 204 yyin = fopen( nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file], "r" ); 205 206 if ( ! yyin ) 207 { 208 TRACE_DEBUG_ERROR("Error in %s: %s", nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file], strerror(errno)); 209 return LEX_ERROR; 210 } 211 212 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE )); 213 214 /* In case of recursive includes */ 215 current_nested_level++; 216 } 217 218 } 89 219 90 220 {qstring} {
Note: See TracChangeset
for help on using the changeset viewer.