/** \brief Convert a string in UTF-8 format into a wide string. * * \param op String to convert. * \return Newly created wide string. */ static inline std::wstring wstr_utf8(const std::string &op) { return wstr_utf8(op.c_str()); }
CELL * p_select(CELL * params) { size_t n = 0, idx = 0; ssize_t index; CELL * list, * cell; CELL * result = NULL; CELL * head; int evalFlag = TRUE; char * str, * newStr; #ifdef SUPPORT_UTF8 int * wstr; int * wnewStr; size_t len; #endif params = getEvalDefault(params, &head); cell = evaluateExpression(params); if(isList(cell->type)) { evalFlag = FALSE; cell = params = (CELL *)cell->contents; } if(head->type == CELL_STRING) { if((n = listlen(params)) == 0) return(stuffString("")); str = (char *)head->contents; #ifndef SUPPORT_UTF8 newStr = (char *)allocMemory(n + 1); idx = 0; while(params->type != CELL_NIL) { if(idx == 0) { getIntegerExt(cell, (UINT *)&index, FALSE); params = params->next; } else params = getIntegerExt(params, (UINT *)&index, evalFlag); index = adjustNegativeIndex(index, head->aux -1); *(newStr + idx++) = *(str + index); } *(newStr + n) = 0; #else wstr = allocMemory(head->aux * sizeof(int)); len = utf8_wstr(wstr, str, head->aux - 1); wnewStr = allocMemory((n + 1) * sizeof(int)); idx = 0; while(params->type != CELL_NIL) { if(idx == 0) { getIntegerExt(cell, (UINT *)&index, FALSE); params = params->next; } else params = getIntegerExt(params, (UINT *)&index, evalFlag); index = adjustNegativeIndex(index, len); *(wnewStr + idx++) = *(wstr + index); } *(wnewStr + n) = 0; newStr = allocMemory(UTF8_MAX_BYTES * n + 1); n = wstr_utf8(newStr, wnewStr, UTF8_MAX_BYTES * n); newStr = reallocMemory(newStr, n + 1); free(wstr); free(wnewStr); #endif result = getCell(CELL_STRING); result->aux = n + 1; result->contents = (UINT)newStr; return(result); } if(!isList(head->type)) return(errorProcExt(ERR_LIST_OR_STRING_EXPECTED, head)); head = (CELL *)head->contents; list = head; n = 0; while(params->type != CELL_NIL) { if(n++ == 0) { getIntegerExt(cell, (UINT *)&index, FALSE); params = params->next; } else params = getIntegerExt(params, (UINT *)&index, evalFlag); if(index < 0) index = convertNegativeOffset(index, head); if(index < idx) list = head, idx = 0; while(idx < index && list != nilCell) list = list->next, idx++; if(list == nilCell) errorProc(ERR_LIST_INDEX_OUTOF_BOUNDS); if(result == NULL) { result = getCell(CELL_EXPRESSION); cell = copyCell(list); result->contents = (UINT)cell; } else { cell->next = copyCell(list); cell = cell->next; } } return((result == NULL) ? getCell(CELL_EXPRESSION) : result); }