/** \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());
 }
Esempio n. 2
0
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);
}