Skip to content

Commit

Permalink
- Added builtin function stringDelimitList to MetaModelica
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@9873 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Sep 20, 2011
1 parent 0b034fd commit 014bb84
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Compiler/FrontEnd/MetaModelicaBuiltin.mo
Expand Up @@ -414,6 +414,17 @@ function stringAppendList "O(str)"
external "builtin";
end stringAppendList;

function stringDelimitList
"O(str)
Takes a list of strings and a string delimiter and appends all
list elements with the string delimiter inserted between elements.
Example: stringDelimitList({\"x\",\"y\",\"z\"}, \", \") => \"x, y, z\""
input List<String> strs;
input String delimiter;
output String str;
external "builtin";
end stringDelimitList;

function stringLength "O(1)"
input String str;
output Integer i;
Expand Down
61 changes: 61 additions & 0 deletions c_runtime/meta/meta_modelica_builtin.cpp
Expand Up @@ -276,6 +276,67 @@ metamodelica_string stringAppendList(modelica_metatype lst)
return p;
}

metamodelica_string stringDelimitList(modelica_metatype lst, metamodelica_string_const delimiter)
{
// fprintf(stderr, "stringDelimitList(%s)\n", anyString(lst));
modelica_integer lstLen, len, lenDelimiter;
unsigned nbytes,header,nwords;
modelica_metatype car, lstHead, lstTmp;
char *tmp,*delimiter_cstr;
struct mmc_string *res;
void *p;
lstLen = 0;
nbytes = 0;
lstHead = lst;
lstTmp = lst;
while (!listEmpty(lstTmp)) {
MMC_CHECK_STRING(MMC_CAR(lstTmp));
nbytes += MMC_STRLEN(MMC_CAR(lstTmp));
// fprintf(stderr, "stringDelimitList: Has success reading input %d: %s\n", lstLen, MMC_STRINGDATA(MMC_CAR(lst)));
lstTmp = MMC_CDR(lstTmp);
lstLen++;
}
if (nbytes == 0) return mmc_emptystring;
if (lstLen == 1) return MMC_CAR(lstHead);
lenDelimiter = MMC_STRLEN(delimiter);
nbytes += (lstLen-1)*lenDelimiter;
delimiter_cstr = MMC_STRINGDATA(delimiter);
MMC_DEBUG_ASSERT(lenDelimiter == strlen(delimiter_cstr));

header = MMC_STRINGHDR(nbytes);
nwords = MMC_HDRSLOTS(header) + 1;
res = (struct mmc_string *) mmc_alloc_words(nwords);
res->header = header;
tmp = (char*) res->data;
nbytes = 0;
lstTmp = lstHead;
{ // Unrolled first element (not delimiter in front)
car = MMC_CAR(lstTmp);
len = MMC_STRLEN(car);
MMC_DEBUG_ASSERT(len == strlen(MMC_STRINGDATA(car)));
memcpy(tmp+nbytes,MMC_STRINGDATA(car),len);
nbytes += len;
lstTmp = MMC_CDR(lstTmp);
}
while (!listEmpty(lstTmp)) {
memcpy(tmp+nbytes,delimiter_cstr,lenDelimiter);
nbytes += lenDelimiter;
car = MMC_CAR(lstTmp);
len = MMC_STRLEN(car);
// fprintf(stderr, "stringDelimitList: %s %d %d\n", MMC_STRINGDATA(car), len, strlen(MMC_STRINGDATA(car)));
// Might be useful to check this when debugging. String literals are often done wrong :)
MMC_DEBUG_ASSERT(len == strlen(MMC_STRINGDATA(car)));
memcpy(tmp+nbytes,MMC_STRINGDATA(car),len);
nbytes += len;
lstTmp = MMC_CDR(lstTmp);
}
tmp[nbytes] = '\0';
// fprintf(stderr, "stringDelimitList(%s)=>%s\n", anyString(lstHead), anyString(MMC_TAGPTR(res)));
p = MMC_TAGPTR(res);
MMC_CHECK_STRING(p);
return p;
}

modelica_integer mmc_stringCompare(const void *str1, const void *str2)
{
MMC_CHECK_STRING(str1);
Expand Down
1 change: 1 addition & 0 deletions c_runtime/meta/meta_modelica_builtin.h
Expand Up @@ -61,6 +61,7 @@ modelica_integer stringInt(metamodelica_string);
modelica_real stringReal(metamodelica_string);
modelica_metatype stringListStringChar(metamodelica_string);
metamodelica_string stringAppendList(modelica_metatype);
metamodelica_string stringDelimitList(modelica_metatype,metamodelica_string_const);
metamodelica_string_const stringAppend(metamodelica_string_const,metamodelica_string_const);
#define stringLength(x) MMC_STRLEN(x)
modelica_integer mmc_stringCompare(const void *,const void *);
Expand Down

0 comments on commit 014bb84

Please sign in to comment.