static int test_eof(lua_State *L, UFILE *ufile) { UChar32 c = u_fgetcx(ufile); u_fungetc(c, ufile); lua_pushlstring(L, NULL, 0); icu4lua_internrawustring(L, UFILE_UV_USTRING_META, UFILE_UV_USTRING_POOL); return (c != EOF); }
/* TODO: Is always skipping the prefix symbol as a positive sign a good idea in all locales? */ static int32_t u_scanf_skip_leading_positive_sign(UFILE *input, UNumberFormat *format, UErrorCode *status) { UChar c; int32_t count = 0; UBool isNotEOF; UChar plusSymbol[USCANF_SYMBOL_BUFFER_SIZE]; int32_t symbolLen; UErrorCode localStatus = U_ZERO_ERROR; if (U_SUCCESS(*status)) { symbolLen = unum_getSymbol(format, UNUM_PLUS_SIGN_SYMBOL, plusSymbol, UPRV_LENGTHOF(plusSymbol), &localStatus); if (U_SUCCESS(localStatus)) { /* skip all leading ws in the input */ while( (isNotEOF = ufile_getch(input, &c)) && (count < symbolLen && c == plusSymbol[count]) ) { count++; } /* put the final character back on the input */ if(isNotEOF) { u_fungetc(c, input); } } } return count; }
static int32_t u_scanf_ustring_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { UChar *arg = (UChar*)(args[0].ptrValue); UChar *alias = arg; int32_t count; int32_t skipped = 0; UChar c; UBool isNotEOF = FALSE; /* skip all ws in the input */ if (info->fIsString) { skipped = u_scanf_skip_leading_ws(input, info->fPadChar); } /* get the string one character at a time, truncating to the width */ count = 0; while( (info->fWidth == -1 || count < info->fWidth) && (isNotEOF = ufile_getch(input, &c)) && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c)))) { /* put the character from the input onto the target */ if (!info->fSkipArg) { *alias++ = c; } /* increment the count */ ++count; } /* put the final character we read back on the input */ if (!info->fSkipArg) { if((info->fWidth == -1 || count < info->fWidth) && isNotEOF) { u_fungetc(c, input); } /* add the terminator */ if (info->fIsString) { *alias = 0x0000; } } /* we converted 1 arg */ *argConverted = !info->fSkipArg; return count + skipped; }
static int32_t u_scanf_skip_leading_ws(UFILE *input, UChar pad) { UChar c; int32_t count = 0; UBool isNotEOF; /* skip all leading ws in the input */ while( (isNotEOF = ufile_getch(input, &c)) && (c == pad || u_isWhitespace(c)) ) { count++; } /* put the final character back on the input */ if(isNotEOF) u_fungetc(c, input); return count; }
static int32_t u_scanf_string_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { const UChar *source; UConverter *conv; char *arg = (char*)(args[0].ptrValue); char *alias = arg; char *limit; UErrorCode status = U_ZERO_ERROR; int32_t count; int32_t skipped = 0; UChar c; UBool isNotEOF = FALSE; /* skip all ws in the input */ if (info->fIsString) { skipped = u_scanf_skip_leading_ws(input, info->fPadChar); } /* get the string one character at a time, truncating to the width */ count = 0; /* open the default converter */ conv = u_getDefaultConverter(&status); if(U_FAILURE(status)) return -1; while( (info->fWidth == -1 || count < info->fWidth) && (isNotEOF = ufile_getch(input, &c)) && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c)))) { if (!info->fSkipArg) { /* put the character from the input onto the target */ source = &c; /* Since we do this one character at a time, do it this way. */ if (info->fWidth > 0) { limit = alias + info->fWidth - count; } else { limit = alias + ucnv_getMaxCharSize(conv); } /* convert the character to the default codepage */ ucnv_fromUnicode(conv, &alias, limit, &source, source + 1, NULL, TRUE, &status); if(U_FAILURE(status)) { /* clean up */ u_releaseDefaultConverter(conv); return -1; } } /* increment the count */ ++count; } /* put the final character we read back on the input */ if (!info->fSkipArg) { if ((info->fWidth == -1 || count < info->fWidth) && isNotEOF) u_fungetc(c, input); /* add the terminator */ if (info->fIsString) { *alias = 0x00; } } /* clean up */ u_releaseDefaultConverter(conv); /* we converted 1 arg */ *argConverted = !info->fSkipArg; return count + skipped; }
static int32_t u_scanf_scanset_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { USet *scanset; UErrorCode status = U_ZERO_ERROR; int32_t chLeft = INT32_MAX; UChar32 c; UChar *alias = (UChar*) (args[0].ptrValue); UBool isNotEOF = FALSE; UBool readCharacter = FALSE; /* Create an empty set */ scanset = uset_open(0, -1); /* Back up one to get the [ */ fmt--; /* truncate to the width, if specified and alias the target */ if(info->fWidth >= 0) { chLeft = info->fWidth; } /* parse the scanset from the fmt string */ *fmtConsumed = uset_applyPattern(scanset, fmt, -1, 0, &status); /* verify that the parse was successful */ if (U_SUCCESS(status)) { c=0; /* grab characters one at a time and make sure they are in the scanset */ while(chLeft > 0) { if ((isNotEOF = ufile_getch32(input, &c)) && uset_contains(scanset, c)) { readCharacter = TRUE; if (!info->fSkipArg) { int32_t idx = 0; UBool isError = FALSE; U16_APPEND(alias, idx, chLeft, c, isError); if (isError) { break; } alias += idx; } chLeft -= (1 + U_IS_SUPPLEMENTARY(c)); } else { /* if the character's not in the scanset, break out */ break; } } /* put the final character we read back on the input */ if(isNotEOF && chLeft > 0) { u_fungetc(c, input); } } uset_close(scanset); /* if we didn't match at least 1 character, fail */ if(!readCharacter) return -1; /* otherwise, add the terminator */ else if (!info->fSkipArg) { *alias = 0x00; } /* we converted 1 arg */ *argConverted = !info->fSkipArg; return (info->fWidth >= 0 ? info->fWidth : INT32_MAX) - chLeft; }