Skip to content

Commit

Permalink
- optimize template unparsing a bit (mostly memory but also speed)
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@19430 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
adrpo committed Mar 5, 2014
1 parent 6479476 commit e90e5de
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 42 deletions.
45 changes: 3 additions & 42 deletions Compiler/Template/Tpl.mo
Expand Up @@ -137,11 +137,11 @@ algorithm
// a new-line is inside
case (txt, str )
then
writeChars(txt, stringListStringChar(str));
//writeChars(txt, stringListStringChar(str));
writeChars(txt, System.strtokIncludingDelimiters(str, "\n"));
end matchcontinue;
end writeStr;


public function writeTok
input Text inText;
input StringToken inToken;
Expand Down Expand Up @@ -176,7 +176,6 @@ algorithm
end matchcontinue;
end writeTok;


public function writeText
input Text inText;
input Text inTextToWrite;
Expand Down Expand Up @@ -215,44 +214,6 @@ algorithm
end matchcontinue;
end writeText;

// can be optimized in C ... a tokenization function for "\n" is needed; strtok is insufficien
// even any substring function is not there (or is somwhere ??)
//-obsolete - writeStr will parse the string by default
public function writeParseNL "parses inStr for new lines"
input Text inText;
input String inStr;

output Text outText;
algorithm
outText := matchcontinue (inText, inStr)
local
Tokens toks, txttoks;
list<tuple<Tokens,BlockType>> blstack;
Text txt;
String str;
list<String> chars;

case (txt, str)
equation
-1 = System.stringFind(str, "\n");
then
writeStr(txt, str);

// a new-len is inside
case (txt, str )
then
writeChars(txt, stringListStringChar(str));

//should not ever happen
case (_ , _)
equation
Debug.fprint(Flags.FAILTRACE, "-!!!Tpl.writeParseNL failed.\n");
then
fail();
end matchcontinue;
end writeParseNL;


public function writeChars
input Text inText;
input list<String> inChars;
Expand Down Expand Up @@ -281,7 +242,7 @@ algorithm
case (txt, c :: chars )
equation
(lschars, chars, isline) = takeLineOrString(chars);
txt = writeLineOrStr(txt, stringCharListString( c :: lschars), isline);
txt = writeLineOrStr(txt, stringAppendList(c :: lschars), isline);
//Error txt = writeLineOrStr(txt, stringCharListString( str :: lschars), isline);
then
writeChars(txt, chars);
Expand Down
11 changes: 11 additions & 0 deletions Compiler/Util/System.mo
Expand Up @@ -157,6 +157,17 @@ public function strtok
external "C" strings=System_strtok(string,token) annotation(Library = "omcruntime");
end strtok;

public function strtokIncludingDelimiters
"as strtok but also includes *all* delimiters
split the string at delimiters into a list of strings including *all* delimiters
stringSplitInTokens(*a**b*, *) => {*, a, *, *, b, *}"
input String string;
input String token;
output list<String> strings;

external "C" strings=System_strtokIncludingDelimiters(string,token) annotation(Library = "omcruntime");
end strtokIncludingDelimiters;

public function substring
input String inString;
input Integer start;
Expand Down
79 changes: 79 additions & 0 deletions Compiler/runtime/System_omc.c
Expand Up @@ -814,6 +814,85 @@ int System_isRML()
return 0;
}

