modelica_metatype listAppend(modelica_metatype lst1,modelica_metatype lst2) { int length = 0, i = 0; struct mmc_cons_struct *res = NULL; struct mmc_cons_struct *p = NULL; if (MMC_NILTEST(lst2)) /* If lst2 is empty, simply return lst1; huge performance gain for some uses of listAppend */ return lst1; length = listLength(lst1); if (length == 0) /* We need to check for empty lst1 */ return lst2; res = (struct mmc_cons_struct*)mmc_alloc_words( length * 3 /*(sizeof(struct mmc_cons_struct)/sizeof(void*))*/ ); /* Do one single big alloc. It's cheaper */ for (i=0; i<length-1; i++) { /* Write all except the last element... */ struct mmc_cons_struct *p = res+i; p->header = MMC_STRUCTHDR(2, MMC_CONS_CTOR); p->data[0] = MMC_CAR(lst1); p->data[1] = MMC_TAGPTR(res+i+1); lst1 = MMC_CDR(lst1); } /* The last element is a bit special. It points to lst2. */ p = res+length-1; p->header = MMC_STRUCTHDR(2, MMC_CONS_CTOR); p->data[0] = MMC_CAR(lst1); p->data[1] = lst2; return MMC_TAGPTR(res); }
modelica_metatype boxptr_stringUpdateStringChar(threadData_t *threadData,metamodelica_string str, metamodelica_string c, modelica_metatype iix) { int ix = MMC_UNTAGFIXNUM(iix); int length = 0; unsigned header = MMC_GETHDR(str); unsigned nwords = MMC_HDRSLOTS(header) + 1; struct mmc_string *p = NULL; void *res = NULL; MMC_CHECK_STRING(str); MMC_CHECK_STRING(c); /* fprintf(stderr, "stringUpdateStringChar(%s,%s,%ld)\n", MMC_STRINGDATA(str),MMC_STRINGDATA(c),ix); */ if (ix < 1 || MMC_STRLEN(c) != 1) MMC_THROW_INTERNAL(); length = MMC_STRLEN(str); if (ix > length) MMC_THROW_INTERNAL(); p = (struct mmc_string *) mmc_alloc_words_atomic(nwords); p->header = header; memcpy(p->data, MMC_STRINGDATA(str), length+1 /* include NULL */); p->data[ix-1] = MMC_STRINGDATA(c)[0]; res = MMC_TAGPTR(p); MMC_CHECK_STRING(res); return res; }
metamodelica_string_const stringAppend(metamodelica_string_const s1, metamodelica_string_const s2) { unsigned len1 = 0, len2 = 0, nbytes = 0, header = 0, nwords = 0; void *res = NULL; struct mmc_string *p = NULL; MMC_CHECK_STRING(s1); MMC_CHECK_STRING(s2); /* fprintf(stderr, "stringAppend([%p] %s, [%p] %s)->\n", s1, anyString(s1), s2, anyString(s2)); fflush(NULL); */ len1 = MMC_STRLEN(s1); len2 = MMC_STRLEN(s2); nbytes = len1+len2; header = MMC_STRINGHDR(nbytes); nwords = MMC_HDRSLOTS(header) + 1; p = (struct mmc_string *) mmc_alloc_words_atomic(nwords); /* fprintf(stderr, "at address %p\n", MMC_TAGPTR(p)); fflush(NULL); */ p->header = header; memcpy(p->data, MMC_STRINGDATA(s1), len1); memcpy(p->data + len1, MMC_STRINGDATA(s2), len2 + 1); res = MMC_TAGPTR(p); MMC_CHECK_STRING(res); /* fprintf(stderr, "-> %s\n", anyString(res)); fflush(NULL); */ return res; }
metamodelica_string stringAppendList(modelica_metatype lst) { /* fprintf(stderr, "stringAppendList(%s)\n", anyString(lst)); */ modelica_integer lstLen = 0, len = 0; unsigned nbytes = 0, header = 0, nwords = 0; modelica_metatype car = NULL, lstHead = NULL, lstTmp = NULL; char *tmp = NULL; struct mmc_string *res = NULL; void *p = NULL; 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, "stringAppendList: 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); header = MMC_STRINGHDR(nbytes); nwords = MMC_HDRSLOTS(header) + 1; res = (struct mmc_string *) mmc_alloc_words_atomic(nwords); res->header = header; tmp = (char*) res->data; nbytes = 0; lstTmp = lstHead; while (!listEmpty(lstTmp)) { car = MMC_CAR(lstTmp); len = MMC_STRLEN(car); /* fprintf(stderr, "stringAppendList: %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, "stringAppendList(%s)=>%s\n", anyString(lstHead), anyString(MMC_TAGPTR(res))); */ p = MMC_TAGPTR(res); MMC_CHECK_STRING(p); return p; }
modelica_metatype boxptr_substring(threadData_t *threadData, metamodelica_string_const str, modelica_metatype boxstart, modelica_metatype boxstop) { unsigned header = 0, nwords; long start = MMC_UNTAGFIXNUM(boxstart) - 1; long stop = MMC_UNTAGFIXNUM(boxstop) - 1; long totalLen = MMC_STRLEN(str), len = stop-start+1; struct mmc_string *res; char *tmp; modelica_metatype p; /* Bad indexes */ if (start < 0 || start >= totalLen || stop < start || stop >= totalLen) { MMC_THROW_INTERNAL(); } header = MMC_STRINGHDR(len); nwords = MMC_HDRSLOTS(header) + 1; res = (struct mmc_string *) mmc_alloc_words_atomic(nwords); res->header = header; tmp = (char*) res->data; memcpy(tmp, MMC_STRINGDATA(str) + start, len); tmp[len] = '\0'; p = MMC_TAGPTR(res); MMC_CHECK_STRING(p); return p; }