1 /* NetHack 3.6 posixregex.c $NHDT-Date: 1434446947 2015/06/16 09:29:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.5 $ */
2 /* Copyright (c) Sean Hunt 2015. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 #include "hack.h"
6
7 #include <regex.h>
8
9 /* The nhregex interface is implemented by several source files. The
10 * file to be used can be linked in by the build.
11 *
12 * The regex standard implemented should be POSIX extended regular
13 * expressions, see:
14 * http://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap09.html
15 * If an implementation uses an alternate expression format, this should
16 * be clearly noted; this will result in incompatibility of config files
17 * when NetHack is compiled with that implementation.
18 *
19 * struct nhregex
20 * The nhregex structure is an opaque structure type containing the
21 * information about a compiled regular expression.
22 *
23 * struct nhregex *regex_init(void)
24 * Used to create a new instance of the nhregex structure. It is
25 * uninitialized and can only safely be passed to regex_compile.
26 *
27 * boolean regex_compile(const char *s, struct nhregex *re)
28 * Used to compile s into a regex and store it in re. Returns TRUE if
29 * successful and FALSE otherwise. re is invalidated regardless of
30 * success.
31 *
32 * const char *regex_error_desc(struct nhregex *re)
33 * Used to retrieve an error description from an error created involving
34 * re. Returns NULL if no description can be retrieved. The returned
35 * string may be a static buffer and so is only valid until the next
36 * call to regex_error_desc.
37 *
38 * boolean regex_match(const char *s, struct nhregex *re)
39 * Used to determine if s (or any substring) matches the regex compiled
40 * into re. Only valid if the most recent call to regex_compile on re
41 * succeeded.
42 *
43 * void regex_free(struct nhregex *re)
44 * Deallocate a regex object.
45 */
46
47 const char regex_id[] = "posixregex";
48
49 struct nhregex {
50 regex_t re;
51 int err;
52 };
53
54 struct nhregex *
regex_init()55 regex_init()
56 {
57 return (struct nhregex *) alloc(sizeof(struct nhregex));
58 }
59
60 boolean
regex_compile(const char * s,struct nhregex * re)61 regex_compile(const char *s, struct nhregex *re)
62 {
63 if (!re)
64 return FALSE;
65 if ((re->err = regcomp(&re->re, s, REG_EXTENDED | REG_NOSUB)))
66 return FALSE;
67 return TRUE;
68 }
69
70 const char *
regex_error_desc(struct nhregex * re)71 regex_error_desc(struct nhregex *re)
72 {
73 static char buf[BUFSZ];
74
75 if (!re || !re->err)
76 return (const char *) 0;
77
78 /* FIXME: Using a static buffer here is not ideal, but avoids memory
79 * leaks. Consider the allocation more carefully. */
80 regerror(re->err, &re->re, buf, BUFSZ);
81
82 return buf;
83 }
84
85 boolean
regex_match(const char * s,struct nhregex * re)86 regex_match(const char *s, struct nhregex *re)
87 {
88 int result;
89
90 if (!re || !s)
91 return FALSE;
92
93 if ((result = regexec(&re->re, s, 0, (genericptr_t) 0, 0))) {
94 if (result != REG_NOMATCH)
95 re->err = result;
96 return FALSE;
97 }
98 return TRUE;
99 }
100
101 void
regex_free(struct nhregex * re)102 regex_free(struct nhregex *re)
103 {
104 regfree(&re->re);
105 free(re);
106 }
107