extern void* System_strtokIncludingDelimiters(const char *str0, const char *delimit)
{
char* str = (char*)str0;
mmc_uint_t len = strlen(str);
char* cp = NULL;
char *d = (char*)delimit;
mmc_uint_t dlen = strlen(d);
void *lst = mmc_mk_nil();
void *slst = mmc_mk_nil();
char* s = str;
char* stmp;
mmc_uint_t start = 0, end = 0;
/* len + 3 in pos signifies that there is no delimiter in the string */
mmc_uint_t pos = len + 3;

/* fail if delimiter is bigger than string */
if (dlen > len)
{
MMC_THROW();
}

/* add 0 to the list! */
lst = mmc_mk_cons(mmc_mk_icon(0), lst);

/* find the first delimiter */
while ((cp = strstr(s, d)) != NULL)
{
s = cp + dlen;
pos = (cp - str);
/* check if the position is already in the list */
/* in the list add only the end */
if (pos == MMC_UNTAGFIXNUM(MMC_CAR(lst)))
{
lst = mmc_mk_cons(mk_icon(pos+dlen), lst);
}
else /* not in the list, add both */
{
lst = mmc_mk_cons(mmc_mk_icon(pos), lst);
lst = mmc_mk_cons(mmc_mk_icon(pos+dlen), lst);
}
}
/* this means it was not found in the entire string */
if (pos == (len + 3))
{
/* return the empty list */
return slst;
}

/* add len to the list! */
if ((len) != MMC_UNTAGFIXNUM(MMC_CAR(lst)))
{
lst = mmc_mk_cons(mmc_mk_icon(len), lst);
}

/*
* BIG NOTE! the list of indexes is reversed, it starts closer to len!
*/
/* now we walk the list and build the string list */
while( MMC_GETHDR(lst) == MMC_CONSHDR )
{
end = MMC_UNTAGFIXNUM(MMC_CAR(lst));
lst = MMC_CDR(lst);
/* break if we reached the last in the list */
if (MMC_GETHDR(lst) == MMC_NILHDR)
{
break;
}
start = MMC_UNTAGFIXNUM(MMC_CAR(lst));
/* create stmp */
pos = end - start;
stmp = (char*)malloc((pos+1) * sizeof(char));
strncpy(stmp, str + start, pos);
stmp[pos] = '\0';
slst = mk_cons(mk_scon(stmp), slst);
free(stmp);
}
return slst;
}

#ifdef __cplusplus
}
#endif
83 changes: 83 additions & 0 deletions Compiler/runtime/System_rml.c
Expand Up @@ -1918,3 +1918,86 @@ RML_BEGIN_LABEL(System__isRML)
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__strtokIncludingDelimiters)
{
char* str = RML_STRINGDATA(rmlA0);
rml_uint_t len = RML_HDRSTRLEN(RML_GETHDR(rmlA0));
char* cp = NULL;
char *d = RML_STRINGDATA(rmlA1);
rml_uint_t dlen = RML_HDRSTRLEN(RML_GETHDR(rmlA1));
void *lst = RML_TAGPTR(&rml_prim_nil);
void *slst = RML_TAGPTR(&rml_prim_nil);
char* s = str;
char* stmp;
rml_uint_t start = 0, end = 0;
/* len + 3 in pos signifies that there is no delimiter in the string */
rml_uint_t pos = len + 3;

/* fail if delimiter is bigger than string */
if (dlen > len)
{
RML_TAILCALLK(rmlFC);
}

/* add 0 to the list! */
lst = mk_cons(mk_icon(0), lst);

/* find the first delimiter */
while ((cp = strstr(s, d)) != NULL)
{
s = cp + dlen;
pos = (cp - str);
/* check if the position is already in the list */
/* in the list add only the end */
if (pos == RML_UNTAGFIXNUM(RML_CAR(lst)))
{
lst = mk_cons(mk_icon(pos+dlen), lst);
}
else /* not in the list, add both */
{
lst = mk_cons(mk_icon(pos), lst);
lst = mk_cons(mk_icon(pos+dlen), lst);
}
}
/* this means it was not found in the entire string */
if (pos == (len + 3))
{
/* return the empty list */
rmlA0 = slst;
RML_TAILCALLK(rmlSC);
}

/* add len to the list! */
if ((len) != RML_UNTAGFIXNUM(RML_CAR(lst)))
{
lst = mk_cons(mk_icon(len), lst);
}

/*
* BIG NOTE! the list of indexes is reversed, it starts closer to len!
*/
/* now we walk the list and build the string list */
while( RML_GETHDR(lst) == RML_CONSHDR )
{
end = RML_UNTAGFIXNUM(RML_CAR(lst));
lst = RML_CDR(lst);
/* break if we reached the last in the list */
if (RML_GETHDR(lst) == RML_NILHDR)
{
break;
}
start = RML_UNTAGFIXNUM(RML_CAR(lst));
/* create stmp */
pos = end - start;
stmp = (char*)malloc((pos+1) * sizeof(char));
strncpy(stmp, str + start, pos);
stmp[pos] = '\0';
slst = mk_cons(mk_scon(stmp), slst);
free(stmp);
}
rmlA0 = slst;
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

0 comments on commit e90e5de

Please sign in to comment.