Module: sip-router
Branch: kamailio_3.0
Commit: 744813329639b323e77a148aebb83112ec1039d1
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=744813329639b323e77a148aebb83112ec1039d1

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date:   Fri Oct 30 11:05:28 2009 +0100

support for defines

- applied patch from Bogdan Harjoc
- support for define/ifdef/ifndef
- nicer way to build config file
- additions to preprocessor directives, so far was 'include'
- format is:
  #!define ID
  #!ifdef ID
  #!ifndef ID
  #!else
  #!endif

---

 cfg.lex |  157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/cfg.lex b/cfg.lex
index 105df4b..38bc6db 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -106,6 +106,12 @@
        #define PVAR_P_S                7  /* pvar: $(...)  or $foo(...)*/
        #define PVARID_S                8  /* $foo.bar...*/
        #define STR_BETWEEN_S           9
+       #define LINECOMMENT_S            10
+       #define DEFINE_S                11
+       #define DEFINE_EOL_S            12
+       #define IFDEF_S                    13
+       #define IFDEF_EOL_S                14
+       #define IFDEF_SKIP_S            15
 
        #define STR_BUF_ALLOC_UNIT      128
        struct str_buf{
@@ -153,11 +159,19 @@
                struct sr_yy_fname *next;
        } *sr_yy_fname_list = 0;
 
+       static int  pp_define(int len, const char * text);
+       static int  pp_ifdef_type(int pos);
+       static void pp_ifdef_var(int len, const char * text);
+       static void pp_ifdef();
+       static void pp_else();
+       static void pp_endif();
+
 %}
 
 /* start conditions */
 %x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P 
 %x PVARID INCLF
+%x LINECOMMENT DEFINE_ID DEFINE_EOL IFDEF_ID IFDEF_EOL IFDEF_SKIP
 
 /* config script types : #!SER  or #!KAMAILIO or #!MAX_COMPAT */
 SER_CFG                        SER
@@ -475,8 +489,9 @@ TLSv1                       "tlsv1"|"TLSv1"|"TLSV1"
 
 LETTER         [a-zA-Z]
 DIGIT          [0-9]
-ALPHANUM       {LETTER}|{DIGIT}|[_]
-ID                     {LETTER}{ALPHANUM}*
+LETTER_     {LETTER}|[_]
+ALPHANUM    {LETTER_}|{DIGIT}
+ID          {LETTER_}{ALPHANUM}*
 NUM_ID         {ALPHANUM}+
 HEX                    [0-9a-fA-F]
 HEXNUMBER      0x{HEX}+
@@ -507,6 +522,12 @@ COM_LINE   #
 COM_START      "/\*"
 COM_END                "\*/"
 
+DEFINE       define
+IFDEF        ifdef
+IFNDEF       ifndef
+ENDIF        endif
+/* else is already defined */
+
 EAT_ABLE       [\ \t\b\r]
 
 %%
@@ -1123,7 +1144,38 @@ EAT_ABLE [\ \t\b\r]
                                                                                
        sr_cfg_compat=SR_COMPAT_KAMAILIO;}
 <INITIAL>{COM_LINE}!{MAXCOMPAT_CFG}{CR}        { count(); 
                                                                                
                sr_cfg_compat=SR_COMPAT_MAX;}
-<INITIAL>{COM_LINE}.*{CR}      { count(); }
+
+<INITIAL>{COM_LINE}!{DEFINE}{EAT_ABLE}+        { count();
+                                                                               
state = DEFINE_S; BEGIN(DEFINE_ID); }
+<DEFINE_ID>{ID}                                { count();
+                                                               if 
(pp_define(yyleng, yytext)) return 1;
+                                                               state = 
DEFINE_EOL_S; BEGIN(DEFINE_EOL); }
+<DEFINE_EOL>{EAT_ABLE}*{CR}                    { count();
+                                                                       state = 
INITIAL; BEGIN(INITIAL); }
+
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{IFDEF}{EAT_ABLE}+    { count();
+                                                               if 
(pp_ifdef_type(1)) return 1;
+                                                               state = 
IFDEF_S; BEGIN(IFDEF_ID); }
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{IFNDEF}{EAT_ABLE}+    { count();
+                                                               if 
(pp_ifdef_type(0)) return 1;
+                                                               state = 
IFDEF_S; BEGIN(IFDEF_ID); }
+<IFDEF_ID>{ID}                { count();
+                                pp_ifdef_var(yyleng, yytext);
+                                state = IFDEF_EOL_S; BEGIN(IFDEF_EOL); }
+<IFDEF_EOL>{EAT_ABLE}*{CR}    { count(); pp_ifdef(); }
+
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{ELSE}{EAT_ABLE}*{CR}    { count(); pp_else(); }
+
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{ENDIF}{EAT_ABLE}*{CR}    { count();
+                                                                               
                                        pp_endif(); }
