Skip to content

Commit

Permalink
- Move regex() to utility.c
Browse files Browse the repository at this point in the history
- Better allocators (pass mk_scon or init_modelica_string to regex)
- Never fail (pass 0 match and the error-message on failure; let the user handle it)
- Removed #ifdef for regex (fix cmakefiles instead to get regex working)


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@14935 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Jan 25, 2013
1 parent f791481 commit 22dc396
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 106 deletions.
36 changes: 5 additions & 31 deletions Compiler/FrontEnd/Ceval.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ algorithm
case ("ModelicaStrings_scanReal") then ();
case ("ModelicaStrings_skipWhiteSpace") then ();
case ("ModelicaError") then ();
case ("System_regexModelica") then ();
case ("OpenModelica_regex") then ();
end match;
end isKnownExternalFunc;

Expand Down Expand Up @@ -1290,41 +1290,15 @@ algorithm
i = ModelicaExternalC.Strings_advanced_skipWhiteSpace(str,i);
then Values.INTEGER(i);

case ("System_regexModelica",{Values.STRING(str),Values.STRING(re),Values.INTEGER(i),Values.BOOL(extended),Values.BOOL(insensitive)},_)
equation
v = cevalRegex(str,re,i,extended,insensitive);
then v;

end match;
end cevalKnownExternalFuncs2;

protected function cevalRegex
input String str;
input String re;
input Integer i;
input Boolean extended;
input Boolean insensitive;
output Values.Value v;
algorithm
v := matchcontinue (str,re,i,extended,insensitive)
local
Integer n;
list<String> strs;
list<Values.Value> vals;
case (_,_,_,_,_)
case ("OpenModelica_regex",{Values.STRING(str),Values.STRING(re),Values.INTEGER(i),Values.BOOL(extended),Values.BOOL(insensitive)},_)
equation
(n,strs) = System.regex(str,re,i,extended,insensitive);
vals = List.map(strs,ValuesUtil.makeString);
v = Values.ARRAY(vals,{i});
then Values.TUPLE({Values.INTEGER(n),v});
else
equation
strs = List.fill("",i);
vals = List.map(strs,ValuesUtil.makeString);
v = Values.ARRAY(vals,{i});
then Values.TUPLE({Values.INTEGER(-1),v});
end matchcontinue;
end cevalRegex;

end match;
end cevalKnownExternalFuncs2;

protected function cevalMatrixElt "function: cevalMatrixElt
Evaluates the expression of a matrix constructor, e.g. {1,2;3,4}"
Expand Down
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/ModelicaBuiltin.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ function regex "Sets the error buffer and returns -1 if the regex does not comp
input Boolean caseInsensitive := false;
output Integer numMatches "-1 is an error, 0 means no match, else returns a number 1..maxMatches";
output String matchedSubstrings[maxMatches] "unmatched strings are returned as empty";
external "C" numMatches = System_regexModelica(str,re,maxMatches,extended,caseInsensitive,matchedSubstrings) annotation(Library = {"omcruntime"});
external "C" numMatches = OpenModelica_regex(str,re,maxMatches,extended,caseInsensitive,matchedSubstrings);
annotation(preferredView="text");
end regex;

Expand Down
25 changes: 8 additions & 17 deletions Compiler/runtime/System_omc.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,24 +552,15 @@ extern void* System_getRuntimeLibs()

extern void* System_regex(const char* str, const char* re, int maxn, int extended, int sensitive, int *nmatch)
{
*nmatch = 0;
void *res = SystemImpl__regex(str,re,maxn,extended,sensitive,nmatch);
if (res==NULL) MMC_THROW();
return res;
}

