YAP 7.1.0
regexp.c
Go to the documentation of this file.
1/*************************************************************************
2 * *
3 * YAP Prolog *
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8 * *
9 **************************************************************************
10 * *
11 * File: regexp.c * Last rev:
12 ** mods: * comments: regular expression interpreter *
13 * *
14 *************************************************************************/
15
25#if HAVE_SYS_TYPES_H
26#include <sys/types.h>
27#endif
28#include "YapInterface.h"
29#if HAVE_REGEXEC
30#include "regex.h"
31#define yap_regcomp(A, B, C) regcomp(A, B, C)
32#define yap_regexec(A, B, C, D, E) regexec(A, B, C, D, E)
33#define yap_regfree(A) regfree(A)
34#define yap_regerror(A, B, C, D) regfree(A, B, C, D)
35#else
36#include "yapregex.h"
37#endif
38/* for the sake of NULL */
39#include <stdio.h>
40
41void init_regexp(void);
42
43static YAP_Bool check_regexp(void) {
44 unsigned int buflen = (unsigned int)YAP_IntOfTerm(YAP_ARG2) + 1;
45 unsigned int sbuflen = (unsigned int)YAP_IntOfTerm(YAP_ARG4) + 1;
46 char *buf, *sbuf;
47 regex_t reg;
48 int out;
49 int yap_flags = YAP_IntOfTerm(YAP_ARG5);
50 int regcomp_flags = REG_NOSUB | REG_EXTENDED;
51
52 if ((buf = (char *)YAP_AllocSpaceFromYap(buflen)) == NULL) {
53 /* early exit */
54 return (FALSE);
55 }
56 if (YAP_StringToBuffer(YAP_ARG1, buf, buflen) == FALSE) {
57 /* something went wrong, possibly a type checking error */
58 YAP_FreeSpaceFromYap(buf);
59 return (FALSE);
60 }
61 if (yap_flags & 1)
62 regcomp_flags |= REG_ICASE;
63 /* cool, now I have my string in the buffer, let's have some fun */
64 if (yap_regcomp(&reg, buf, regcomp_flags) != 0)
65 return (FALSE);
66 if ((sbuf = (char *)YAP_AllocSpaceFromYap(sbuflen)) == NULL) {
67 /* early exit */
68 yap_regfree(&reg);
69 YAP_FreeSpaceFromYap(buf);
70 return (FALSE);
71 }
72 if (YAP_StringToBuffer(YAP_ARG3, sbuf, sbuflen) == FALSE) {
73 /* something went wrong, possibly a type checking error */
74 yap_regfree(&reg);
75 YAP_FreeSpaceFromYap(buf);
76 YAP_FreeSpaceFromYap(sbuf);
77 return (FALSE);
78 }
79 out = yap_regexec(&reg, sbuf, 0, NULL, 0);
80 yap_regfree(&reg);
81 YAP_FreeSpaceFromYap(buf);
82 YAP_FreeSpaceFromYap(sbuf);
83 if (out != 0 && out != REG_NOMATCH) {
84 return (FALSE);
85 }
86 return (out == 0);
87}
88
89static YAP_Bool regexp(void) {
90 unsigned int buflen = (unsigned int)YAP_IntOfTerm(YAP_ARG2) + 1;
91 unsigned int sbuflen = (unsigned int)YAP_IntOfTerm(YAP_ARG4) + 1;
92 char *buf, *sbuf;
93 regex_t reg;
94 int out;
95 size_t nmatch;
96 regmatch_t *pmatch;
97 long int tout;
98 int yap_flags = YAP_IntOfTerm(YAP_ARG5);
99 int regcomp_flags = REG_EXTENDED;
100
101 if ((buf = (char *)YAP_AllocSpaceFromYap(buflen)) == NULL) {
102 /* early exit */
103 return (FALSE);
104 }
105 if (YAP_StringToBuffer(YAP_ARG1, buf, buflen) == FALSE) {
106 /* something went wrong, possibly a type checking error */
107 YAP_FreeSpaceFromYap(buf);
108 return (FALSE);
109 }
110 if (yap_flags & 1)
111 regcomp_flags |= REG_ICASE;
112 /* cool, now I have my string in the buffer, let's have some fun */
113 if (yap_regcomp(&reg, buf, regcomp_flags) != 0) {
114 YAP_FreeSpaceFromYap(buf);
115 return (FALSE);
116 }
117 if (YAP_IsVarTerm(YAP_ARG7)) {
118 nmatch = reg.re_nsub;
119 } else {
120 nmatch = YAP_IntOfTerm(YAP_ARG7);
121 }
122 if ((sbuf = (char *)YAP_AllocSpaceFromYap(sbuflen)) == NULL) {
123 /* early exit */
124 yap_regfree(&reg);
125 YAP_FreeSpaceFromYap(buf);
126 return (FALSE);
127 }
128 if (YAP_StringToBuffer(YAP_ARG3, sbuf, sbuflen) == FALSE) {
129 /* something went wrong, possibly a type checking error */
130 yap_regfree(&reg);
131 YAP_FreeSpaceFromYap(buf);
132 YAP_FreeSpaceFromYap(sbuf);
133 return (FALSE);
134 }
135 pmatch = YAP_AllocSpaceFromYap(sizeof(regmatch_t) * (nmatch));
136 out = yap_regexec(&reg, sbuf, nmatch, pmatch, 0);
137 if (out == 0) {
138 /* match succeed, let's fill the match in */
139 long int i;
140 YAP_Term TNil = YAP_MkAtomTerm(YAP_LookupAtom("[]"));
141 YAP_Functor FDiff = YAP_MkFunctor(YAP_LookupAtom("-"), 2);
142
143 tout = TNil;
144 for (i = nmatch - 1; i >= 0; --i) {
145 int j;
146 YAP_Term t = TNil;
147
148 if (pmatch[i].rm_so != -1) {
149 if (yap_flags & 2) {
150 YAP_Term to[2];
151 to[0] = YAP_MkIntTerm(pmatch[i].rm_so);
152 to[1] = YAP_MkIntTerm(pmatch[i].rm_eo);
153 t = YAP_MkApplTerm(FDiff, 2, to);
154 } else {
155 for (j = pmatch[i].rm_eo - 1; j >= pmatch[i].rm_so; j--) {
156 t = YAP_MkPairTerm(YAP_MkIntTerm(sbuf[j]), t);
157 }
158 }
159 tout = YAP_MkPairTerm(t, tout);
160 }
161 }
162 out = !YAP_Unify(tout, YAP_ARG6);
163 } else if (out != REG_NOMATCH) {
164 out = 0;
165 }
166 yap_regfree(&reg);
167 YAP_FreeSpaceFromYap(buf);
168 YAP_FreeSpaceFromYap(sbuf);
169 YAP_FreeSpaceFromYap(pmatch);
170 return (out == 0);
171}
172
173void init_regexp(void) {
174 YAP_UserCPredicate("check_regexp", check_regexp, 5);
175 YAP_UserCPredicate("check_regexp", regexp, 7);
176}
177
178#if __WINDOWS__
179
180#include <windows.h>
181
182int WINAPI win_regexp(HANDLE, DWORD, LPVOID);
183
184int WINAPI win_regexp(HANDLE hinst, DWORD reason, LPVOID reserved) {
185 switch (reason) {
186 case DLL_PROCESS_ATTACH:
187 break;
188 case DLL_PROCESS_DETACH:
189 break;
190 case DLL_THREAD_ATTACH:
191 break;
192 case DLL_THREAD_DETACH:
193 break;
194 }
195 return 1;
196}
197#endif
X_API char * YAP_StringToBuffer(Term t, char *buf, unsigned int bufsize)
copy a string to a buffer, the buffer must have been malloced
Definition: c_interface.c:1362