size_t calc_base_index_dims_subs(int ndims,...) { int i; size_t index; _index_t *dims = (_index_t*)omc_alloc_interface.malloc(sizeof(_index_t)*ndims); _index_t *subs = (_index_t*)omc_alloc_interface.malloc(sizeof(_index_t)*ndims); va_list ap; va_start(ap,ndims); for(i = 0; i < ndims; ++i) { dims[i] = va_arg(ap, _index_t); } for(i = 0; i < ndims; ++i) { subs[i] = va_arg(ap, _index_t) - 1; } va_end(ap); index = 0; for(i = 0; i < ndims; ++i) { if (subs[i] < 0 || subs[i] >= dims[i]) { FILE_INFO info = omc_dummyFileInfo; omc_assert(NULL, info, "Dimension %d has bounds 1..%d, got array subscript %d", i+1, dims[i], subs[i]+1); } index = (index * dims[i]) + subs[i]; } return index; }
/* 0-based index*/ size_t calc_base_index_va(const base_array_t *source, int ndims, va_list ap) { int i; size_t index; index = 0; for(i = 0; i < ndims; ++i) { int sub_i = va_arg(ap, _index_t) - 1; if (sub_i < 0 || sub_i >= source->dim_size[i]) { FILE_INFO info = omc_dummyFileInfo; omc_assert(NULL, info, "Dimension %d has bounds 1..%d, got array subscript %d", i+1, source->dim_size[i], sub_i+1); } index = (index * source->dim_size[i]) + sub_i; } return index; }
/* Convert a modelica_integer to a modelica_string, used in String(integer, format="xxx") */ modelica_string modelica_integer_to_modelica_string_format(modelica_integer i,modelica_string format) { void *res; size_t sz; void *c_fmt = modelica_string_format_to_c_string_format(format); switch (MMC_STRINGDATA(c_fmt)[MMC_STRLEN(c_fmt)-1]) { case 'f': case 'e': case 'E': case 'g': case 'G': /* double */ sz = snprintf(NULL, 0, MMC_STRINGDATA(c_fmt), (double) i); res = alloc_modelica_string(sz); sprintf(MMC_STRINGDATA(res), MMC_STRINGDATA(c_fmt), (double) i); break; case 'c': case 'd': case 'i': /* int */ sz = snprintf(NULL, 0, MMC_STRINGDATA(c_fmt), (long) i); res = alloc_modelica_string(sz); sprintf(MMC_STRINGDATA(res), MMC_STRINGDATA(c_fmt), (long) i); break; case 'o': case 'x': case 'X': case 'u': /* uint */ sz = snprintf(NULL, 0, MMC_STRINGDATA(c_fmt), (unsigned long) i); res = alloc_modelica_string(sz); sprintf(MMC_STRINGDATA(res), MMC_STRINGDATA(c_fmt), (unsigned long) i); break; default: /* integer values, etc */ omc_assert(NULL, dummyFILE_INFO, "Invalid conversion specifier for Real: %c", MMC_STRINGDATA(c_fmt)[MMC_STRLEN(c_fmt)-1]); } return res; }
modelica_real real_int_pow(threadData_t *threadData, modelica_real base, modelica_integer n) { modelica_real result = 1.0; modelica_integer m = n < 0; FILE_INFO info = omc_dummyFileInfo; if(m) { if(base == 0.0) omc_assert(threadData, info, "Model error. 0^(%i) is not defined", n); n = -n; } while(n != 0) { if((n % 2) != 0) { result *= base; n--; } base *= base; n /= 2; } return m ? (1 / result) : result; }
modelica_string modelica_string_format_to_c_string_format(modelica_string format) { char buf[FMT_BUFSIZE]; const char *str = MMC_STRINGDATA(format), *tmp = str; int cont=1, n=0; buf[n++] = '%'; while (cont) { /* Parse flag characters */ switch (*tmp) { /* Extended flags? ',I */ case '#': case '0': case '-': case ' ': case '+': buf[n] = *(tmp++); checkBufSize(str, n++); break; default: cont = 0; } } // width: [1-9][0-9]* if ((*tmp >= '1') || (*tmp <= '9')) { while (*tmp >= '0' && *tmp <= '9') { buf[n] = *(tmp++); checkBufSize(str, n++); } } // precision: .[0-9]* if (*tmp == '.') { buf[n] = *(tmp++); checkBufSize(str, n++); while (*tmp >= '0' && *tmp <= '9') { buf[n] = *(tmp++); checkBufSize(str, n++); } } switch (*tmp) { case 'f': case 'e': case 'E': case 'g': case 'G': /* double */ case 'c': /* int */ buf[n] = *(tmp++); checkBufSize(str, n++); break; case 'd': case 'i': /* int */ case 'o': case 'x': case 'X': case 'u': /* uint */ buf[n] = 'l'; /* we use long in OpenModelica */ checkBufSize(str, n++); buf[n] = *(tmp++); checkBufSize(str, n++); break; case 'h': case 'l': case 'L': case 'q': case 'j': case 'z': case 't': omc_assert(NULL, dummyFILE_INFO, "Length modifiers are not legal in Modelica format strings: %s", str); break; default: omc_assert(NULL, dummyFILE_INFO, "Could not parse format string: invalid conversion specifier: %c in %s", *tmp, str); } if (*tmp) { omc_assert(NULL, dummyFILE_INFO, "Could not parse format string: trailing data after the format directive", *tmp, str); } buf[n] = '\0'; return mmc_mk_scon(buf); }
static inline void checkBufSize(const char *str, int n) { if (n >= FMT_BUFSIZE) { omc_assert(NULL, dummyFILE_INFO, "Could not parse format string; ran out of buffer size (%d): %s", FMT_BUFSIZE, str); } }