extern int System_regexModelica(const char* str, const char* re, int maxn, int extended, int sensitive, char **matches)
{
int nmatch = 0, i=0;
void *res = SystemImpl__regex(str,re,maxn,extended,sensitive,&nmatch);
if (res==NULL) MMC_THROW();
for (i=0; i<maxn; i++) {
char *tmp = MMC_STRINGDATA(MMC_CAR(res));
matches[i] = alloc_modelica_string(strlen(tmp));
strcpy(matches[i],tmp);
res = MMC_CDR(res);
void *res;
int i = 0;
void *matches[maxn];
*nmatch = OpenModelica_regexImpl(str,re,maxn,extended,sensitive,mmc_mk_scon,(void**)&matches);
res = mmc_mk_nil();
for (i=maxn-1; i>=0; i--) {
res = mmc_mk_cons(matches[i],res);
}
return nmatch;
return res;
}

extern char* System_escapedString(char* str, int nl)
Expand Down
15 changes: 10 additions & 5 deletions Compiler/runtime/System_rml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1910,12 +1910,17 @@ RML_END_LABEL

RML_BEGIN_LABEL(System__regex)
{
int nmatch = 0;
rmlA1 = SystemImpl__regex(RML_STRINGDATA(rmlA0),RML_STRINGDATA(rmlA1),RML_UNTAGFIXNUM(rmlA2),RML_UNTAGFIXNUM(rmlA3),RML_UNTAGFIXNUM(rmlA4),&nmatch);
void *res;
int nmatch, i = 0, maxn = RML_UNTAGFIXNUM(rmlA2);
void *matches[maxn];
nmatch = OpenModelica_regexImpl(RML_STRINGDATA(rmlA0),RML_STRINGDATA(rmlA1),maxn,RML_UNTAGFIXNUM(rmlA3),RML_UNTAGFIXNUM(rmlA4),mk_scon,(void**)&matches);
res = mk_nil();
for (i=maxn-1; i>=0; i--) {
res = mk_cons(matches[i],res);
}
rmlA0 = mk_icon(nmatch);
if (rmlA1)
RML_TAILCALLK(rmlSC);
RML_TAILCALLK(rmlFC);
rmlA1 = res;
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

Expand Down
51 changes: 0 additions & 51 deletions Compiler/runtime/systemimpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ extern "C" {
*/
#if !defined(_MSC_VER)
#include <libgen.h>
#include <regex.h>
#endif

#include "meta_modelica.h"
Expand Down Expand Up @@ -1170,56 +1169,6 @@ extern char* SystemImpl__unescapedString(const char* str)
return res;
}

extern void* SystemImpl__regex(const char* str, const char* re, int maxn, int extended, int sensitive, int *nmatch)
{
void *lst = mk_nil();
#if !defined(_MSC_VER) /* crap compiler doesn't have regex */
char *dup;
regex_t myregex;
regmatch_t matches[maxn];
int i,rc,res;
int flags = (extended ? REG_EXTENDED : 0) | (sensitive ? REG_ICASE : 0) | (maxn ? 0 : REG_NOSUB);
memset(&myregex, 1, sizeof(regex_t));
rc = regcomp(&myregex, re, flags);
lst = mk_nil();
if (rc) {
char err_buf[2048] = {0};
int len = 0;
len += snprintf(err_buf+len,2040-len,gettext("Failed to compile regular expression: %s with error: "), re);
len += regerror(rc, &myregex, err_buf+len, 2048-len);
len += snprintf(err_buf+len,2040-len,".");
len += snprintf(err_buf+len,2040-len,".");
c_add_message(-1, ErrorType_scripting,ErrorLevel_error, err_buf, NULL, 0);
regfree(&myregex);
return NULL;
}
res = regexec(&myregex, str, maxn, matches, 0);
lst = mk_nil();
*nmatch = 0;
if (!maxn)
(*nmatch)+= res == 0 ? 1 : 0;
else {
if (maxn) {
dup = strdup(str);
for (i=maxn-1; i>=0; i--) {
if (!res && matches[i].rm_so != -1) {
memcpy(dup, str + matches[i].rm_so, matches[i].rm_eo - matches[i].rm_so);
dup[matches[i].rm_eo - matches[i].rm_so] = '\0';
lst = mk_cons(mk_scon(dup),lst);
(*nmatch)++;
} else {
lst = mk_cons(mk_scon(""),lst);
}
}
free(dup);
}
}

regfree(&myregex);
#endif /* !defined(_MSC_VER) crap compiler doesn't have regex */
return lst;
}

char* SystemImpl__unquoteIdentifier(const char* str)
{
const char lookupTbl[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/c/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
include Makefile.objs

CPPFLAGS = -I. -I$(UTILPATH) -I. -I$(METAPATH) -I$(METAPATH)gc -I./simulation/libf2c/ -I$(top_builddir)/3rdParty/gc-7.2/include
CFLAGS = $(CPPFLAGS) $(CONFIG_CFLAGS) -Wall -pedantic $(EXTRA_CFLAGS)
CFLAGS = $(CPPFLAGS) $(CONFIG_CFLAGS) $(EXTRA_CFLAGS)
CXXFLAGS = $(CFLAGS)
FFLAGS = -O -fexceptions
# P.A: before, g77 had -O3 or -O2 but that caused a bug in DDASRT, giving infinite loop.
Expand Down
57 changes: 57 additions & 0 deletions SimulationRuntime/c/util/utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@


#include "utility.h"
#include "modelica_string.h"
#include <regex.h>
#include <string.h>

modelica_real real_int_pow(modelica_real base, modelica_integer n)
{
Expand All @@ -49,3 +52,57 @@ modelica_real real_int_pow(modelica_real base, modelica_integer n)
}
return m ? (1 / result) : result;
}

extern int OpenModelica_regexImpl(const char* str, const char* re, int maxn, int extended, int sensitive, void*(*mystrdup)(const char*), void **outMatches)
{
char *dup;
regex_t myregex;
regmatch_t matches[maxn];
int nmatch=0,i,rc,res;
int flags = (extended ? REG_EXTENDED : 0) | (sensitive ? REG_ICASE : 0) | (maxn ? 0 : REG_NOSUB);
memset(&myregex, 1, sizeof(regex_t));
rc = regcomp(&myregex, re, flags);
if (rc && maxn == 0) {
return 0;
}
if (rc) {
char err_buf[2048] = {0};
int len = 0;
len += snprintf(err_buf+len,2040-len,"Failed to compile regular expression: %s with error: ", re);
len += regerror(rc, &myregex, err_buf+len, 2048-len);
len += snprintf(err_buf+len,2040-len,".");
len += snprintf(err_buf+len,2040-len,".");
regfree(&myregex);
if (maxn) {
outMatches[0] = mystrdup(err_buf);
for (i=1; i<maxn; i++)
outMatches[i] = mystrdup("");
}
return 0;
}
res = regexec(&myregex, str, maxn, matches, 0);
if (!maxn)
nmatch += res == 0 ? 1 : 0;
else if (maxn) {
dup = strdup(str);
for (i=maxn-1; i>=0; i--) {
if (!res && matches[i].rm_so != -1) {
memcpy(dup, str + matches[i].rm_so, matches[i].rm_eo - matches[i].rm_so);
dup[matches[i].rm_eo - matches[i].rm_so] = '\0';
outMatches[i] = mystrdup(dup);
nmatch++;
} else {
outMatches[i] = mystrdup("");
}
}
free(dup);
}

regfree(&myregex);
return nmatch;
}

extern int OpenModelica_regex(const char* str, const char* re, int maxn, int extended, int sensitive, const char **outMatches)
{
return OpenModelica_regexImpl(str,re,maxn,extended,sensitive,(void*(*)(const char*)) init_modelica_string,(void**)outMatches);
}
4 changes: 4 additions & 0 deletions SimulationRuntime/c/util/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,9 @@ static inline modelica_integer modelica_integer_max(modelica_integer x,modelica_

/* pow(), but for integer exponents (faster implementation) */
extern modelica_real real_int_pow(modelica_real base,modelica_integer n);
/* Returns 0 on failure. The first element in nmatches contains the error-message. */
extern int OpenModelica_regexImpl(const char* str, const char* re, int maxn, int extended, int sensitive, void*(*)(const char*), void **result);
/* Wrapper for the builtin call */
extern int OpenModelica_regex(const char* str, const char* re, int maxn, int extended, int sensitive, const char **result);

#endif

0 comments on commit 22dc396

Please sign in to comment.