Make gnulib a git submodule.
[m4.git] / m4 / resyntax.c
blob8be3038e4c487398b2c9bfc791912d45d1495e42
1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
4 This file is part of GNU M4.
6 GNU M4 is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU M4 is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
22 #include <regex.h>
23 #include <string.h>
25 #include "m4private.h"
27 typedef struct {
28 const char *spec;
29 const int code;
30 } m4_resyntax;
32 /* The syntaxes named in this table are saved into frozen files. Changing
33 the mappings will break programs that load a frozen file made before
34 such a change... */
36 static m4_resyntax const m4_resyntax_map[] =
38 /* First, the canonical definitions for reverse lookups: */
40 { "AWK", RE_SYNTAX_AWK },
41 { "ED", RE_SYNTAX_ED },
42 { "EGREP", RE_SYNTAX_EGREP },
43 { "EMACS", RE_SYNTAX_EMACS },
44 { "GNU_AWK", RE_SYNTAX_GNU_AWK },
45 { "GREP", RE_SYNTAX_GREP },
46 { "POSIX_AWK", RE_SYNTAX_POSIX_AWK },
47 { "POSIX_BASIC", RE_SYNTAX_POSIX_BASIC },
48 { "POSIX_EGREP", RE_SYNTAX_POSIX_EGREP },
49 { "POSIX_EXTENDED", RE_SYNTAX_POSIX_EXTENDED },
50 { "POSIX_MINIMAL_BASIC", RE_SYNTAX_POSIX_MINIMAL_BASIC },
51 { "SED", RE_SYNTAX_SED },
53 /* The rest are aliases, for forward lookups only: */
55 { "", RE_SYNTAX_EMACS },
56 { "BASIC", RE_SYNTAX_POSIX_BASIC },
57 { "BSD_M4", RE_SYNTAX_POSIX_EXTENDED },
58 { "EXTENDED", RE_SYNTAX_POSIX_EXTENDED },
59 { "GAWK", RE_SYNTAX_GNU_AWK },
60 { "GNU_EGREP", RE_SYNTAX_EGREP },
61 { "GNU_EMACS", RE_SYNTAX_EMACS },
62 { "GNU_M4", RE_SYNTAX_EMACS },
63 { "MINIMAL", RE_SYNTAX_POSIX_MINIMAL_BASIC },
64 { "MINIMAL_BASIC", RE_SYNTAX_POSIX_MINIMAL_BASIC },
65 { "POSIX_MINIMAL", RE_SYNTAX_POSIX_MINIMAL_BASIC },
67 /* End marker: */
69 { NULL, -1 }
73 /* Return the internal code representing the syntax SPEC, or -1 if
74 SPEC is invalid. The `m4_syntax_map' table is searched case
75 insensitively, after replacing any spaces or dashes in SPEC with
76 underscore characters. Possible matches for the "GNU_M4" element
77 then, are "gnu m4", "GNU-m4" or "Gnu_M4". */
78 int
79 m4_regexp_syntax_encode (const char *spec)
81 const m4_resyntax *resyntax;
82 char *canonical;
83 char *p;
85 /* Unless specified otherwise, return the historical GNU M4 default. */
86 if (!spec)
87 return RE_SYNTAX_EMACS;
89 canonical = xstrdup (spec);
91 /* Canonicalise SPEC. */
92 for (p = canonical; *p != '\0'; ++p)
94 if ((*p == ' ') || (*p == '-'))
95 *p = '_';
96 else if (islower (to_uchar (*p)))
97 *p = toupper (to_uchar (*p));
100 for (resyntax = m4_resyntax_map; resyntax->spec != NULL; ++resyntax)
102 if (!strcmp (resyntax->spec, canonical))
103 break;
106 free (canonical);
108 return resyntax->code;
112 /* Return the syntax specifier that matches CODE, or NULL if there is
113 no match. */
114 const char *
115 m4_regexp_syntax_decode (int code)
117 const m4_resyntax *resyntax;
119 for (resyntax = m4_resyntax_map; resyntax->spec != NULL; ++resyntax)
121 if (resyntax->code == code)
122 break;
125 return resyntax->spec;