+
+ /* we're in an ifdef that evaluated to false -- throw it away */
+<IFDEF_SKIP>.|{CR}    { count(); }
+
+ /* this is split so the shebangs match more, giving them priority */
+<INITIAL>{COM_LINE}        { count(); state = LINECOMMENT_S;
+                                                               
BEGIN(LINECOMMENT); }
+<LINECOMMENT>.*{CR}        { count(); state = INITIAL_S; BEGIN(INITIAL); }
 
 <INITIAL>{ID}                  { count(); addstr(&s_buf, yytext, yyleng);
                                                                        
yylval.strval=s_buf.s;
@@ -1474,3 +1526,102 @@ static int sr_pop_yy_state()
        return 0;
 }
 
+/* define/ifdef support */
+
+#define MAX_DEFINES    1024
+static str pp_defines[MAX_DEFINES];
+static int pp_num_defines = 0;
+
+/* pp_ifdef_stack[i] is 1 if the ifdef test at depth i is either
+ * ifdef(defined), ifndef(undefined), or the opposite of these
+ * two, but in an else branch
+ */
+#define MAX_IFDEFS    128
+static int pp_ifdef_stack[MAX_IFDEFS];
+static int pp_sptr = 0; /* stack pointer */
+
+static int pp_lookup(int len, const char * text)
+{
+       str var = {(char *)text, len};
+       int i;
+
+       for (i=0; i<pp_num_defines; i++)
+               if (STR_EQ(pp_defines[i], var))
+                       return i;
+
+       return -1;
+}
+
+static int pp_define(int len, const char * text)
+{
+       if (pp_num_defines == MAX_DEFINES) {
+               LOG(L_CRIT, "ERROR: too many defines -- adjust MAX_DEFINES\n");
+               return -1;
+       }
+
+       if (pp_lookup(len, text) >= 0) {
+               LOG(L_CRIT, "ERROR: already defined: %.*s\n", len, text);
+               return -1;
+       }
+
+       pp_defines[pp_num_defines].len = len;
+       pp_defines[pp_num_defines].s = (char*)pkg_malloc(len+1);
+       memcpy(pp_defines[pp_num_defines].s, text, len);
+       pp_num_defines++;
+
+       return 0;
+}
+
+static int pp_ifdef_type(int type)
+{
+       if (pp_sptr == MAX_IFDEFS) {
+               LOG(L_CRIT, "ERROR: too many nested ifdefs -- adjust 
MAX_IFDEFS\n");
+               return -1;
+       }
+
+       pp_ifdef_stack[pp_sptr] = type;
+       return 0;
+}
+
+/* this sets the result of the if[n]def expr:
+ * ifdef  defined   -> 1
+ * ifdef  undefined -> 0
+ * ifndef defined   -> 0
+ * ifndef undefined -> 1
+ */
+static void pp_ifdef_var(int len, const char * text)
+{
+       pp_ifdef_stack[pp_sptr] ^= (pp_lookup(len, text) < 0);
+}
+
+static void pp_update_state()
+{
+       int i;
+
+       for (i=0; i<pp_sptr; i++)
+               if (! pp_ifdef_stack[i]) {
+                       state = IFDEF_SKIP_S; BEGIN(IFDEF_SKIP);
+                       return;
+               }
+
+       state = INITIAL; BEGIN(INITIAL);
+}
+
+static void pp_ifdef()
+{
+       pp_sptr++;
+       pp_update_state();
+}
+
+static void pp_else()
+{
+       pp_ifdef_stack[pp_sptr-1] ^= 1;
+       pp_update_state();
+}
+
+static void pp_endif()
+{
+       pp_sptr--;
+       pp_update_state();
+}
+


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to