[augeas-devel] [PATCH 8/8] Add syntax for case-insensitive regexps

lutter at redhat.com lutter at redhat.com
Wed Jan 13 18:40:45 UTC 2010


From: David Lutterkort <lutter at redhat.com>

A regexp literal /regexp/i will be converted to a case-insensitive regexp.
---
 src/lexer.l                         |   10 +++++++-
 src/parser.y                        |   41 ++++++++++++++++++++--------------
 tests/modules/fail_nocase_union.aug |    3 ++
 tests/modules/pass_nocase.aug       |   19 ++++++++++++++++
 4 files changed, 55 insertions(+), 18 deletions(-)
 create mode 100644 tests/modules/fail_nocase_union.aug
 create mode 100644 tests/modules/pass_nocase.aug

diff --git a/src/lexer.l b/src/lexer.l
index 607d82a..cda014d 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -95,9 +95,17 @@ ARROW  ->
                return DQUOTED;
   }
 
+  \/([^/]|\\\/)*\/i {
+               loc_update(yylloc, yytext, yyleng);
+               yylval->regexp.nocase = 1;
+               yylval->regexp.pattern = regexp_literal(yytext+1, yyleng-3);
+               return REGEXP;
+  }
+
   \/([^/]|\\\/)*\/ {
                loc_update(yylloc, yytext, yyleng);
-               yylval->string = regexp_literal(yytext+1, yyleng-2);
+               yylval->regexp.nocase = 0;
+               yylval->regexp.pattern = regexp_literal(yytext+1, yyleng-2);
                return REGEXP;
   }
 
diff --git a/src/parser.y b/src/parser.y
index d6c00e1..f39be59 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -62,7 +62,7 @@ typedef struct info YYLTYPE;
 };
 
 %token <string> DQUOTED   /* "foo" */
-%token <string> REGEXP    /* /[ \t]+/ */
+%token <regexp> REGEXP    /* /[ \t]+/ */
 %token <string> LIDENT UIDENT QIDENT
 %token          ARROW
 
@@ -76,11 +76,15 @@ typedef struct info YYLTYPE;
 %token          KW_TEST KW_GET KW_PUT KW_AFTER
 
 %union {
-  struct term     *term;
+  struct term    *term;
   struct type    *type;
   struct ident   *ident;
   struct tree    *tree;
   char           *string;
+  struct {
+    int             nocase;
+    char           *pattern;
+  } regexp;
   int            intval;
   enum quant_tag quant;
 }
@@ -127,8 +131,9 @@ static void augl_error(struct info *locp, struct term **term,
  static struct term *make_unop(enum term_tag tag,
                               struct term *exp, struct info *locp);
  static struct term *make_ident(char *qname, struct info *locp);
- static struct term *make_value_term(enum value_tag tag, char *value,
-                                     struct info *locp);
+ static struct term *make_string_term(char *value, struct info *locp);
+ static struct term *make_regexp_term(char *pattern,
+                                      int nocase, struct info *locp);
  static struct term *make_rep(struct term *exp, enum quant_tag quant,
                              struct info *locp);
 
@@ -232,9 +237,9 @@ appexp: appexp rexp
 aexp: qid
       { $$ = make_ident($1, &@1); }
     | DQUOTED
-      { $$ = make_value_term(V_STRING, $1, &@1); }
+      { $$ = make_string_term($1, &@1); }
     | REGEXP
-      { $$ = make_value_term(V_REGEXP, $1, &@1); }
+      { $$ = make_regexp_term($1.pattern, $1.nocase, &@1); }
     | '(' exp ')'
       { $$ = $2; }
     | '[' exp ']'
@@ -442,18 +447,20 @@ static struct term *make_ident(char *qname, struct info *locp) {
   return term;
 }
 
-static struct term *make_value_term(enum value_tag tag, char *value,
-                                    struct info *locp) {
-  assert(tag == V_STRING || tag == V_REGEXP);
+static struct term *make_string_term(char *value, struct info *locp) {
   struct term *term = make_term_locp(A_VALUE, locp);
-  term->value = make_value(tag, ref(term->info));
-  if (tag == V_STRING) {
-    term->value->string = make_string(value);
-    term->type = make_base_type(T_STRING);
-  } else {
-    term->type = make_base_type(T_REGEXP);
-    term->value->regexp = make_regexp(term->info, value, 0);
-  }
+  term->value = make_value(V_STRING, ref(term->info));
+  term->value->string = make_string(value);
+  term->type = make_base_type(T_STRING);
+  return term;
+}
+
+static struct term *make_regexp_term(char *pattern, int nocase,
+                                     struct info *locp) {
+  struct term *term = make_term_locp(A_VALUE, locp);
+  term->value = make_value(V_REGEXP, ref(term->info));
+  term->type = make_base_type(T_REGEXP);
+  term->value->regexp = make_regexp(term->info, pattern, nocase);
   return term;
 }
 
diff --git a/tests/modules/fail_nocase_union.aug b/tests/modules/fail_nocase_union.aug
new file mode 100644
index 0000000..6b69fae
--- /dev/null
+++ b/tests/modules/fail_nocase_union.aug
@@ -0,0 +1,3 @@
+module Fail_Nocase_Union =
+
+let lns = [ key /[a-z]+/i ] | [ key "UPPER" ]
diff --git a/tests/modules/pass_nocase.aug b/tests/modules/pass_nocase.aug
new file mode 100644
index 0000000..6d254a3
--- /dev/null
+++ b/tests/modules/pass_nocase.aug
@@ -0,0 +1,19 @@
+module Pass_nocase =
+
+let lns1 =
+  let re = /[a-z]+/i - "Key" in
+  [ label "1" . store re ] | [ label "2" . store "Key" ]
+
+test lns1 get "Key" = { "2" = "Key" }
+test lns1 get "key" = { "1" = "key" }
+test lns1 get "KEY" = { "1" = "KEY" }
+test lns1 get "KeY" = { "1" = "KeY" }
+
+let lns2 =
+  let re = /[a-z]/i - /Key/i in
+  [ label "1" . store re ] | [ label "2" . store /Key/i ]
+
+test lns2 get "Key" = { "2" = "Key" }
+test lns2 get "key" = { "2" = "key" }
+test lns2 get "KEY" = { "2" = "KEY" }
+test lns2 get "KeY" = { "2" = "KeY" }
-- 
1.6.5.2




More information about the augeas-devel mailing list