core: respect order field in NAPTR, as required by RFC 2915
[sip-router] / cfg.lex
1 /*
2  * $Id$
3  *
4  * scanner for cfg files
5  *
6  * Copyright (C) 2001-2003 FhG Fokus
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  * History:
30  * -------
31  *  2003-01-29  src_port added (jiri)
32  *  2003-01-23  mhomed added (jiri)
33  *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
34  *  2003-04-01  added dst_port, proto (tcp, udp, tls), af(inet, inet6) (andrei)
35  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
36  *  2003-04-12  added force_rport, chdir and wdir (andrei)
37  *  2003-04-22  strip_tail added (jiri)
38  *  2003-07-03  tls* (disable, certificate, private_key, ca_list, verify,
39  *               require_certificate added (andrei)
40  *  2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
41  *  2003-10-02  added {,set_}advertised_{address,port} (andrei)
42  *  2003-10-07  added hex and octal numbers support (andrei)
43  *  2003-10-10  replaced len_gt w/ msg:len (andrei)
44  *  2003-10-13  added fifo_dir (andrei)
45  *  2003-10-28  added tcp_accept_aliases (andrei)
46  *  2003-11-29  added {tcp_send, tcp_connect, tls_*}_timeout (andrei)
47  *  2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
48  *  2004-04-28  added sock_mode (replaces fifo_mode), sock_user &
49  *               sock_group  (andrei)
50  *  2004-05-03  applied multicast support patch from janakj
51  *              added MCAST_TTL (andrei)
52  *  2004-10-08  more escapes: \", \xHH, \nnn and minor optimizations (andrei)
53  *  2004-10-19  added FROM_URI and TO_URI (andrei)
54  *  2004-11-30  added force_send_socket
55  *  2005-07-08  added tcp_connection_lifetime, tcp_poll_method,
56  *               tcp_max_connections (andrei)
57  *  2005-07-11  added dns_retr_{time,no}, dns_servers_no, dns_use_search_list,
58  *              dns_try_ipv6 (andrei)
59  *  2005-12-11  added onsend_route, snd_{ip,port,proto,af},
60  *              to_{ip,port} (andrei)
61  *  2005-12-12  separated drop, exit, break, return, added RETCODE (andrei)
62  *  2005-12-19  select framework (mma)
63  *  2006-09-11  added dns cache (use, flags, ttls, mem ,gc) & dst blacklist
64  *              options (andrei)
65  *  2006-10-13  added STUN_ALLOW_STUN, STUN_ALLOW_FP, STUN_REFRESH_INTERVAL
66  *              (vlada)
67  *  2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
68  *              RT_POLICY, RT_TIMER1_PRIO, RT_TIMER1_POLICY, RT_TIMER2_PRIO,
69  *              RT_TIMER2_POLICY (andrei)
70  *  2007-06-16  added DNS_SRV_LB, DNS_TRY_NAPTR (andrei)
71  *  2007-06-18  added DNS_{UDP,TCP,TLS}_PREF (andrei)
72  *  2007-09-10  introduced phone2tel option which allows NOT to consider
73  *              user=phone URIs as TEL URIs (jiri)
74  *  2007-10-10  added DNS_SEARCH_FMATCH (mma)
75  *  2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
76  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
77  *  2008-01-24  added CFG_DESCRIPTION used by cfg_var (Miklos)
78  *  2008-11-28  added support for kamailio pvars and avp/pvar guessing (andrei)
79  *  2008-12-11  added support for "string1" "string2" (andrei)
80  *  2009-03-10  added SET_USERPHONE action (Miklos)
81  *  2009-04-24  add strlen, strempty and defined operators (andrei)
82  *  2009-03-07  RETCODE, it's now  a core pvar (andrei)
83  *  2010-01-10  added SHM_MEM_SZ (andrei)
84  *  2010-02-17 added DST_BLST_{UDP,TCP,TLS,SCTP}_IMASK (andrei)
85 */
86
87 %option noinput
88
89 %{
90         #include "dprint.h"
91         #include "globals.h"
92         #include "mem/mem.h"
93         #include <string.h>
94         #include <stdlib.h>
95         #include "ip_addr.h"
96         #include "usr_avp.h"
97         #include "select.h"
98         #include "cfg.tab.h"
99         #include "sr_compat.h"
100         #include "ppcfg.h"
101
102         /* states */
103         #define INITIAL_S               0
104         #define COMMENT_S               1
105         #define COMMENT_LN_S            2
106         #define STRING_S                3
107         #define ATTR_S                  4  /* avp/attr */
108         #define SELECT_S                5
109         #define AVP_PVAR_S              6  /* avp or pvar */
110         #define PVAR_P_S                7  /* pvar: $(...)  or $foo(...)*/
111         #define PVARID_S                8  /* $foo.bar...*/
112         #define STR_BETWEEN_S           9
113         #define LINECOMMENT_S           10
114         #define DEFINE_S                11
115         #define DEFINE_EOL_S            12
116         #define IFDEF_S                 13
117         #define IFDEF_EOL_S             14
118         #define IFDEF_SKIP_S            15
119         #define DEFINE_DATA_S           16
120
121         #define STR_BUF_ALLOC_UNIT      128
122         struct str_buf{
123                 char* s;
124                 char* crt;
125                 int left;
126         };
127
128
129         static int comment_nest=0;
130         static int p_nest=0;
131         static int state=0, old_state=0, old_initial=0;
132         static struct str_buf s_buf;
133         int line=1;
134         int column=1;
135         int startcolumn=1;
136         int startline=1;
137         char *finame = 0;
138         static int ign_lines=0;
139         static int ign_columns=0;
140         char* yy_number_str=0; /* str correspondent for the current NUMBER token */
141         int r = 0;
142         str *sdef = 0;
143
144         static char* addchar(struct str_buf *, char);
145         static char* addstr(struct str_buf *, char*, int);
146         static void count();
147         static void count_more();
148         static void count_ignore();
149
150         #define MAX_INCLUDE_DEPTH 10
151         static struct sr_yy_state {
152                 YY_BUFFER_STATE state;
153                 int line;
154                 int column;
155                 int startcolumn;
156                 int startline;
157                 char *finame;
158         } include_stack[MAX_INCLUDE_DEPTH];
159         static int include_stack_ptr = 0;
160
161         static int sr_push_yy_state(char *fin, int mode);
162         static int sr_pop_yy_state();
163
164         static struct sr_yy_fname {
165                 char *fname;
166                 struct sr_yy_fname *next;
167         } *sr_yy_fname_list = 0;
168
169         static str  *pp_define_get(int len, const char * text);
170         static int  pp_ifdef_type(int pos);
171         static void pp_ifdef_var(int len, const char * text);
172         static void pp_ifdef();
173         static void pp_else();
174         static void pp_endif();
175
176 %}
177
178 /* start conditions */
179 %x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P 
180 %x PVARID INCLF IMPTF
181 %x LINECOMMENT DEFINE_ID DEFINE_EOL DEFINE_DATA IFDEF_ID IFDEF_EOL IFDEF_SKIP
182
183 /* config script types : #!SER  or #!KAMAILIO or #!MAX_COMPAT */
184 SER_CFG                 SER
185 KAMAILIO_CFG    KAMAILIO|OPENSER
186 MAXCOMPAT_CFG   MAXCOMPAT|ALL
187
188 /* action keywords */
189 FORWARD forward
190 FORWARD_TCP     forward_tcp
191 FORWARD_UDP     forward_udp
192 FORWARD_TLS     forward_tls
193 FORWARD_SCTP    forward_sctp
194 DROP    "drop"
195 EXIT    "exit"
196 RETURN  "return"
197 BREAK   "break"
198 LOG             log
199 ERROR   error
200 ROUTE   route
201 ROUTE_REQUEST request_route
202 ROUTE_FAILURE failure_route
203 ROUTE_REPLY reply_route
204 ROUTE_ONREPLY onreply_route
205 ROUTE_BRANCH branch_route
206 ROUTE_SEND onsend_route
207 ROUTE_EVENT event_route
208 EXEC    exec
209 FORCE_RPORT             "force_rport"|"add_rport"
210 ADD_LOCAL_RPORT         "add_local_rport"
211 FORCE_TCP_ALIAS         "force_tcp_alias"|"add_tcp_alias"
212 UDP_MTU         "udp_mtu"
213 UDP_MTU_TRY_PROTO       "udp_mtu_try_proto"
214 UDP4_RAW                "udp4_raw"
215 UDP4_RAW_MTU    "udp4_raw_mtu"
216 UDP4_RAW_TTL    "udp4_raw_ttl"
217 SETFLAG         setflag
218 RESETFLAG       resetflag
219 ISFLAGSET       isflagset
220 FLAGS_DECL      "flags"|"bool"
221 SETAVPFLAG      setavpflag
222 RESETAVPFLAG    resetavpflag
223 ISAVPFLAGSET    isavpflagset
224 AVPFLAGS_DECL   avpflags
225 SET_HOST                "rewritehost"|"sethost"|"seth"
226 SET_HOSTPORT    "rewritehostport"|"sethostport"|"sethp"
227 SET_HOSTPORTTRANS       "rewritehostporttrans"|"sethostporttrans"|"sethpt"
228 SET_USER                "rewriteuser"|"setuser"|"setu"
229 SET_USERPASS    "rewriteuserpass"|"setuserpass"|"setup"
230 SET_PORT                "rewriteport"|"setport"|"setp"
231 SET_URI                 "rewriteuri"|"seturi"
232 REVERT_URI              "revert_uri"
233 PREFIX                  "prefix"
234 STRIP                   "strip"
235 STRIP_TAIL              "strip_tail"
236 SET_USERPHONE           "userphone"
237 REMOVE_BRANCH   "remove_branch"
238 CLEAR_BRANCHES  "clear_branches"
239 IF                              "if"
240 ELSE                    "else"
241 SET_ADV_ADDRESS "set_advertised_address"
242 SET_ADV_PORT    "set_advertised_port"
243 FORCE_SEND_SOCKET       "force_send_socket"
244 SET_FWD_NO_CONNECT              "set_forward_no_connect"
245 SET_RPL_NO_CONNECT      "set_reply_no_connect"
246 SET_FWD_CLOSE   "set_forward_close"
247 SET_RPL_CLOSE   "set_reply_close"
248 SWITCH                  "switch"
249 CASE                    "case"
250 DEFAULT                 "default"
251 WHILE                   "while"
252
253 CFG_SELECT      "cfg_select"
254 CFG_RESET       "cfg_reset"
255
256 /*ACTION LVALUES*/
257 URIHOST                 "uri:host"
258 URIPORT                 "uri:port"
259
260 MAX_LEN                 "max_len"
261
262
263 /* condition keywords */
264 METHOD  method
265 /* hack -- the second element in first line is referable
266    as either uri or status; it only would makes sense to
267    call it "uri" from route{} and status from onreply_route{}
268 */
269 URI             "uri"|"status"
270 FROM_URI        "from_uri"
271 TO_URI          "to_uri"
272 SRCIP   src_ip
273 SRCPORT src_port
274 DSTIP   dst_ip
275 DSTPORT dst_port
276 SNDIP   snd_ip
277 SNDPORT snd_port
278 SNDPROTO        snd_proto|to_proto
279 SNDAF           snd_af|to_af
280 TOIP    to_ip
281 TOPORT  to_port
282 PROTO   proto
283 AF              af
284 MYSELF  myself
285 MSGLEN                  "msg:len"
286 RETCODE \$\?|\$retcode|\$rc
287 /* operators */
288 EQUAL   =
289 EQUAL_T ==
290 GT      >
291 LT      <
292 GTE     >=
293 LTE     <=
294 DIFF    !=
295 MATCH   =~
296 ADDEQ     "+="
297 NOT             !|"not"
298 LOG_AND         "and"|"&&"
299 BIN_AND         "&"
300 LOG_OR          "or"|"||"
301 BIN_OR          "|"
302 BIN_NOT     "~"
303 BIN_XOR     "^"
304 BIN_LSHIFT     "<<"
305 BIN_RSHIFT     ">>"
306 PLUS    "+"
307 MINUS   "-"
308 MODULO  "mod"
309 STRLEN  "strlen"
310 STREMPTY        "strempty"
311 DEFINED         "defined"
312 STREQ   eq
313 INTEQ   ieq
314 STRDIFF ne
315 INTDIFF ine
316 INTCAST \(int\)
317 STRCAST \(str\)
318
319 /* Attribute specification */
320 ATTR_MARK   "%"
321 VAR_MARK    "$"
322 SELECT_MARK  "@"
323 ATTR_FROM         "f"
324 ATTR_TO           "t"
325 ATTR_FROMURI      "fr"
326 ATTR_TOURI       "tr"
327 ATTR_FROMUSER     "fu"
328 ATTR_TOUSER       "tu"
329 ATTR_FROMDOMAIN   "fd"
330 ATTR_TODOMAIN     "td"
331 ATTR_GLOBAL       "g"
332
333 /* avp prefix */
334 AVP_PREF        (([ft][rud]?)|g)\.
335
336 /* config vars. */
337 DEBUG   debug
338 FORK    fork
339 FORK_DELAY      fork_delay
340 MODINIT_DELAY   modinit_delay
341 LOGSTDERROR     log_stderror
342 LOGFACILITY     log_facility
343 LOGNAME         log_name
344 LOGCOLOR        log_color
345 LISTEN          listen
346 ADVERTISE       advertise|ADVERTISE
347 ALIAS           alias
348 SR_AUTO_ALIASES auto_aliases
349 DNS              dns
350 REV_DNS  rev_dns
351 DNS_TRY_IPV6    dns_try_ipv6
352 DNS_TRY_NAPTR   dns_try_naptr
353 DNS_SRV_LB              dns_srv_lb|dns_srv_loadbalancing
354 DNS_UDP_PREF    dns_udp_pref|dns_udp_preference
355 DNS_TCP_PREF    dns_tcp_pref|dns_tcp_preference
356 DNS_TLS_PREF    dns_tls_pref|dns_tls_preference
357 DNS_SCTP_PREF   dns_sctp_pref|dns_sctp_preference
358 DNS_RETR_TIME   dns_retr_time
359 DNS_RETR_NO             dns_retr_no
360 DNS_SERVERS_NO  dns_servers_no
361 DNS_USE_SEARCH  dns_use_search_list
362 DNS_SEARCH_FMATCH       dns_search_full_match
363 DNS_NAPTR_IGNORE_RFC    dns_naptr_ignore_rfc
364 /* dns cache */
365 DNS_CACHE_INIT  dns_cache_init
366 DNS_USE_CACHE   use_dns_cache
367 DNS_USE_FAILOVER        use_dns_failover
368 DNS_CACHE_FLAGS         dns_cache_flags
369 DNS_CACHE_NEG_TTL       dns_cache_negative_ttl
370 DNS_CACHE_MIN_TTL       dns_cache_min_ttl
371 DNS_CACHE_MAX_TTL       dns_cache_max_ttl
372 DNS_CACHE_MEM           dns_cache_mem
373 DNS_CACHE_GC_INT        dns_cache_gc_interval
374 DNS_CACHE_DEL_NONEXP    dns_cache_del_nonexp|dns_cache_delete_nonexpired
375 /* ipv6 auto bind */
376 AUTO_BIND_IPV6          auto_bind_ipv6
377 /* blacklist */
378 DST_BLST_INIT   dst_blacklist_init
379 USE_DST_BLST            use_dst_blacklist
380 DST_BLST_MEM            dst_blacklist_mem
381 DST_BLST_TTL            dst_blacklist_expire|dst_blacklist_ttl
382 DST_BLST_GC_INT         dst_blacklist_gc_interval
383 DST_BLST_UDP_IMASK      dst_blacklist_udp_imask
384 DST_BLST_TCP_IMASK      dst_blacklist_tcp_imask
385 DST_BLST_TLS_IMASK      dst_blacklist_tls_imask
386 DST_BLST_SCTP_IMASK     dst_blacklist_sctp_imask
387
388
389 PORT    port
390 STAT    statistics
391 MAXBUFFER maxbuffer
392 SQL_BUFFER_SIZE sql_buffer_size
393 CHILDREN children
394 SOCKET_WORKERS socket_workers
395 CHECK_VIA       check_via
396 PHONE2TEL       phone2tel
397 MEMLOG          "memlog"|"mem_log"
398 MEMDBG          "memdbg"|"mem_dbg"
399 MEMSUM          "mem_summary"
400 MEMSAFETY       "mem_safety"
401 MEMJOIN         "mem_join"
402 CORELOG         "corelog"|"core_log"
403 SIP_WARNING sip_warning
404 SERVER_SIGNATURE server_signature
405 SERVER_HEADER server_header
406 USER_AGENT_HEADER user_agent_header
407 REPLY_TO_VIA reply_to_via
408 USER            "user"|"uid"
409 GROUP           "group"|"gid"
410 CHROOT          "chroot"
411 WDIR            "workdir"|"wdir"
412 MHOMED          mhomed
413 DISABLE_TCP             "disable_tcp"
414 TCP_CHILDREN    "tcp_children"
415 TCP_ACCEPT_ALIASES      "tcp_accept_aliases"
416 TCP_SEND_TIMEOUT        "tcp_send_timeout"
417 TCP_CONNECT_TIMEOUT     "tcp_connect_timeout"
418 TCP_CON_LIFETIME        "tcp_connection_lifetime"
419 TCP_POLL_METHOD         "tcp_poll_method"
420 TCP_MAX_CONNECTIONS     "tcp_max_connections"
421 TLS_MAX_CONNECTIONS     "tls_max_connections"
422 TCP_NO_CONNECT          "tcp_no_connect"
423 TCP_SOURCE_IPV4         "tcp_source_ipv4"
424 TCP_SOURCE_IPV6         "tcp_source_ipv6"
425 TCP_OPT_FD_CACHE        "tcp_fd_cache"
426 TCP_OPT_BUF_WRITE       "tcp_buf_write"|"tcp_async"
427 TCP_OPT_CONN_WQ_MAX     "tcp_conn_wq_max"
428 TCP_OPT_WQ_MAX          "tcp_wq_max"
429 TCP_OPT_RD_BUF          "tcp_rd_buf_size"
430 TCP_OPT_WQ_BLK          "tcp_wq_blk_size"
431 TCP_OPT_DEFER_ACCEPT "tcp_defer_accept"
432 TCP_OPT_DELAYED_ACK     "tcp_delayed_ack"
433 TCP_OPT_SYNCNT          "tcp_syncnt"
434 TCP_OPT_LINGER2         "tcp_linger2"
435 TCP_OPT_KEEPALIVE       "tcp_keepalive"
436 TCP_OPT_KEEPIDLE        "tcp_keepidle"
437 TCP_OPT_KEEPINTVL       "tcp_keepintvl"
438 TCP_OPT_KEEPCNT         "tcp_keepcnt"
439 TCP_OPT_CRLF_PING       "tcp_crlf_ping"
440 TCP_OPT_ACCEPT_NO_CL    "tcp_accept_no_cl"
441 TCP_CLONE_RCVBUF        "tcp_clone_rcvbuf"
442 DISABLE_TLS             "disable_tls"|"tls_disable"
443 ENABLE_TLS              "enable_tls"|"tls_enable"
444 TLSLOG                  "tlslog"|"tls_log"
445 TLS_PORT_NO             "tls_port_no"
446 TLS_METHOD              "tls_method"
447 TLS_VERIFY              "tls_verify"
448 TLS_REQUIRE_CERTIFICATE "tls_require_certificate"
449 TLS_CERTIFICATE "tls_certificate"
450 TLS_PRIVATE_KEY "tls_private_key"
451 TLS_CA_LIST             "tls_ca_list"
452 TLS_HANDSHAKE_TIMEOUT   "tls_handshake_timeout"
453 TLS_SEND_TIMEOUT        "tls_send_timeout"
454 DISABLE_SCTP    "disable_sctp"
455 ENABLE_SCTP     "enable_sctp"
456 SCTP_CHILDREN   "sctp_children"
457
458 ADVERTISED_ADDRESS      "advertised_address"
459 ADVERTISED_PORT         "advertised_port"
460 DISABLE_CORE            "disable_core_dump"
461 OPEN_FD_LIMIT           "open_files_limit"
462 SHM_MEM_SZ              "shm"|"shm_mem"|"shm_mem_size"
463 SHM_FORCE_ALLOC         "shm_force_alloc"
464 MLOCK_PAGES                     "mlock_pages"
465 REAL_TIME                       "real_time"
466 RT_PRIO                         "rt_prio"
467 RT_POLICY                       "rt_policy"
468 RT_TIMER1_PRIO          "rt_timer1_prio"|"rt_fast_timer_prio"|"rt_ftimer_prio"
469 RT_TIMER1_POLICY        "rt_timer1_policy"|"rt_ftimer_policy"
470 RT_TIMER2_PRIO          "rt_timer2_prio"|"rt_stimer_prio"
471 RT_TIMER2_POLICY        "rt_timer2_policy"|"rt_stimer_policy"
472 MCAST_LOOPBACK          "mcast_loopback"
473 MCAST_TTL               "mcast_ttl"
474 TOS                     "tos"
475 PMTU_DISCOVERY  "pmtu_discovery"
476 KILL_TIMEOUT    "exit_timeout"|"ser_kill_timeout"
477 MAX_WLOOPS              "max_while_loops"
478 PVBUFSIZE               "pv_buffer_size"
479 PVBUFSLOTS              "pv_buffer_slots"
480 HTTP_REPLY_PARSE                "http_reply_hack"|"http_reply_parse"
481 VERSION_TABLE_CFG               "version_table"
482
483 SERVER_ID     "server_id"
484
485 LATENCY_LOG                             latency_log
486 LATENCY_LIMIT_DB                latency_limit_db
487 LATENCY_LIMIT_ACTION    latency_limit_action
488
489 MSG_TIME        msg_time
490
491 CFG_DESCRIPTION         "description"|"descr"|"desc"
492
493 LOADMODULE      loadmodule
494 LOADPATH        "loadpath"|"mpath"
495 MODPARAM        modparam
496
497 /* values */
498 YES                     "yes"|"true"|"on"|"enable"
499 NO                      "no"|"false"|"off"|"disable"
500 UDP                     "udp"|"UDP"
501 TCP                     "tcp"|"TCP"
502 TLS                     "tls"|"TLS"
503 SCTP            "sctp"|"SCTP"
504 WS              "ws"|"WS"
505 WSS             "wss"|"WSS"
506 INET            "inet"|"INET"
507 INET6           "inet6"|"INET6"
508 SSLv23                  "sslv23"|"SSLv23"|"SSLV23"
509 SSLv2                   "sslv2"|"SSLv2"|"SSLV2"
510 SSLv3                   "sslv3"|"SSLv3"|"SSLV3"
511 TLSv1                   "tlsv1"|"TLSv1"|"TLSV1"
512
513 LETTER          [a-zA-Z]
514 DIGIT           [0-9]
515 LETTER_     {LETTER}|[_]
516 ALPHANUM    {LETTER_}|{DIGIT}
517 ID          {LETTER_}{ALPHANUM}*
518 NUM_ID          {ALPHANUM}+
519 HEX                     [0-9a-fA-F]
520 HEXNUMBER       0x{HEX}+
521 OCTNUMBER       0[0-7]+
522 DECNUMBER       0|([1-9]{DIGIT}*)
523 BINNUMBER       [0-1]+b
524 HEX4            {HEX}{1,4}
525 IPV6ADDR        ({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
526 QUOTES          \"
527 TICK            \'
528 SLASH           "/"
529 SEMICOLON       ;
530 RPAREN          \)
531 LPAREN          \(
532 LBRACE          \{
533 RBRACE          \}
534 LBRACK          \[
535 RBRACK          \]
536 COMMA           ","
537 COLON           ":"
538 STAR            \*
539 DOT                     \.
540 CR                      \n
541 EVENT_RT_NAME [a-zA-Z][0-9a-zA-Z-]*(":"[a-zA-Z][0-9a-zA-Z-]*)+
542
543
544 COM_LINE        "#"|"//"
545 COM_START       "/\*"
546 COM_END         "\*/"
547
548 /* start of pre-processing directives */
549 PREP_START      "#!"|"!!"
550
551 DEFINE       "define"|"def"
552 IFDEF        ifdef
553 IFNDEF       ifndef
554 ENDIF        endif
555 TRYDEF       "trydefine"|"trydef"
556 REDEF        "redefine"|"redef"
557
558 /* else is already defined */
559
560 EAT_ABLE        [\ \t\b\r]
561
562 /* pre-processing blocks */
563 SUBST       subst
564 SUBSTDEF    substdef
565 SUBSTDEFS   substdefs
566
567 /* include files */
568 INCLUDEFILE     "include_file"
569 IMPORTFILE      "import_file"
570
571 %%
572
573
574 <INITIAL>{EAT_ABLE}     { count(); }
575
576 <INITIAL>{FORWARD}      {count(); yylval.strval=yytext; return FORWARD; }
577 <INITIAL>{FORWARD_TCP}  {count(); yylval.strval=yytext; return FORWARD_TCP; }
578 <INITIAL>{FORWARD_TLS}  {count(); yylval.strval=yytext; return FORWARD_TLS; }
579 <INITIAL>{FORWARD_SCTP} {count(); yylval.strval=yytext; return FORWARD_SCTP;}
580 <INITIAL>{FORWARD_UDP}  {count(); yylval.strval=yytext; return FORWARD_UDP; }
581 <INITIAL>{DROP} { count(); yylval.strval=yytext; return DROP; }
582 <INITIAL>{EXIT} { count(); yylval.strval=yytext; return EXIT; }
583 <INITIAL>{RETURN}       { count(); yylval.strval=yytext; return RETURN; }
584 <INITIAL>{BREAK}        { count(); yylval.strval=yytext; return BREAK; }
585 <INITIAL>{LOG}  { count(); yylval.strval=yytext; return LOG_TOK; }
586 <INITIAL>{ERROR}        { count(); yylval.strval=yytext; return ERROR; }
587 <INITIAL>{SETFLAG}      { count(); yylval.strval=yytext; return SETFLAG; }
588 <INITIAL>{RESETFLAG}    { count(); yylval.strval=yytext; return RESETFLAG; }
589 <INITIAL>{ISFLAGSET}    { count(); yylval.strval=yytext; return ISFLAGSET; }
590 <INITIAL>{FLAGS_DECL}   { count(); yylval.strval=yytext; return FLAGS_DECL; }
591 <INITIAL>{SETAVPFLAG}   { count(); yylval.strval=yytext; return SETAVPFLAG; }
592 <INITIAL>{RESETAVPFLAG} { count(); yylval.strval=yytext; return RESETAVPFLAG; }
593 <INITIAL>{ISAVPFLAGSET} { count(); yylval.strval=yytext; return ISAVPFLAGSET; }
594 <INITIAL>{AVPFLAGS_DECL}        { count(); yylval.strval=yytext; return AVPFLAGS_DECL; }
595 <INITIAL>{MSGLEN}       { count(); yylval.strval=yytext; return MSGLEN; }
596 <INITIAL>{ROUTE}        { count(); yylval.strval=yytext; return ROUTE; }
597 <INITIAL>{ROUTE_REQUEST}        { count(); yylval.strval=yytext; return ROUTE_REQUEST; }
598 <INITIAL>{ROUTE_ONREPLY}        { count(); yylval.strval=yytext;
599                                                                 return ROUTE_ONREPLY; }
600 <INITIAL>{ROUTE_REPLY}  { count(); yylval.strval=yytext; return ROUTE_REPLY; }
601 <INITIAL>{ROUTE_FAILURE}        { count(); yylval.strval=yytext;
602                                                                 return ROUTE_FAILURE; }
603 <INITIAL>{ROUTE_BRANCH} { count(); yylval.strval=yytext; return ROUTE_BRANCH; }
604 <INITIAL>{ROUTE_SEND} { count(); yylval.strval=yytext; return ROUTE_SEND; }
605 <INITIAL>{ROUTE_EVENT} { count(); yylval.strval=yytext; return ROUTE_EVENT; }
606 <INITIAL>{EXEC} { count(); yylval.strval=yytext; return EXEC; }
607 <INITIAL>{SET_HOST}     { count(); yylval.strval=yytext; return SET_HOST; }
608 <INITIAL>{SET_HOSTPORT} { count(); yylval.strval=yytext; return SET_HOSTPORT; }
609 <INITIAL>{SET_HOSTPORTTRANS}    { count(); yylval.strval=yytext; return SET_HOSTPORTTRANS; }
610 <INITIAL>{SET_USER}     { count(); yylval.strval=yytext; return SET_USER; }
611 <INITIAL>{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; }
612 <INITIAL>{SET_PORT}     { count(); yylval.strval=yytext; return SET_PORT; }
613 <INITIAL>{SET_URI}      { count(); yylval.strval=yytext; return SET_URI; }
614 <INITIAL>{REVERT_URI}   { count(); yylval.strval=yytext; return REVERT_URI; }
615 <INITIAL>{PREFIX}       { count(); yylval.strval=yytext; return PREFIX; }
616 <INITIAL>{STRIP}        { count(); yylval.strval=yytext; return STRIP; }
617 <INITIAL>{STRIP_TAIL}   { count(); yylval.strval=yytext; return STRIP_TAIL; }
618 <INITIAL>{REMOVE_BRANCH}        { count(); yylval.strval=yytext;
619                                                                 return REMOVE_BRANCH; }
620 <INITIAL>{CLEAR_BRANCHES}       { count(); yylval.strval=yytext;
621                                                                 return CLEAR_BRANCHES; }
622 <INITIAL>{SET_USERPHONE}        { count(); yylval.strval=yytext;
623                                                                 return SET_USERPHONE; }
624 <INITIAL>{FORCE_RPORT}  { count(); yylval.strval=yytext; return FORCE_RPORT; }
625 <INITIAL>{ADD_LOCAL_RPORT}      { count(); yylval.strval=yytext;
626                                                                 return ADD_LOCAL_RPORT; }
627 <INITIAL>{FORCE_TCP_ALIAS}      { count(); yylval.strval=yytext;
628                                                                 return FORCE_TCP_ALIAS; }
629 <INITIAL>{UDP_MTU}      { count(); yylval.strval=yytext; return UDP_MTU; }
630 <INITIAL>{UDP_MTU_TRY_PROTO}    { count(); yylval.strval=yytext;
631                                                                         return UDP_MTU_TRY_PROTO; }
632 <INITIAL>{UDP4_RAW}     { count(); yylval.strval=yytext; return UDP4_RAW; }
633 <INITIAL>{UDP4_RAW_MTU} { count(); yylval.strval=yytext; return UDP4_RAW_MTU; }
634 <INITIAL>{UDP4_RAW_TTL} { count(); yylval.strval=yytext; return UDP4_RAW_TTL; }
635 <INITIAL>{IF}   { count(); yylval.strval=yytext; return IF; }
636 <INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; }
637
638 <INITIAL>{SET_ADV_ADDRESS}      { count(); yylval.strval=yytext;
639                                                                                 return SET_ADV_ADDRESS; }
640 <INITIAL>{SET_ADV_PORT} { count(); yylval.strval=yytext;
641                                                                                 return SET_ADV_PORT; }
642 <INITIAL>{FORCE_SEND_SOCKET}    {       count(); yylval.strval=yytext;
643                                                                         return FORCE_SEND_SOCKET; }
644 <INITIAL>{SET_FWD_NO_CONNECT}   { count(); yylval.strval=yytext;
645                                                                         return SET_FWD_NO_CONNECT; }
646 <INITIAL>{SET_RPL_NO_CONNECT}   { count(); yylval.strval=yytext;
647                                                                         return SET_RPL_NO_CONNECT; }
648 <INITIAL>{SET_FWD_CLOSE}                { count(); yylval.strval=yytext;
649                                                                         return SET_FWD_CLOSE; }
650 <INITIAL>{SET_RPL_CLOSE}                { count(); yylval.strval=yytext;
651                                                                         return SET_RPL_CLOSE; }
652 <INITIAL>{SWITCH}       { count(); yylval.strval=yytext; return SWITCH; }
653 <INITIAL>{CASE} { count(); yylval.strval=yytext; return CASE; }
654 <INITIAL>{DEFAULT}      { count(); yylval.strval=yytext; return DEFAULT; }
655 <INITIAL>{WHILE}        { count(); yylval.strval=yytext; return WHILE; }
656
657 <INITIAL>{INCLUDEFILE}  { count(); BEGIN(INCLF); }
658 <INITIAL>{PREP_START}{INCLUDEFILE}  { count(); BEGIN(INCLF); }
659
660 <INITIAL>{IMPORTFILE}  { count(); BEGIN(IMPTF); }
661 <INITIAL>{PREP_START}{IMPORTFILE}  { count(); BEGIN(IMPTF); }
662
663 <INITIAL>{CFG_SELECT}   { count(); yylval.strval=yytext; return CFG_SELECT; }
664 <INITIAL>{CFG_RESET}    { count(); yylval.strval=yytext; return CFG_RESET; }
665
666 <INITIAL>{URIHOST}      { count(); yylval.strval=yytext; return URIHOST; }
667 <INITIAL>{URIPORT}      { count(); yylval.strval=yytext; return URIPORT; }
668
669 <INITIAL>{MAX_LEN}      { count(); yylval.strval=yytext; return MAX_LEN; }
670
671 <INITIAL>{METHOD}       { count(); yylval.strval=yytext; return METHOD; }
672 <INITIAL>{URI}  { count(); yylval.strval=yytext; return URI; }
673 <INITIAL>{FROM_URI}     { count(); yylval.strval=yytext; return FROM_URI; }
674 <INITIAL>{TO_URI}       { count(); yylval.strval=yytext; return TO_URI; }
675 <INITIAL>{SRCIP}        { count(); yylval.strval=yytext; return SRCIP; }
676 <INITIAL>{SRCPORT}      { count(); yylval.strval=yytext; return SRCPORT; }
677 <INITIAL>{DSTIP}        { count(); yylval.strval=yytext; return DSTIP; }
678 <INITIAL>{DSTPORT}      { count(); yylval.strval=yytext; return DSTPORT; }
679 <INITIAL>{SNDIP}        { count(); yylval.strval=yytext; return SNDIP; }
680 <INITIAL>{SNDPORT}      { count(); yylval.strval=yytext; return SNDPORT; }
681 <INITIAL>{SNDPROTO}     { count(); yylval.strval=yytext; return SNDPROTO; }
682 <INITIAL>{SNDAF}        { count(); yylval.strval=yytext; return SNDAF; }
683 <INITIAL>{TOIP}         { count(); yylval.strval=yytext; return TOIP; }
684 <INITIAL>{TOPORT}       { count(); yylval.strval=yytext; return TOPORT; }
685 <INITIAL>{PROTO}        { count(); yylval.strval=yytext; return PROTO; }
686 <INITIAL>{AF}   { count(); yylval.strval=yytext; return AF; }
687 <INITIAL>{MYSELF}       { count(); yylval.strval=yytext; return MYSELF; }
688
689 <INITIAL>{DEBUG}        { count(); yylval.strval=yytext; return DEBUG_V; }
690 <INITIAL>{FORK}         { count(); yylval.strval=yytext; return FORK; }
691 <INITIAL>{FORK_DELAY}   { count(); yylval.strval=yytext; return FORK_DELAY; }
692 <INITIAL>{MODINIT_DELAY}        { count(); yylval.strval=yytext; return MODINIT_DELAY; }
693 <INITIAL>{LOGSTDERROR}  { yylval.strval=yytext; return LOGSTDERROR; }
694 <INITIAL>{LOGFACILITY}  { yylval.strval=yytext; return LOGFACILITY; }
695 <INITIAL>{LOGNAME}      { yylval.strval=yytext; return LOGNAME; }
696 <INITIAL>{LOGCOLOR}     { yylval.strval=yytext; return LOGCOLOR; }
697 <INITIAL>{LISTEN}       { count(); yylval.strval=yytext; return LISTEN; }
698 <INITIAL>{ADVERTISE}    { count(); yylval.strval=yytext; return ADVERTISE; }
699 <INITIAL>{ALIAS}        { count(); yylval.strval=yytext; return ALIAS; }
700 <INITIAL>{SR_AUTO_ALIASES}      { count(); yylval.strval=yytext;
701                                                                         return SR_AUTO_ALIASES; }
702 <INITIAL>{DNS}  { count(); yylval.strval=yytext; return DNS; }
703 <INITIAL>{REV_DNS}      { count(); yylval.strval=yytext; return REV_DNS; }
704 <INITIAL>{DNS_TRY_IPV6} { count(); yylval.strval=yytext;
705                                                                 return DNS_TRY_IPV6; }
706 <INITIAL>{DNS_TRY_NAPTR}        { count(); yylval.strval=yytext;
707                                                                 return DNS_TRY_NAPTR; }
708 <INITIAL>{DNS_SRV_LB}   { count(); yylval.strval=yytext;
709                                                                 return DNS_SRV_LB; }
710 <INITIAL>{DNS_UDP_PREF} { count(); yylval.strval=yytext;
711                                                                 return DNS_UDP_PREF; }
712 <INITIAL>{DNS_TCP_PREF} { count(); yylval.strval=yytext;
713                                                                 return DNS_TCP_PREF; }
714 <INITIAL>{DNS_TLS_PREF} { count(); yylval.strval=yytext;
715                                                                 return DNS_TLS_PREF; }
716 <INITIAL>{DNS_SCTP_PREF}        { count(); yylval.strval=yytext;
717                                                                 return DNS_SCTP_PREF; }
718 <INITIAL>{DNS_RETR_TIME}        { count(); yylval.strval=yytext;
719                                                                 return DNS_RETR_TIME; }
720 <INITIAL>{DNS_RETR_NO}  { count(); yylval.strval=yytext;
721                                                                 return DNS_RETR_NO; }
722 <INITIAL>{DNS_SERVERS_NO}       { count(); yylval.strval=yytext;
723                                                                 return DNS_SERVERS_NO; }
724 <INITIAL>{DNS_USE_SEARCH}       { count(); yylval.strval=yytext;
725                                                                 return DNS_USE_SEARCH; }
726 <INITIAL>{DNS_SEARCH_FMATCH}    { count(); yylval.strval=yytext;
727                                                                 return DNS_SEARCH_FMATCH; }
728 <INITIAL>{DNS_NAPTR_IGNORE_RFC} { count(); yylval.strval=yytext;
729                                                                 return DNS_NAPTR_IGNORE_RFC; }
730 <INITIAL>{DNS_CACHE_INIT}       { count(); yylval.strval=yytext;
731                                                                 return DNS_CACHE_INIT; }
732 <INITIAL>{DNS_USE_CACHE}        { count(); yylval.strval=yytext;
733                                                                 return DNS_USE_CACHE; }
734 <INITIAL>{DNS_USE_FAILOVER}     { count(); yylval.strval=yytext;
735                                                                 return DNS_USE_FAILOVER; }
736 <INITIAL>{DNS_CACHE_FLAGS}      { count(); yylval.strval=yytext;
737                                                                 return DNS_CACHE_FLAGS; }
738 <INITIAL>{DNS_CACHE_NEG_TTL}    { count(); yylval.strval=yytext;
739                                                                 return DNS_CACHE_NEG_TTL; }
740 <INITIAL>{DNS_CACHE_MIN_TTL}    { count(); yylval.strval=yytext;
741                                                                 return DNS_CACHE_MIN_TTL; }
742 <INITIAL>{DNS_CACHE_MAX_TTL}    { count(); yylval.strval=yytext;
743                                                                 return DNS_CACHE_MAX_TTL; }
744 <INITIAL>{DNS_CACHE_MEM}        { count(); yylval.strval=yytext;
745                                                                 return DNS_CACHE_MEM; }
746 <INITIAL>{DNS_CACHE_GC_INT}     { count(); yylval.strval=yytext;
747                                                                 return DNS_CACHE_GC_INT; }
748 <INITIAL>{DNS_CACHE_DEL_NONEXP} { count(); yylval.strval=yytext;
749                                                                 return DNS_CACHE_DEL_NONEXP; }
750 <INITIAL>{AUTO_BIND_IPV6}       { count(); yylval.strval=yytext;
751                                                                 return AUTO_BIND_IPV6; }
752 <INITIAL>{DST_BLST_INIT}        { count(); yylval.strval=yytext;
753                                                                 return DST_BLST_INIT; }
754 <INITIAL>{USE_DST_BLST} { count(); yylval.strval=yytext;
755                                                                 return USE_DST_BLST; }
756 <INITIAL>{DST_BLST_MEM} { count(); yylval.strval=yytext;
757                                                                 return DST_BLST_MEM; }
758 <INITIAL>{DST_BLST_TTL} { count(); yylval.strval=yytext;
759                                                                 return DST_BLST_TTL; }
760 <INITIAL>{DST_BLST_GC_INT}      { count(); yylval.strval=yytext;
761                                                                 return DST_BLST_GC_INT; }
762 <INITIAL>{DST_BLST_UDP_IMASK}   { count(); yylval.strval=yytext;
763                                                                 return DST_BLST_UDP_IMASK; }
764 <INITIAL>{DST_BLST_TCP_IMASK}   { count(); yylval.strval=yytext;
765                                                                 return DST_BLST_TCP_IMASK; }
766 <INITIAL>{DST_BLST_TLS_IMASK}   { count(); yylval.strval=yytext;
767                                                                 return DST_BLST_TLS_IMASK; }
768 <INITIAL>{DST_BLST_SCTP_IMASK}  { count(); yylval.strval=yytext;
769                                                                 return DST_BLST_SCTP_IMASK; }
770 <INITIAL>{PORT} { count(); yylval.strval=yytext; return PORT; }
771 <INITIAL>{STAT} { count(); yylval.strval=yytext; return STAT; }
772 <INITIAL>{MAXBUFFER}    { count(); yylval.strval=yytext; return MAXBUFFER; }
773 <INITIAL>{SQL_BUFFER_SIZE}      { count(); yylval.strval=yytext; return SQL_BUFFER_SIZE; }
774 <INITIAL>{CHILDREN}     { count(); yylval.strval=yytext; return CHILDREN; }
775 <INITIAL>{SOCKET_WORKERS}       { count(); yylval.strval=yytext; return SOCKET_WORKERS; }
776 <INITIAL>{CHECK_VIA}    { count(); yylval.strval=yytext; return CHECK_VIA; }
777 <INITIAL>{PHONE2TEL}    { count(); yylval.strval=yytext; return PHONE2TEL; }
778 <INITIAL>{MEMLOG}       { count(); yylval.strval=yytext; return MEMLOG; }
779 <INITIAL>{MEMDBG}       { count(); yylval.strval=yytext; return MEMDBG; }
780 <INITIAL>{MEMSUM}       { count(); yylval.strval=yytext; return MEMSUM; }
781 <INITIAL>{MEMSAFETY}    { count(); yylval.strval=yytext; return MEMSAFETY; }
782 <INITIAL>{MEMJOIN}      { count(); yylval.strval=yytext; return MEMJOIN; }
783 <INITIAL>{CORELOG}      { count(); yylval.strval=yytext; return CORELOG; }
784 <INITIAL>{SIP_WARNING}  { count(); yylval.strval=yytext; return SIP_WARNING; }
785 <INITIAL>{USER}         { count(); yylval.strval=yytext; return USER; }
786 <INITIAL>{GROUP}        { count(); yylval.strval=yytext; return GROUP; }
787 <INITIAL>{CHROOT}       { count(); yylval.strval=yytext; return CHROOT; }
788 <INITIAL>{WDIR} { count(); yylval.strval=yytext; return WDIR; }
789 <INITIAL>{MHOMED}       { count(); yylval.strval=yytext; return MHOMED; }
790 <INITIAL>{DISABLE_TCP}  { count(); yylval.strval=yytext; return DISABLE_TCP; }
791 <INITIAL>{TCP_CHILDREN} { count(); yylval.strval=yytext; return TCP_CHILDREN; }
792 <INITIAL>{TCP_ACCEPT_ALIASES}   { count(); yylval.strval=yytext;
793                                                                         return TCP_ACCEPT_ALIASES; }
794 <INITIAL>{TCP_SEND_TIMEOUT}             { count(); yylval.strval=yytext;
795                                                                         return TCP_SEND_TIMEOUT; }
796 <INITIAL>{TCP_CONNECT_TIMEOUT}          { count(); yylval.strval=yytext;
797                                                                         return TCP_CONNECT_TIMEOUT; }
798 <INITIAL>{TCP_CON_LIFETIME}             { count(); yylval.strval=yytext;
799                                                                         return TCP_CON_LIFETIME; }
800 <INITIAL>{TCP_POLL_METHOD}              { count(); yylval.strval=yytext;
801                                                                         return TCP_POLL_METHOD; }
802 <INITIAL>{TCP_MAX_CONNECTIONS}  { count(); yylval.strval=yytext;
803                                                                         return TCP_MAX_CONNECTIONS; }
804 <INITIAL>{TLS_MAX_CONNECTIONS}  { count(); yylval.strval=yytext;
805                                                                         return TLS_MAX_CONNECTIONS; }
806 <INITIAL>{TCP_NO_CONNECT}               { count(); yylval.strval=yytext;
807                                                                         return TCP_NO_CONNECT; }
808 <INITIAL>{TCP_SOURCE_IPV4}              { count(); yylval.strval=yytext;
809                                                                         return TCP_SOURCE_IPV4; }
810 <INITIAL>{TCP_SOURCE_IPV6}              { count(); yylval.strval=yytext;
811                                                                         return TCP_SOURCE_IPV6; }
812 <INITIAL>{TCP_OPT_FD_CACHE}             { count(); yylval.strval=yytext;
813                                                                         return TCP_OPT_FD_CACHE; }
814 <INITIAL>{TCP_OPT_CONN_WQ_MAX}  { count(); yylval.strval=yytext;
815                                                                         return TCP_OPT_CONN_WQ_MAX; }
816 <INITIAL>{TCP_OPT_WQ_MAX}       { count(); yylval.strval=yytext;
817                                                                         return TCP_OPT_WQ_MAX; }
818 <INITIAL>{TCP_OPT_RD_BUF}       { count(); yylval.strval=yytext;
819                                                                         return TCP_OPT_RD_BUF; }
820 <INITIAL>{TCP_OPT_WQ_BLK}       { count(); yylval.strval=yytext;
821                                                                         return TCP_OPT_WQ_BLK; }
822 <INITIAL>{TCP_OPT_BUF_WRITE}    { count(); yylval.strval=yytext;
823                                                                         return TCP_OPT_BUF_WRITE; }
824 <INITIAL>{TCP_OPT_DEFER_ACCEPT} { count(); yylval.strval=yytext;
825                                                                         return TCP_OPT_DEFER_ACCEPT; }
826 <INITIAL>{TCP_OPT_DELAYED_ACK}  { count(); yylval.strval=yytext;
827                                                                         return TCP_OPT_DELAYED_ACK; }
828 <INITIAL>{TCP_OPT_SYNCNT}               { count(); yylval.strval=yytext;
829                                                                         return TCP_OPT_SYNCNT; }
830 <INITIAL>{TCP_OPT_LINGER2}              { count(); yylval.strval=yytext;
831                                                                         return TCP_OPT_LINGER2; }
832 <INITIAL>{TCP_OPT_KEEPALIVE}    { count(); yylval.strval=yytext;
833                                                                         return TCP_OPT_KEEPALIVE; }
834 <INITIAL>{TCP_OPT_KEEPIDLE}             { count(); yylval.strval=yytext;
835                                                                         return TCP_OPT_KEEPIDLE; }
836 <INITIAL>{TCP_OPT_KEEPINTVL}    { count(); yylval.strval=yytext;
837                                                                         return TCP_OPT_KEEPINTVL; }
838 <INITIAL>{TCP_OPT_KEEPCNT}      { count(); yylval.strval=yytext;
839                                                                         return TCP_OPT_KEEPCNT; }
840 <INITIAL>{TCP_OPT_CRLF_PING}    { count(); yylval.strval=yytext;
841                                                                         return TCP_OPT_CRLF_PING; }
842 <INITIAL>{TCP_OPT_ACCEPT_NO_CL} { count(); yylval.strval=yytext;
843                                                                         return TCP_OPT_ACCEPT_NO_CL; }
844 <INITIAL>{TCP_CLONE_RCVBUF}             { count(); yylval.strval=yytext;
845                                                                         return TCP_CLONE_RCVBUF; }
846 <INITIAL>{DISABLE_TLS}  { count(); yylval.strval=yytext; return DISABLE_TLS; }
847 <INITIAL>{ENABLE_TLS}   { count(); yylval.strval=yytext; return ENABLE_TLS; }
848 <INITIAL>{TLSLOG}               { count(); yylval.strval=yytext; return TLS_PORT_NO; }
849 <INITIAL>{TLS_PORT_NO}  { count(); yylval.strval=yytext; return TLS_PORT_NO; }
850 <INITIAL>{TLS_METHOD}   { count(); yylval.strval=yytext; return TLS_METHOD; }
851 <INITIAL>{TLS_VERIFY}   { count(); yylval.strval=yytext; return TLS_VERIFY; }
852 <INITIAL>{TLS_REQUIRE_CERTIFICATE}      { count(); yylval.strval=yytext;
853                                                                                 return TLS_REQUIRE_CERTIFICATE; }
854 <INITIAL>{TLS_CERTIFICATE}      { count(); yylval.strval=yytext;
855                                                                                 return TLS_CERTIFICATE; }
856 <INITIAL>{TLS_PRIVATE_KEY}      { count(); yylval.strval=yytext;
857                                                                                 return TLS_PRIVATE_KEY; }
858 <INITIAL>{TLS_CA_LIST}  { count(); yylval.strval=yytext;
859                                                                                 return TLS_CA_LIST; }
860 <INITIAL>{TLS_HANDSHAKE_TIMEOUT}        { count(); yylval.strval=yytext;
861                                                                                 return TLS_HANDSHAKE_TIMEOUT; }
862 <INITIAL>{TLS_SEND_TIMEOUT}     { count(); yylval.strval=yytext;
863                                                                                 return TLS_SEND_TIMEOUT; }
864 <INITIAL>{DISABLE_SCTP} { count(); yylval.strval=yytext; return DISABLE_SCTP;}
865 <INITIAL>{ENABLE_SCTP}  { count(); yylval.strval=yytext; return ENABLE_SCTP;}
866 <INITIAL>{SCTP_CHILDREN}        { count(); yylval.strval=yytext;
867                                                                                 return SCTP_CHILDREN; }
868 <INITIAL>{SERVER_SIGNATURE}     { count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
869 <INITIAL>{SERVER_HEADER}        { count(); yylval.strval=yytext; return SERVER_HEADER; }
870 <INITIAL>{USER_AGENT_HEADER}    { count(); yylval.strval=yytext; return USER_AGENT_HEADER; }
871 <INITIAL>{REPLY_TO_VIA} { count(); yylval.strval=yytext; return REPLY_TO_VIA; }
872 <INITIAL>{ADVERTISED_ADDRESS}   {       count(); yylval.strval=yytext;
873                                                                         return ADVERTISED_ADDRESS; }
874 <INITIAL>{ADVERTISED_PORT}              {       count(); yylval.strval=yytext;
875                                                                         return ADVERTISED_PORT; }
876 <INITIAL>{DISABLE_CORE}         {       count(); yylval.strval=yytext;
877                                                                         return DISABLE_CORE; }
878 <INITIAL>{OPEN_FD_LIMIT}                {       count(); yylval.strval=yytext;
879                                                                         return OPEN_FD_LIMIT; }
880 <INITIAL>{SHM_MEM_SZ}           {       count(); yylval.strval=yytext;
881                                                                         return SHM_MEM_SZ; }
882 <INITIAL>{SHM_FORCE_ALLOC}              {       count(); yylval.strval=yytext;
883                                                                         return SHM_FORCE_ALLOC; }
884 <INITIAL>{MLOCK_PAGES}          {       count(); yylval.strval=yytext;
885                                                                         return MLOCK_PAGES; }
886 <INITIAL>{REAL_TIME}            {       count(); yylval.strval=yytext;
887                                                                         return REAL_TIME; }
888 <INITIAL>{RT_PRIO}              {       count(); yylval.strval=yytext;
889                                                                         return RT_PRIO; }
890 <INITIAL>{RT_POLICY}            {       count(); yylval.strval=yytext;
891                                                                         return RT_POLICY; }
892 <INITIAL>{RT_TIMER1_PRIO}               {       count(); yylval.strval=yytext;
893                                                                         return RT_TIMER1_PRIO; }
894 <INITIAL>{RT_TIMER1_POLICY}             {       count(); yylval.strval=yytext;
895                                                                         return RT_TIMER1_POLICY; }
896 <INITIAL>{RT_TIMER2_PRIO}               {       count(); yylval.strval=yytext;
897                                                                         return RT_TIMER2_PRIO; }
898 <INITIAL>{RT_TIMER2_POLICY}             {       count(); yylval.strval=yytext;
899                                                                         return RT_TIMER2_POLICY; }
900 <INITIAL>{MCAST_LOOPBACK}               {       count(); yylval.strval=yytext;
901                                                                         return MCAST_LOOPBACK; }
902 <INITIAL>{MCAST_TTL}            {       count(); yylval.strval=yytext;
903                                                                         return MCAST_TTL; }
904 <INITIAL>{TOS}                  {       count(); yylval.strval=yytext;
905                                                                         return TOS; }
906 <INITIAL>{PMTU_DISCOVERY}               {       count(); yylval.strval=yytext;
907                                                                         return PMTU_DISCOVERY; }
908 <INITIAL>{KILL_TIMEOUT}                 {       count(); yylval.strval=yytext;
909                                                                         return KILL_TIMEOUT; }
910 <INITIAL>{MAX_WLOOPS}                   {       count(); yylval.strval=yytext;
911                                                                         return MAX_WLOOPS; }
912 <INITIAL>{PVBUFSIZE}                    {       count(); yylval.strval=yytext;
913                                                                         return PVBUFSIZE; }
914 <INITIAL>{PVBUFSLOTS}                   {       count(); yylval.strval=yytext;
915                                                                         return PVBUFSLOTS; }
916 <INITIAL>{HTTP_REPLY_PARSE}             {       count(); yylval.strval=yytext;
917                                                                         return HTTP_REPLY_PARSE; }
918 <INITIAL>{VERSION_TABLE_CFG}  { count(); yylval.strval=yytext; return VERSION_TABLE_CFG;}
919 <INITIAL>{SERVER_ID}  { count(); yylval.strval=yytext; return SERVER_ID;}
920 <INITIAL>{LATENCY_LOG}  { count(); yylval.strval=yytext; return LATENCY_LOG;}
921 <INITIAL>{MSG_TIME}  { count(); yylval.strval=yytext; return MSG_TIME;}
922 <INITIAL>{LATENCY_LIMIT_DB}  { count(); yylval.strval=yytext; return LATENCY_LIMIT_DB;}
923 <INITIAL>{LATENCY_LIMIT_ACTION}  { count(); yylval.strval=yytext; return LATENCY_LIMIT_ACTION;}
924 <INITIAL>{CFG_DESCRIPTION}      { count(); yylval.strval=yytext; return CFG_DESCRIPTION; }
925 <INITIAL>{LOADMODULE}   { count(); yylval.strval=yytext; return LOADMODULE; }
926 <INITIAL>{LOADPATH}             { count(); yylval.strval=yytext; return LOADPATH; }
927 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
928
929 <INITIAL>{EQUAL}        { count(); return EQUAL; }
930 <INITIAL>{ADDEQ}          { count(); return ADDEQ; }
931 <INITIAL>{EQUAL_T}      { count(); return EQUAL_T; }
932 <INITIAL>{GT}   { count(); return GT; }
933 <INITIAL>{LT}   { count(); return LT; }
934 <INITIAL>{GTE}  { count(); return GTE; }
935 <INITIAL>{LTE}  { count(); return LTE; }
936 <INITIAL>{DIFF} { count(); return DIFF; }
937 <INITIAL>{MATCH}        { count(); return MATCH; }
938 <INITIAL>{NOT}          { count(); return NOT; }
939 <INITIAL>{LOG_AND}      { count(); return LOG_AND; }
940 <INITIAL>{BIN_AND}      { count(); return BIN_AND; }
941 <INITIAL>{LOG_OR}       { count(); return LOG_OR;  }
942 <INITIAL>{BIN_OR}       { count(); return BIN_OR;  }
943 <INITIAL>{BIN_NOT}      { count(); return BIN_NOT;  }
944 <INITIAL>{BIN_XOR}      { count(); return BIN_XOR;  }
945 <INITIAL>{BIN_LSHIFT}   { count(); return BIN_LSHIFT;  }
946 <INITIAL>{BIN_RSHIFT}   { count(); return BIN_RSHIFT;  }
947 <INITIAL>{PLUS}         { count(); return PLUS; }
948 <INITIAL>{MINUS}        { count(); return MINUS; }
949 <INITIAL>{MODULO}       { count(); return MODULO; }
950 <INITIAL>{STRLEN}       { count(); return STRLEN; }
951 <INITIAL>{STREMPTY}     { count(); return STREMPTY; }
952 <INITIAL>{DEFINED}      { count(); return DEFINED; }
953 <INITIAL>{STREQ}        { count(); return STREQ; }
954 <INITIAL>{INTEQ}        { count(); return INTEQ; }
955 <INITIAL>{STRDIFF}      { count(); return STRDIFF; }
956 <INITIAL>{INTDIFF}      { count(); return INTDIFF; }
957 <INITIAL>{INTCAST}      { count(); return INTCAST; }
958 <INITIAL>{STRCAST}      { count(); return STRCAST; }
959
960 <INITIAL>{SELECT_MARK}  { count(); state = SELECT_S; BEGIN(SELECT); return SELECT_MARK; }
961 <SELECT>{ID}            { count(); addstr(&s_buf, yytext, yyleng);
962                           yylval.strval=s_buf.s;
963                           memset(&s_buf, 0, sizeof(s_buf));
964                           return ID;
965                         }
966 <SELECT>{DOT}           { count(); return DOT; }
967 <SELECT>{LBRACK}        { count(); return LBRACK; }
968 <SELECT>{RBRACK}        { count(); return RBRACK; }
969 <SELECT>{DECNUMBER}     { count(); yylval.intval=atoi(yytext);
970                                                 yy_number_str=yytext; return NUMBER; }
971 <SELECT>{HEXNUMBER}     { count(); yylval.intval=(int)strtol(yytext, 0, 16);
972                                                 yy_number_str=yytext; return NUMBER; }
973 <SELECT>{OCTNUMBER}     { count(); yylval.intval=(int)strtol(yytext, 0, 8);
974                                                 yy_number_str=yytext; return NUMBER; }
975 <SELECT>{BINNUMBER}     { count(); yylval.intval=(int)strtol(yytext, 0, 2);
976                                                 yy_number_str=yytext; return NUMBER; }
977
978
979 <INITIAL>{ATTR_MARK}    { count(); state = ATTR_S; BEGIN(ATTR);
980                                                         return ATTR_MARK; }
981 <ATTR>{ATTR_FROM}       { count(); return ATTR_FROM; }
982 <ATTR>{ATTR_TO}         { count(); return ATTR_TO; }
983 <ATTR>{ATTR_FROMURI}    { count(); return ATTR_FROMURI; }
984 <ATTR>{ATTR_TOURI}      { count(); return ATTR_TOURI; }
985 <ATTR>{ATTR_FROMUSER}   { count(); return ATTR_FROMUSER; }
986 <ATTR>{ATTR_TOUSER}     { count(); return ATTR_TOUSER; }
987 <ATTR>{ATTR_FROMDOMAIN} { count(); return ATTR_FROMDOMAIN; }
988 <ATTR>{ATTR_TODOMAIN}   { count(); return ATTR_TODOMAIN; }
989 <ATTR>{ATTR_GLOBAL}     { count(); return ATTR_GLOBAL; }
990 <ATTR>{DOT}             { count(); return DOT; }
991 <ATTR>{LBRACK}          { count(); return LBRACK; }
992 <ATTR>{RBRACK}          { count(); return RBRACK; }
993 <ATTR>{STAR}                    { count(); return STAR; }
994 <ATTR>{DECNUMBER}               { count(); yylval.intval=atoi(yytext);
995                                                         yy_number_str=yytext; return NUMBER; }
996 <ATTR>{ID}                              { count(); addstr(&s_buf, yytext, yyleng);
997                                                         yylval.strval=s_buf.s;
998                                                         memset(&s_buf, 0, sizeof(s_buf));
999                                                         state = INITIAL_S;
1000                                                         BEGIN(INITIAL);
1001                                                         return ID;
1002                                                 }
1003
1004 <INITIAL>{VAR_MARK}{LPAREN}     {
1005                                                                 switch(sr_cfg_compat){
1006                                                                         case SR_COMPAT_SER:
1007                                                                                 state=ATTR_S; BEGIN(ATTR);
1008                                                                                 yyless(1);
1009                                                                                 count();
1010                                                                                 return ATTR_MARK;
1011                                                                                 break;
1012                                                                         case SR_COMPAT_KAMAILIO:
1013                                                                         case SR_COMPAT_MAX:
1014                                                                         default:
1015                                                                                 state = PVAR_P_S; BEGIN(PVAR_P);
1016                                                                                 p_nest=1; yymore();
1017                                                                                 break;
1018                                                                 }
1019                                                         }
1020         /* eat everything between 2 () and return PVAR token and a string
1021            containing everything (including $ and ()) */
1022 <PVAR_P>{RPAREN}                        {       p_nest--;
1023                                                                 if (p_nest==0){
1024                                                                         count();
1025                                                                         addstr(&s_buf, yytext, yyleng);
1026                                                                         yylval.strval=s_buf.s;
1027                                                                         memset(&s_buf, 0, sizeof(s_buf));
1028                                                                         state=INITIAL_S;
1029                                                                         BEGIN(INITIAL);
1030                                                                         return PVAR;
1031                                                                 }
1032                                                                 yymore();
1033                                                         }
1034 <PVAR_P>{LPAREN}                        { p_nest++; yymore(); }
1035 <PVAR_P>.                                       { yymore(); }
1036
1037 <PVARID>{ID}|'\.'                       {yymore(); }
1038 <PVARID>{LPAREN}                        {       state = PVAR_P_S; BEGIN(PVAR_P);
1039                                                                 p_nest=1; yymore(); }
1040 <PVARID>{CR}|{EAT_ABLE}|.       {       yyless(yyleng-1);
1041                                                                 count();
1042                                                                 addstr(&s_buf, yytext, yyleng);
1043                                                                 yylval.strval=s_buf.s;
1044                                                                 memset(&s_buf, 0, sizeof(s_buf));
1045                                                                 state=INITIAL_S;
1046                                                                 BEGIN(INITIAL);
1047                                                                 return PVAR;
1048                                                         }
1049
1050         /* if found retcode => it's a built-in pvar */
1051 <INITIAL>{RETCODE}                      { count(); yylval.strval=yytext; return PVAR; }
1052
1053 <INITIAL>{VAR_MARK}                     {
1054                                                                 switch(sr_cfg_compat){
1055                                                                         case SR_COMPAT_SER:
1056                                                                                 count();
1057                                                                                 state=ATTR_S; BEGIN(ATTR);
1058                                                                                 return ATTR_MARK;
1059                                                                                 break;
1060                                                                         case SR_COMPAT_KAMAILIO:
1061                                                                                 state=PVARID_S; BEGIN(PVARID);
1062                                                                                 yymore();
1063                                                                                 break;
1064                                                                         case SR_COMPAT_MAX:
1065                                                                         default: 
1066                                                                                 state=AVP_PVAR_S; BEGIN(AVP_PVAR);
1067                                                                                 yymore();
1068                                                                                 break;
1069                                                                 }
1070                                                         }
1071         /* avp prefix detected -> go to avp mode */
1072 <AVP_PVAR>{AVP_PREF}            |
1073 <AVP_PVAR>{ID}{LBRACK}          { state = ATTR_S; BEGIN(ATTR); yyless(1); count();
1074                                                           return ATTR_MARK; }
1075 <AVP_PVAR>{ID}{LPAREN}          { state = PVAR_P_S; p_nest=1; BEGIN(PVAR_P);
1076                                                                 yymore(); }
1077 <AVP_PVAR>{ID}                          {       count(); addstr(&s_buf, yytext, yyleng);
1078                                                                 yylval.strval=s_buf.s;
1079                                                                 memset(&s_buf, 0, sizeof(s_buf));
1080                                                                 state = INITIAL_S;
1081                                                                 BEGIN(INITIAL);
1082                                                                 return AVP_OR_PVAR;
1083                                                         }
1084
1085 <INITIAL>{IPV6ADDR}             { count(); yylval.strval=yytext; return IPV6ADDR; }
1086 <INITIAL>{DECNUMBER}    { count(); yylval.intval=atoi(yytext);
1087                                                                 yy_number_str=yytext; return NUMBER; }
1088 <INITIAL>{HEXNUMBER}    { count(); yylval.intval=(int)strtol(yytext, 0, 16);
1089                                                         yy_number_str=yytext; return NUMBER; }
1090 <INITIAL>{OCTNUMBER}    { count(); yylval.intval=(int)strtol(yytext, 0, 8);
1091                                                         yy_number_str=yytext; return NUMBER; }
1092 <INITIAL>{BINNUMBER}    { count(); yylval.intval=(int)strtol(yytext, 0, 2);
1093                                                         yy_number_str=yytext; return NUMBER; }
1094 <INITIAL>{YES}                  { count(); yylval.intval=1;
1095                                                         yy_number_str=yytext; return NUMBER; }
1096 <INITIAL>{NO}                   { count(); yylval.intval=0;
1097                                                         yy_number_str=yytext; return NUMBER; }
1098 <INITIAL>{TCP}                  { count(); return TCP; }
1099 <INITIAL>{UDP}                  { count(); return UDP; }
1100 <INITIAL>{TLS}                  { count(); return TLS; }
1101 <INITIAL>{SCTP}                 { count(); return SCTP; }
1102 <INITIAL>{WS}                   { count(); return WS; }
1103 <INITIAL>{WSS}                  { count(); return WSS; }
1104 <INITIAL>{INET}                 { count(); yylval.intval=AF_INET;
1105                                                         yy_number_str=yytext; return NUMBER; }
1106 <INITIAL>{INET6}                { count();
1107                                                 yylval.intval=AF_INET6;
1108                                                 yy_number_str=yytext;
1109                                                 return NUMBER; }
1110 <INITIAL>{SSLv23}               { count(); yylval.strval=yytext; return SSLv23; }
1111 <INITIAL>{SSLv2}                { count(); yylval.strval=yytext; return SSLv2; }
1112 <INITIAL>{SSLv3}                { count(); yylval.strval=yytext; return SSLv3; }
1113 <INITIAL>{TLSv1}                { count(); yylval.strval=yytext; return TLSv1; }
1114
1115 <INITIAL>{COMMA}                { count(); return COMMA; }
1116 <INITIAL>{SEMICOLON}    { count(); return SEMICOLON; }
1117 <INITIAL>{COLON}        { count(); return COLON; }
1118 <INITIAL>{STAR}         { count(); return STAR; }
1119 <INITIAL>{RPAREN}       { count(); return RPAREN; }
1120 <INITIAL>{LPAREN}       { count(); return LPAREN; }
1121 <INITIAL>{LBRACE}       { count(); return LBRACE; }
1122 <INITIAL>{RBRACE}       { count(); return RBRACE; }
1123 <INITIAL>{LBRACK}       { count(); return LBRACK; }
1124 <INITIAL>{RBRACK}       { count(); return RBRACK; }
1125 <INITIAL>{SLASH}        { count(); return SLASH; }
1126 <INITIAL>{DOT}          { count(); return DOT; }
1127 <INITIAL>\\{CR}         {count(); } /* eat the escaped CR */
1128 <INITIAL>{CR}           { count();/* return CR;*/ }
1129 <INITIAL>{EVENT_RT_NAME}        { count();
1130                                                                 addstr(&s_buf, yytext, yyleng);
1131                                                                 yylval.strval=s_buf.s;
1132                                                                 memset(&s_buf, 0, sizeof(s_buf));
1133                                                                 return EVENT_RT_NAME; }
1134
1135
1136 <INITIAL,SELECT>{QUOTES} { count(); old_initial = YY_START; 
1137                                                         old_state = state; state=STRING_S;
1138                                                         BEGIN(STRING1); }
1139 <INITIAL>{TICK} { count(); old_initial = YY_START; old_state = state;
1140                                         state=STRING_S; BEGIN(STRING2); }
1141
1142
1143 <STRING1>{QUOTES} { count_more(); 
1144                                                 yytext[yyleng-1]=0; yyleng--;
1145                                                 addstr(&s_buf, yytext, yyleng);
1146                                                 state=STR_BETWEEN_S;
1147                                                 BEGIN(STR_BETWEEN);
1148                                         }
1149 <STRING2>{TICK}  { count_more(); state=old_state; BEGIN(old_initial);
1150                                                 yytext[yyleng-1]=0; yyleng--;
1151                                                 addstr(&s_buf, yytext, yyleng);
1152                                                 r = pp_subst_run(&s_buf.s);
1153                                                 yylval.strval=s_buf.s;
1154                                                 memset(&s_buf, 0, sizeof(s_buf));
1155                                                 return STRING;
1156                                         }
1157 <STRING2>.|{EAT_ABLE}|{CR}      { yymore(); }
1158
1159 <STRING1>\\n            { count_more(); addchar(&s_buf, '\n'); }
1160 <STRING1>\\r            { count_more(); addchar(&s_buf, '\r'); }
1161 <STRING1>\\a            { count_more(); addchar(&s_buf, '\a'); }
1162 <STRING1>\\t            { count_more(); addchar(&s_buf, '\t'); }
1163 <STRING1>\\{QUOTES}     { count_more(); addchar(&s_buf, '"');  }
1164 <STRING1>\\\\           { count_more(); addchar(&s_buf, '\\'); }
1165 <STRING1>\\x{HEX}{1,2}  { count_more(); addchar(&s_buf,
1166                                                                                         (char)strtol(yytext+2, 0, 16)); }
1167  /* don't allow \[0-7]{1}, it will eat the backreferences from
1168     subst_uri if allowed (although everybody should use '' in subt_uri) */
1169 <STRING1>\\[0-7]{2,3}   { count_more(); addchar(&s_buf,
1170                                                                                         (char)strtol(yytext+1, 0, 8));  }
1171 <STRING1>\\{CR}         { count_more(); } /* eat escaped CRs */
1172 <STRING1>.|{EAT_ABLE}|{CR}      { count_more(); addchar(&s_buf, *yytext); }
1173
1174 <STR_BETWEEN>{EAT_ABLE}|{CR}    { count_ignore(); }
1175 <STR_BETWEEN>{QUOTES}                   { count_more(); state=STRING_S;
1176                                                                   BEGIN(STRING1);}
1177 <STR_BETWEEN>.                                  {       
1178                                                                         yyless(0); /* reparse it */
1179                                                                         /* ignore the whitespace now that is
1180                                                                           counted, return saved string value */
1181                                                                         state=old_state; BEGIN(old_initial);
1182                                                                         r = pp_subst_run(&s_buf.s);
1183                                                                         yylval.strval=s_buf.s;
1184                                                                         memset(&s_buf, 0, sizeof(s_buf));
1185                                                                         return STRING;
1186                                                                 }
1187
1188 <INITIAL,COMMENT>{COM_START}    { count(); comment_nest++; state=COMMENT_S;
1189                                                                                 BEGIN(COMMENT); }
1190 <COMMENT>{COM_END}                              { count(); comment_nest--;
1191                                                                                 if (comment_nest==0){
1192                                                                                         state=INITIAL_S;
1193                                                                                         BEGIN(INITIAL);
1194                                                                                 }
1195                                                                 }
1196 <COMMENT>.|{EAT_ABLE}|{CR}                              { count(); };
1197
1198 <INITIAL>{COM_LINE}!{SER_CFG}{CR}               { count();
1199                                                                                         sr_cfg_compat=SR_COMPAT_SER;}
1200 <INITIAL>{COM_LINE}!{KAMAILIO_CFG}{CR}  { count(); 
1201                                                                                         sr_cfg_compat=SR_COMPAT_KAMAILIO;}
1202 <INITIAL>{COM_LINE}!{MAXCOMPAT_CFG}{CR} { count(); 
1203                                                                                                 sr_cfg_compat=SR_COMPAT_MAX;}
1204
1205 <INITIAL>{PREP_START}{DEFINE}{EAT_ABLE}+        {       count(); pp_define_set_type(0);
1206                                                                                         state = DEFINE_S; BEGIN(DEFINE_ID); }
1207 <INITIAL>{PREP_START}{TRYDEF}{EAT_ABLE}+        {       count(); pp_define_set_type(1);
1208                                                                                         state = DEFINE_S; BEGIN(DEFINE_ID); }
1209 <INITIAL>{PREP_START}{REDEF}{EAT_ABLE}+ {       count(); pp_define_set_type(2);
1210                                                                                         state = DEFINE_S; BEGIN(DEFINE_ID); }
1211 <DEFINE_ID>{ID}                 {       count();
1212                                                                         if (pp_define(yyleng, yytext)) return 1;
1213                                                                         state = DEFINE_EOL_S; BEGIN(DEFINE_EOL); }
1214 <DEFINE_EOL>{EAT_ABLE}                  {       count(); }
1215 <DEFINE_EOL>{CR}                                {       count();
1216                                                                         state = INITIAL; BEGIN(INITIAL); }
1217 <DEFINE_EOL>.                   {       count();
1218                                                                         addstr(&s_buf, yytext, yyleng);
1219                                                                         state = DEFINE_DATA_S; BEGIN(DEFINE_DATA); }
1220 <DEFINE_DATA>\\{CR}             {       count(); } /* eat the escaped CR */
1221 <DEFINE_DATA>{CR}               {       count();
1222                                                         if (pp_define_set(strlen(s_buf.s), s_buf.s)) return 1;
1223                                                         memset(&s_buf, 0, sizeof(s_buf));
1224                                                         state = INITIAL; BEGIN(INITIAL); }
1225 <DEFINE_DATA>.          {       count();
1226                                                         addstr(&s_buf, yytext, yyleng); }
1227
1228 <INITIAL>{PREP_START}{SUBST}    { count();  return SUBST;}
1229 <INITIAL>{PREP_START}{SUBSTDEF} { count();  return SUBSTDEF;}
1230 <INITIAL>{PREP_START}{SUBSTDEFS}        { count();  return SUBSTDEFS;}
1231
1232 <INITIAL,IFDEF_SKIP>{PREP_START}{IFDEF}{EAT_ABLE}+    { count();
1233                                                                 if (pp_ifdef_type(1)) return 1;
1234                                                                 state = IFDEF_S; BEGIN(IFDEF_ID); }
1235 <INITIAL,IFDEF_SKIP>{PREP_START}{IFNDEF}{EAT_ABLE}+    { count();
1236                                                                 if (pp_ifdef_type(0)) return 1;
1237                                                                 state = IFDEF_S; BEGIN(IFDEF_ID); }
1238 <IFDEF_ID>{ID}                { count();
1239                                 pp_ifdef_var(yyleng, yytext);
1240                                 state = IFDEF_EOL_S; BEGIN(IFDEF_EOL); }
1241 <IFDEF_EOL>{EAT_ABLE}*{CR}    { count(); pp_ifdef(); }
1242
1243 <INITIAL,IFDEF_SKIP>{PREP_START}{ELSE}{EAT_ABLE}*{CR}    { count(); pp_else(); }
1244
1245 <INITIAL,IFDEF_SKIP>{PREP_START}{ENDIF}{EAT_ABLE}*{CR}    { count();
1246                                                                                                                         pp_endif(); }
1247
1248  /* we're in an ifdef that evaluated to false -- throw it away */
1249 <IFDEF_SKIP>.|{CR}    { count(); }
1250
1251  /* this is split so the shebangs match more, giving them priority */
1252 <INITIAL>{COM_LINE}        { count(); state = LINECOMMENT_S;
1253                                                                 BEGIN(LINECOMMENT); }
1254 <LINECOMMENT>.*{CR}        { count(); state = INITIAL_S; BEGIN(INITIAL); }
1255
1256 <INITIAL>{ID}           {       if ((sdef = pp_define_get(yyleng, yytext))!=NULL) {
1257                                                         for (r=sdef->len-1; r>=0; r--)
1258                                                                 unput(sdef->s[r]); /* reverse order */
1259                                                 } else {
1260                                                         count();
1261                                                         addstr(&s_buf, yytext, yyleng);
1262                                                         yylval.strval=s_buf.s;
1263                                                         memset(&s_buf, 0, sizeof(s_buf));
1264                                                         return ID;
1265                                                 }
1266                                         }
1267 <INITIAL>{NUM_ID}                       { count(); addstr(&s_buf, yytext, yyleng);
1268                                                                         yylval.strval=s_buf.s;
1269                                                                         memset(&s_buf, 0, sizeof(s_buf));
1270                                                                         return NUM_ID; }
1271
1272 <SELECT>.               { unput(yytext[0]); state = INITIAL_S; BEGIN(INITIAL); } /* Rescan the token in INITIAL state */
1273
1274 <INCLF>[ \t]*      /* eat the whitespace */
1275 <INCLF>[^ \t\r\n]+   { /* get the include file name */
1276                                 memset(&s_buf, 0, sizeof(s_buf));
1277                                 addstr(&s_buf, yytext, yyleng);
1278                                 r = pp_subst_run(&s_buf.s);
1279                                 if(sr_push_yy_state(s_buf.s, 0)<0)
1280                                 {
1281                                         LOG(L_CRIT, "error at %s line %d\n", (finame)?finame:"cfg", line);
1282                                         exit(-1);
1283                                 }
1284                                 memset(&s_buf, 0, sizeof(s_buf));
1285                                 BEGIN(INITIAL);
1286 }
1287
1288 <IMPTF>[ \t]*      /* eat the whitespace */
1289 <IMPTF>[^ \t\r\n]+   { /* get the import file name */
1290                                 memset(&s_buf, 0, sizeof(s_buf));
1291                                 addstr(&s_buf, yytext, yyleng);
1292                                 r = pp_subst_run(&s_buf.s);
1293                                 if(sr_push_yy_state(s_buf.s, 1)<0)
1294                                 {
1295                                         LOG(L_CRIT, "error at %s line %d\n", (finame)?finame:"cfg", line);
1296                                         exit(-1);
1297                                 }
1298                                 memset(&s_buf, 0, sizeof(s_buf));
1299                                 BEGIN(INITIAL);
1300 }
1301
1302
1303 <<EOF>>                                                 {
1304                                                                         switch(state){
1305                                                                                 case STR_BETWEEN_S:
1306                                                                                         state=old_state;
1307                                                                                         BEGIN(old_initial);
1308                                                                                         r = pp_subst_run(&s_buf.s);
1309                                                                                         yylval.strval=s_buf.s;
1310                                                                                         memset(&s_buf, 0, sizeof(s_buf));
1311                                                                                         return STRING;
1312                                                                                 case STRING_S:
1313                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
1314                                                                                                                 " unclosed string\n");
1315                                                                                         if (s_buf.s){
1316                                                                                                 pkg_free(s_buf.s);
1317                                                                                                 memset(&s_buf, 0,
1318                                                                                                                         sizeof(s_buf));
1319                                                                                         }
1320                                                                                         break;
1321                                                                                 case COMMENT_S:
1322                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
1323                                                                                                                 " %d comments open\n", comment_nest);
1324                                                                                         break;
1325                                                                                 case COMMENT_LN_S:
1326                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF:"
1327                                                                                                                 "comment line open\n");
1328                                                                                         break;
1329                                                                                 case  ATTR_S:
1330                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF"
1331                                                                                                         " while parsing"
1332                                                                                                         " avp name\n");
1333                                                                                         break;
1334                                                                                 case PVARID_S:
1335                                                                                         p_nest=0;
1336                                                                                 case PVAR_P_S: 
1337                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF"
1338                                                                                                         " while parsing pvar name"
1339                                                                                                         " (%d paranthesis open)\n",
1340                                                                                                         p_nest);
1341                                                                                         break;
1342                                                                                 case AVP_PVAR_S:
1343                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF"
1344                                                                                                         " while parsing"
1345                                                                                                         " avp or pvar name\n");
1346                                                                         }
1347                                                                         if(sr_pop_yy_state()<0)
1348                                                                                 return 0;
1349                                                                 }
1350
1351 %%
1352
1353
1354 static char* addchar(struct str_buf* dst, char c)
1355 {
1356         return addstr(dst, &c, 1);
1357 }
1358
1359
1360
1361 static char* addstr(struct str_buf* dst_b, char* src, int len)
1362 {
1363         char *tmp;
1364         unsigned size;
1365         unsigned used;
1366
1367         if (dst_b->left<(len+1)){
1368                 used=(unsigned)(dst_b->crt-dst_b->s);
1369                 size=used+len+1;
1370                 /* round up to next multiple */
1371                 size+= STR_BUF_ALLOC_UNIT-size%STR_BUF_ALLOC_UNIT;
1372                 tmp=pkg_malloc(size);
1373                 if (tmp==0) goto error;
1374                 if (dst_b->s){
1375                         memcpy(tmp, dst_b->s, used);
1376                         pkg_free(dst_b->s);
1377                 }
1378                 dst_b->s=tmp;
1379                 dst_b->crt=dst_b->s+used;
1380                 dst_b->left=size-used;
1381         }
1382         memcpy(dst_b->crt, src, len);
1383         dst_b->crt+=len;
1384         *(dst_b->crt)=0;
1385         dst_b->left-=len;
1386
1387         return dst_b->s;
1388 error:
1389         LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
1390         LOG(L_CRIT, "ERROR:lex:addstr: try to increase pkg size with"
1391                                         " -M parameter\n");
1392         exit(-1);
1393 }
1394
1395
1396
1397 /** helper function for count_*(). */
1398 static void count_lc(int* l, int* c)
1399 {
1400         int i;
1401         for (i=0; i<yyleng;i++){
1402                 if (yytext[i]=='\n'){
1403                         (*l)++;
1404                         (*c)=1;
1405                 }else if (yytext[i]=='\t'){
1406                         (*c)++;
1407                         /*(*c)+=8 -((*c)%8);*/
1408                 }else{
1409                         (*c)++;
1410                 }
1411         }
1412 }
1413
1414
1415
1416 /* helper function */
1417 static void count_restore_ignored()
1418 {
1419         if (ign_lines) /* ignored line(s) => column has changed */
1420                 column=ign_columns;
1421         else
1422                 column+=ign_columns;
1423         line+=ign_lines;
1424         ign_lines=ign_columns=0;
1425 }
1426
1427
1428
1429 /** count/record position for stuff added to the current token. */
1430 static void count_more()
1431 {
1432         count_restore_ignored();
1433         count_lc(&line, &column);
1434 }
1435
1436
1437
1438 /** count/record position for a new token. */
1439 static void count()
1440 {
1441         count_restore_ignored();
1442         startline=line;
1443         startcolumn=column;
1444         count_more();
1445 }
1446
1447
1448
1449 /** record discarded stuff (not contained in the token) so that
1450     the next token position can be adjusted properly*/
1451 static void count_ignore()
1452 {
1453         count_lc(&ign_lines, &ign_columns);
1454 }
1455
1456
1457 /* replacement yywrap, removes libfl dependency */
1458 int yywrap()
1459 {
1460         return 1;
1461 }
1462
1463 static int sr_push_yy_state(char *fin, int mode)
1464 {
1465         struct sr_yy_fname *fn = NULL;
1466         FILE *fp = NULL;
1467         char *x = NULL;
1468         char *newf = NULL;
1469 #define MAX_INCLUDE_FNAME       128
1470         char fbuf[MAX_INCLUDE_FNAME];
1471         int i, j, l;
1472         char *tmpfiname = 0;
1473
1474         if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
1475         {
1476                 LOG(L_CRIT, "too many includes\n");
1477                 return -1;
1478         }
1479         l = strlen(fin);
1480         if(l>=MAX_INCLUDE_FNAME)
1481         {
1482                 LOG(L_CRIT, "included file name too long: %s\n", fin);
1483                 return -1;
1484         }
1485         if(fin[0]!='"' || fin[l-1]!='"')
1486         {
1487                 LOG(L_CRIT, "included file name must be between quotes: %s\n", fin);
1488                 return -1;
1489         }
1490         j = 0;
1491         for(i=1; i<l-1; i++)
1492         {
1493                 switch(fin[i]) {
1494                         case '\\':
1495                                 if(i+1==l-1)
1496                                 {
1497                                         LOG(L_CRIT, "invalid escape at %d in included file name: %s\n", i, fin);
1498                                         return -1;
1499                                 }
1500                                 i++;
1501                                 switch(fin[i]) {
1502                                         case 't':
1503                                                 fbuf[j++] = '\t';
1504                                         break;
1505                                         case 'n':
1506                                                 fbuf[j++] = '\n';
1507                                         break;
1508                                         case 'r':
1509                                                 fbuf[j++] = '\r';
1510                                         break;
1511                                         default:
1512                                                 fbuf[j++] = fin[i];
1513                                 }
1514                         break;
1515                         default:
1516                                 fbuf[j++] = fin[i];
1517                 }
1518         }
1519         if(j==0)
1520         {
1521                 LOG(L_CRIT, "invalid included file name: %s\n", fin);
1522                 return -1;
1523         }
1524         fbuf[j] = '\0';
1525
1526         fp = fopen(fbuf, "r" );
1527
1528         if ( ! fp )
1529         {
1530                 tmpfiname = (finame==0)?cfg_file:finame;
1531                 if(tmpfiname==0 || fbuf[0]=='/')
1532                 {
1533                         if(mode==0)
1534                         {
1535                                 LOG(L_CRIT, "cannot open included file: %s\n", fin);
1536                                 return -1;
1537                         } else {
1538                                 LOG(L_DBG, "importing file ignored: %s\n", fin);
1539                                 return 0;
1540                         }
1541                 }
1542                 x = strrchr(tmpfiname, '/');
1543                 if(x==NULL)
1544                 {
1545                         /* nothing else to try */
1546                         if(mode==0)
1547                         {
1548                                 LOG(L_CRIT, "cannot open included file: %s\n", fin);
1549                                 return -1;
1550                         } else {
1551                                 LOG(L_DBG, "importing file ignored: %s\n", fin);
1552                                 return 0;
1553                         }
1554                 }
1555
1556                 newf = (char*)pkg_malloc(x-tmpfiname+strlen(fbuf)+2);
1557                 if(newf==0)
1558                 {
1559                         LOG(L_CRIT, "no more pkg\n");
1560                         return -1;
1561                 }
1562                 newf[0] = '\0';
1563                 strncat(newf, tmpfiname, x-tmpfiname);
1564                 strcat(newf, "/");
1565                 strcat(newf, fbuf);
1566
1567                 fp = fopen(newf, "r" );
1568                 if ( fp==NULL )
1569                 {
1570                         pkg_free(newf);
1571                         if(mode==0)
1572                         {
1573                                 LOG(L_CRIT, "cannot open included file: %s (%s)\n", fbuf, newf);
1574                                 return -1;
1575                         } else {
1576                                 LOG(L_DBG, "importing file ignored: %s (%s)\n", fbuf, newf);
1577                                 return 0;
1578                         }
1579                 }
1580                 LOG(L_DBG, "including file: %s (%s)\n", fbuf, newf);
1581         } else {
1582                 newf = fbuf;
1583         }
1584
1585         include_stack[include_stack_ptr].state = YY_CURRENT_BUFFER;
1586         include_stack[include_stack_ptr].line = line;
1587         include_stack[include_stack_ptr].column = column;
1588         include_stack[include_stack_ptr].startline = startline;
1589         include_stack[include_stack_ptr].startcolumn = startcolumn;
1590         include_stack[include_stack_ptr].finame = finame;
1591         include_stack_ptr++;
1592
1593         line=1;
1594         column=1;
1595         startline=1;
1596         startcolumn=1;
1597
1598         yyin = fp;
1599
1600         /* make a copy in PKG if does not exist */
1601         fn = sr_yy_fname_list;
1602         while(fn!=0)
1603         {
1604                 if(strcmp(fn->fname, newf)==0)
1605                 {
1606                         if(newf!=fbuf)
1607                                 pkg_free(newf);
1608                         newf = fbuf;
1609                         break;
1610                 }
1611                 fn = fn->next;
1612         }
1613         if(fn==0)
1614         {
1615                 fn = (struct sr_yy_fname*)pkg_malloc(sizeof(struct sr_yy_fname));
1616                 if(fn==0)
1617                 {
1618                         if(newf!=fbuf)
1619                                 pkg_free(newf);
1620                         LOG(L_CRIT, "no more pkg\n");
1621                         return -1;
1622                 }
1623                 if(newf==fbuf)
1624                 {
1625                         fn->fname = (char*)pkg_malloc(strlen(fbuf)+1);
1626                         if(fn->fname==0)
1627                         {
1628                                 pkg_free(fn);
1629                                 LOG(L_CRIT, "no more pkg!\n");
1630                                 return -1;
1631                         }
1632                         strcpy(fn->fname, fbuf);
1633                 } else {
1634                         fn->fname = newf;
1635                 }
1636                 fn->next = sr_yy_fname_list;
1637                 sr_yy_fname_list = fn;
1638         }
1639
1640         finame = fn->fname;
1641
1642         yy_switch_to_buffer( yy_create_buffer(yyin, YY_BUF_SIZE ) );
1643
1644         return 0;
1645
1646 }
1647
1648 static int sr_pop_yy_state()
1649 {
1650         include_stack_ptr--;
1651         if (include_stack_ptr<0 )
1652                 return -1;
1653
1654         yy_delete_buffer( YY_CURRENT_BUFFER );
1655         yy_switch_to_buffer(include_stack[include_stack_ptr].state);
1656         line=include_stack[include_stack_ptr].line;
1657         column=include_stack[include_stack_ptr].column;
1658         startline=include_stack[include_stack_ptr].startline;
1659         startcolumn=include_stack[include_stack_ptr].startcolumn;
1660         finame = include_stack[include_stack_ptr].finame;
1661         return 0;
1662 }
1663
1664 /* define/ifdef support */
1665
1666 #define MAX_DEFINES    256
1667 static str pp_defines[MAX_DEFINES][2];
1668 static int pp_num_defines = 0;
1669 static int pp_define_type = 0;
1670 static int pp_define_index = -1;
1671
1672 /* pp_ifdef_stack[i] is 1 if the ifdef test at depth i is either
1673  * ifdef(defined), ifndef(undefined), or the opposite of these
1674  * two, but in an else branch
1675  */
1676 #define MAX_IFDEFS    256
1677 static int pp_ifdef_stack[MAX_IFDEFS];
1678 static int pp_sptr = 0; /* stack pointer */
1679
1680 static int pp_lookup(int len, const char * text)
1681 {
1682         str var = {(char *)text, len};
1683         int i;
1684
1685         for (i=0; i<pp_num_defines; i++)
1686                 if (STR_EQ(pp_defines[i][0], var))
1687                         return i;
1688
1689         return -1;
1690 }
1691
1692 int pp_define_set_type(int type)
1693 {
1694         pp_define_type = type;
1695         return 0;
1696 }
1697
1698 int pp_define(int len, const char * text)
1699 {
1700         int ppos;
1701
1702         LM_DBG("defining id: %.*s\n", len, text);
1703
1704         if (pp_num_defines == MAX_DEFINES) {
1705                 LOG(L_CRIT, "ERROR: too many defines -- adjust MAX_DEFINES\n");
1706                 return -1;
1707         }
1708
1709         pp_define_index = -1;
1710         ppos = pp_lookup(len, text);
1711         if(ppos >= 0) {
1712                 if(pp_define_type==1) {
1713                         LOG(L_DBG, "ignoring - already defined: %.*s\n", len, text);
1714                         pp_define_index = -2;
1715                         return 0;
1716                 } else if(pp_define_type==2) {
1717                         LOG(L_DBG, "redefining: %.*s\n", len, text);
1718                         pp_define_index = ppos;
1719                         if(pp_defines[ppos][1].s != NULL) {
1720                                 pkg_free(pp_defines[ppos][1].s);
1721                                 pp_defines[ppos][1].len = 0;
1722                                 pp_defines[ppos][1].s = NULL;
1723                         }
1724                         return 0;
1725                 } else {
1726                         LOG(L_CRIT, "ERROR: already defined: %.*s\n", len, text);
1727                         return -1;
1728                 }
1729         }
1730
1731         pp_defines[pp_num_defines][0].len = len;
1732         pp_defines[pp_num_defines][0].s = (char*)pkg_malloc(len+1);
1733         if(pp_defines[pp_num_defines][0].s==NULL) {
1734                 LOG(L_CRIT, "no more memory to define: %.*s\n", len, text);
1735                 return -1;
1736         }
1737         memcpy(pp_defines[pp_num_defines][0].s, text, len);
1738         pp_defines[pp_num_defines][1].len = 0;
1739         pp_defines[pp_num_defines][1].s = NULL;
1740         pp_define_index = pp_num_defines;
1741         pp_num_defines++;
1742
1743         return 0;
1744 }
1745
1746 int pp_define_set(int len, char *text)
1747 {
1748         int ppos;
1749
1750         if(pp_define_index == -2) {
1751                 /* #!trydef that should be ignored */
1752                 return 0;
1753         }
1754
1755         if(pp_define_index < 0) {
1756                 /* invalid position in define table */
1757                 LOG(L_BUG, "BUG: the index in define table not set yet\n");
1758                 return -1;
1759         }
1760         if(len<=0) {
1761                 LOG(L_DBG, "no define value - ignoring\n");
1762                 return 0;
1763         }
1764         if (pp_num_defines == MAX_DEFINES) {
1765                 LOG(L_CRIT, "ERROR: too many defines -- adjust MAX_DEFINES\n");
1766                 return -1;
1767         }
1768         if (pp_num_defines == 0) {
1769                 LOG(L_BUG, "BUG: setting define value, but no define id yet\n");
1770                 return -1;
1771         }
1772
1773         ppos = pp_define_index;
1774         if (pp_defines[ppos][0].s == NULL) {
1775                 LOG(L_BUG, "BUG: last define ID is null\n");
1776                 return -1;
1777         }
1778
1779         if (pp_defines[ppos][1].s != NULL) {
1780                 LOG(L_BUG, "BUG: ID %.*s [%d] overwritten\n",
1781                         pp_defines[ppos][0].len,
1782                         pp_defines[ppos][0].s, ppos);
1783                 return -1;
1784         }
1785
1786         pp_defines[ppos][1].len = len;
1787         pp_defines[ppos][1].s = text;
1788         LM_DBG("### setting define ID [%.*s] value [%.*s]\n",
1789                         pp_defines[ppos][0].len,
1790                         pp_defines[ppos][0].s,
1791                         pp_defines[ppos][1].len,
1792                         pp_defines[ppos][1].s);
1793         return 0;
1794 }
1795
1796 static str *pp_define_get(int len, const char * text)
1797 {
1798         str var = {(char *)text, len};
1799         int i;
1800
1801         for (i=0; i<pp_num_defines; i++)
1802         {
1803                 if (STR_EQ(pp_defines[i][0], var))
1804                 {
1805                         if(pp_defines[i][0].s!=NULL)
1806                         {
1807                                 LM_DBG("### returning define ID [%.*s] value [%.*s]\n",
1808                                         pp_defines[i][0].len,
1809                                         pp_defines[i][0].s,
1810                                         pp_defines[i][1].len,
1811                                         pp_defines[i][1].s);
1812                                 return &pp_defines[i][1];
1813                         }
1814                         return NULL;
1815                 }
1816         }
1817         return NULL;
1818 }
1819
1820 static int pp_ifdef_type(int type)
1821 {
1822         if (pp_sptr == MAX_IFDEFS) {
1823                 LOG(L_CRIT, "ERROR: too many nested ifdefs -- adjust MAX_IFDEFS\n");
1824                 return -1;
1825         }
1826
1827         pp_ifdef_stack[pp_sptr] = type;
1828         return 0;
1829 }
1830
1831 /* this sets the result of the if[n]def expr:
1832  * ifdef  defined   -> 1
1833  * ifdef  undefined -> 0
1834  * ifndef defined   -> 0
1835  * ifndef undefined -> 1
1836  */
1837 static void pp_ifdef_var(int len, const char * text)
1838 {
1839         pp_ifdef_stack[pp_sptr] ^= (pp_lookup(len, text) < 0);
1840 }
1841
1842 static void pp_update_state()
1843 {
1844         int i;
1845
1846         for (i=0; i<pp_sptr; i++)
1847                 if (! pp_ifdef_stack[i]) {
1848                         state = IFDEF_SKIP_S; BEGIN(IFDEF_SKIP);
1849                         return;
1850                 }
1851
1852         state = INITIAL; BEGIN(INITIAL);
1853 }
1854
1855 static void pp_ifdef()
1856 {
1857         pp_sptr++;
1858         pp_update_state();
1859 }
1860
1861 static void pp_else()
1862 {
1863         pp_ifdef_stack[pp_sptr-1] ^= 1;
1864         pp_update_state();
1865 }
1866
1867 static void pp_endif()
1868 {
1869         pp_sptr--;
1870         pp_update_state();
1871 }
1872