@@ -39,11 +39,11 @@ #import "OFString.h" #import "OFLocale.h" #import "OFInitializationFailedException.h" -#define MAX_SUBFORMAT_LEN 64 +#define maxSubformatLen 64 #ifndef HAVE_ASPRINTF /* * (v)asprintf might be declared, but HAVE_ASPRINTF not defined because * configure determined it is broken. In this case, we must make sure there is @@ -51,36 +51,36 @@ */ # define asprintf asprintf_ # define vasprintf vasprintf_ #endif -struct context { +struct Context { const char *format; size_t formatLen; - char subformat[MAX_SUBFORMAT_LEN + 1]; + char subformat[maxSubformatLen + 1]; size_t subformatLen; va_list arguments; char *buffer; size_t bufferLen; size_t i, last; enum { - STATE_STRING, - STATE_FORMAT_FLAGS, - STATE_FORMAT_FIELD_WIDTH, - STATE_FORMAT_LENGTH_MODIFIER, - STATE_FORMAT_CONVERSION_SPECIFIER + stateString, + stateFormatFlags, + stateFormatFieldWidth, + stateFormatLengthModifier, + stateFormatConversionSpecifier } state; enum { - LENGTH_MODIFIER_NONE, - LENGTH_MODIFIER_HH, - LENGTH_MODIFIER_H, - LENGTH_MODIFIER_L, - LENGTH_MODIFIER_LL, - LENGTH_MODIFIER_J, - LENGTH_MODIFIER_Z, - LENGTH_MODIFIER_T, - LENGTH_MODIFIER_CAPITAL_L + lengthModifierNone, + lengthModifierHH, + lengthModifierH, + lengthModifierL, + lengthModifierLL, + lengthModifierJ, + lengthModifierZ, + lengthModifierT, + lengthModifierCapitalL } lengthModifier; bool useLocale; }; #ifdef HAVE_ASPRINTF_L @@ -95,11 +95,12 @@ #ifndef HAVE_ASPRINTF static int vasprintf(char **string, const char *format, va_list arguments) { - size_t length, bufferLength = 128; + int length; + size_t bufferLength = 128; *string = NULL; for (;;) { free(*string); @@ -108,11 +109,11 @@ return -1; length = vsnprintf(*string, bufferLength - 1, format, arguments); - if (length > 0 && (size_t)length < bufferLength - 1) + if (length >= 0 && (size_t)length < bufferLength - 1) break; if (bufferLength > INT_MAX / 2) { free(*string); return -1; @@ -119,11 +120,11 @@ } bufferLength <<= 1; } - if (length != bufferLength - 1) { + if (length > 0 && (size_t)length != bufferLength - 1) { char *resized = realloc(*string, length + 1); /* Ignore if making it smaller failed. */ if (resized != NULL) *string = resized; @@ -145,11 +146,11 @@ return ret; } #endif static bool -appendString(struct context *ctx, const char *append, size_t appendLen) +appendString(struct Context *ctx, const char *append, size_t appendLen) { char *newBuf; if (appendLen == 0) return true; @@ -165,14 +166,14 @@ return true; } static bool -appendSubformat(struct context *ctx, const char *subformat, +appendSubformat(struct Context *ctx, const char *subformat, size_t subformatLen) { - if (ctx->subformatLen + subformatLen > MAX_SUBFORMAT_LEN) + if (ctx->subformatLen + subformatLen > maxSubformatLen) return false; memcpy(ctx->subformat + ctx->subformatLen, subformat, subformatLen); ctx->subformatLen += subformatLen; ctx->subformat[ctx->subformatLen] = 0; @@ -179,11 +180,11 @@ return true; } static bool -stringState(struct context *ctx) +stringState(struct Context *ctx) { if (ctx->format[ctx->i] == '%') { if (ctx->i > 0) if (!appendString(ctx, ctx->format + ctx->last, ctx->i - ctx->last)) @@ -191,18 +192,18 @@ if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; ctx->last = ctx->i + 1; - ctx->state = STATE_FORMAT_FLAGS; + ctx->state = stateFormatFlags; } return true; } static bool -formatFlagsState(struct context *ctx) +formatFlagsState(struct Context *ctx) { switch (ctx->format[ctx->i]) { case '-': case '+': case ' ': @@ -215,36 +216,36 @@ case ',': /* ObjFW extension: Use decimal point from locale */ ctx->useLocale = true; break; default: - ctx->state = STATE_FORMAT_FIELD_WIDTH; + ctx->state = stateFormatFieldWidth; ctx->i--; break; } return true; } static bool -formatFieldWidthState(struct context *ctx) +formatFieldWidthState(struct Context *ctx) { if ((ctx->format[ctx->i] >= '0' && ctx->format[ctx->i] <= '9') || ctx->format[ctx->i] == '*' || ctx->format[ctx->i] == '.') { if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; } else { - ctx->state = STATE_FORMAT_LENGTH_MODIFIER; + ctx->state = stateFormatLengthModifier; ctx->i--; } return true; } static bool -formatLengthModifierState(struct context *ctx) +formatLengthModifierState(struct Context *ctx) { /* Only one allowed */ switch (ctx->format[ctx->i]) { case 'h': /* and also hh */ if (ctx->formatLen > ctx->i + 1 && @@ -251,16 +252,16 @@ ctx->format[ctx->i + 1] == 'h') { if (!appendSubformat(ctx, ctx->format + ctx->i, 2)) return false; ctx->i++; - ctx->lengthModifier = LENGTH_MODIFIER_HH; + ctx->lengthModifier = lengthModifierHH; } else { if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; - ctx->lengthModifier = LENGTH_MODIFIER_H; + ctx->lengthModifier = lengthModifierH; } break; case 'l': /* and also ll */ if (ctx->formatLen > ctx->i + 1 && @@ -272,16 +273,16 @@ if (!appendSubformat(ctx, "I64", 3)) return false; #endif ctx->i++; - ctx->lengthModifier = LENGTH_MODIFIER_LL; + ctx->lengthModifier = lengthModifierLL; } else { if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; - ctx->lengthModifier = LENGTH_MODIFIER_L; + ctx->lengthModifier = lengthModifierL; } break; case 'j': #if defined(OF_WINDOWS) @@ -293,11 +294,11 @@ #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif - ctx->lengthModifier = LENGTH_MODIFIER_J; + ctx->lengthModifier = lengthModifierJ; break; case 'z': #if defined(OF_WINDOWS) if (sizeof(size_t) == 8) @@ -309,11 +310,11 @@ #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif - ctx->lengthModifier = LENGTH_MODIFIER_Z; + ctx->lengthModifier = lengthModifierZ; break; case 't': #if defined(OF_WINDOWS) if (sizeof(ptrdiff_t) == 8) @@ -325,18 +326,18 @@ #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif - ctx->lengthModifier = LENGTH_MODIFIER_T; + ctx->lengthModifier = lengthModifierT; break; case 'L': if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; - ctx->lengthModifier = LENGTH_MODIFIER_CAPITAL_L; + ctx->lengthModifier = lengthModifierCapitalL; break; #ifdef OF_WINDOWS case 'I': /* win32 strangeness (I64 instead of ll or j) */ if (ctx->formatLen > ctx->i + 2 && @@ -344,11 +345,11 @@ ctx->format[ctx->i + 2] == '4') { if (!appendSubformat(ctx, ctx->format + ctx->i, 3)) return false; ctx->i += 2; - ctx->lengthModifier = LENGTH_MODIFIER_LL; + ctx->lengthModifier = lengthModifierLL; } else ctx->i--; break; #endif @@ -355,26 +356,26 @@ #ifdef OF_IOS case 'q': /* iOS uses this for PRI?64 */ if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; - ctx->lengthModifier = LENGTH_MODIFIER_LL; + ctx->lengthModifier = lengthModifierLL; break; #endif default: ctx->i--; break; } - ctx->state = STATE_FORMAT_CONVERSION_SPECIFIER; + ctx->state = stateFormatConversionSpecifier; return true; } static bool -formatConversionSpecifierState(struct context *ctx) +formatConversionSpecifierState(struct Context *ctx) { char *tmp = NULL; int tmpLen = 0; #ifndef HAVE_ASPRINTF_L OFString *point; @@ -383,11 +384,11 @@ if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; switch (ctx->format[ctx->i]) { case '@': - if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) + if (ctx->lengthModifier != lengthModifierNone) return false; ctx->subformat[ctx->subformatLen - 1] = 's'; @try { @@ -408,19 +409,19 @@ @throw e; } break; case 'C': - if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) + if (ctx->lengthModifier != lengthModifierNone) return false; ctx->subformat[ctx->subformatLen - 1] = 's'; { char buffer[5]; - size_t len = of_string_utf8_encode( - va_arg(ctx->arguments, of_unichar_t), buffer); + size_t len = OFUTF8StringEncode( + va_arg(ctx->arguments, OFUnichar), buffer); if (len == 0) return false; buffer[len] = 0; @@ -427,19 +428,19 @@ tmpLen = asprintf(&tmp, ctx->subformat, buffer); } break; case 'S': - if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) + if (ctx->lengthModifier != lengthModifierNone) return false; ctx->subformat[ctx->subformatLen - 1] = 's'; { - const of_unichar_t *arg = - va_arg(ctx->arguments, const of_unichar_t *); - size_t j, len = of_string_utf32_length(arg); + const OFUnichar *arg = + va_arg(ctx->arguments, const OFUnichar *); + size_t j, len = OFUTF32StringLength(arg); char *buffer; if (SIZE_MAX / 4 < len || (SIZE_MAX / 4) - len < 1) return false; @@ -446,11 +447,11 @@ if ((buffer = malloc((len * 4) + 1)) == NULL) return false; j = 0; for (size_t i = 0; i < len; i++) { - size_t clen = of_string_utf8_encode(arg[i], + size_t clen = OFUTF8StringEncode(arg[i], buffer + j); if (clen == 0) { free(buffer); return false; @@ -467,33 +468,33 @@ break; case 'd': case 'i': switch (ctx->lengthModifier) { - case LENGTH_MODIFIER_NONE: - case LENGTH_MODIFIER_HH: - case LENGTH_MODIFIER_H: + case lengthModifierNone: + case lengthModifierHH: + case lengthModifierH: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, int)); break; - case LENGTH_MODIFIER_L: + case lengthModifierL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, long)); break; - case LENGTH_MODIFIER_LL: + case lengthModifierLL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, long long)); break; - case LENGTH_MODIFIER_J: + case lengthModifierJ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, intmax_t)); break; - case LENGTH_MODIFIER_Z: + case lengthModifierZ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, ssize_t)); break; - case LENGTH_MODIFIER_T: + case lengthModifierT: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, ptrdiff_t)); break; default: return false; @@ -503,33 +504,33 @@ case 'o': case 'u': case 'x': case 'X': switch (ctx->lengthModifier) { - case LENGTH_MODIFIER_NONE: - case LENGTH_MODIFIER_HH: - case LENGTH_MODIFIER_H: + case lengthModifierNone: + case lengthModifierHH: + case lengthModifierH: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, unsigned int)); break; - case LENGTH_MODIFIER_L: + case lengthModifierL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, unsigned long)); break; - case LENGTH_MODIFIER_LL: + case lengthModifierLL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, unsigned long long)); break; - case LENGTH_MODIFIER_J: + case lengthModifierJ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, uintmax_t)); break; - case LENGTH_MODIFIER_Z: + case lengthModifierZ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, size_t)); break; - case LENGTH_MODIFIER_T: + case lengthModifierT: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, ptrdiff_t)); break; default: return false; @@ -543,12 +544,12 @@ case 'g': case 'G': case 'a': case 'A': switch (ctx->lengthModifier) { - case LENGTH_MODIFIER_NONE: - case LENGTH_MODIFIER_L: + case lengthModifierNone: + case lengthModifierL: #ifdef HAVE_ASPRINTF_L if (!ctx->useLocale) tmpLen = asprintf_l(&tmp, cLocale, ctx->subformat, va_arg(ctx->arguments, double)); @@ -555,11 +556,11 @@ else #endif tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, double)); break; - case LENGTH_MODIFIER_CAPITAL_L: + case lengthModifierCapitalL: #ifdef HAVE_ASPRINTF_L if (!ctx->useLocale) tmpLen = asprintf_l(&tmp, cLocale, ctx->subformat, va_arg(ctx->arguments, long double)); @@ -610,15 +611,15 @@ #endif break; case 'c': switch (ctx->lengthModifier) { - case LENGTH_MODIFIER_NONE: + case lengthModifierNone: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, int)); break; - case LENGTH_MODIFIER_L: + case lengthModifierL: #ifdef HAVE_WCHAR_H # if WINT_MAX >= INT_MAX tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, wint_t)); # else @@ -632,16 +633,16 @@ } break; case 's': switch (ctx->lengthModifier) { - case LENGTH_MODIFIER_NONE: + case lengthModifierNone: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, const char *)); break; #ifdef HAVE_WCHAR_T - case LENGTH_MODIFIER_L: + case lengthModifierL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, const wchar_t *)); break; #endif default: @@ -648,57 +649,57 @@ return false; } break; case 'p': - if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) + if (ctx->lengthModifier != lengthModifierNone) return false; tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, void *)); break; case 'n': switch (ctx->lengthModifier) { - case LENGTH_MODIFIER_NONE: + case lengthModifierNone: *va_arg(ctx->arguments, int *) = (int)ctx->bufferLen; break; - case LENGTH_MODIFIER_HH: + case lengthModifierHH: *va_arg(ctx->arguments, signed char *) = (signed char)ctx->bufferLen; break; - case LENGTH_MODIFIER_H: + case lengthModifierH: *va_arg(ctx->arguments, short *) = (short)ctx->bufferLen; break; - case LENGTH_MODIFIER_L: + case lengthModifierL: *va_arg(ctx->arguments, long *) = (long)ctx->bufferLen; break; - case LENGTH_MODIFIER_LL: + case lengthModifierLL: *va_arg(ctx->arguments, long long *) = (long long)ctx->bufferLen; break; - case LENGTH_MODIFIER_J: + case lengthModifierJ: *va_arg(ctx->arguments, intmax_t *) = (intmax_t)ctx->bufferLen; break; - case LENGTH_MODIFIER_Z: + case lengthModifierZ: *va_arg(ctx->arguments, size_t *) = (size_t)ctx->bufferLen; break; - case LENGTH_MODIFIER_T: + case lengthModifierT: *va_arg(ctx->arguments, ptrdiff_t *) = (ptrdiff_t)ctx->bufferLen; break; default: return false; } break; case '%': - if (ctx->lengthModifier != LENGTH_MODIFIER_NONE) + if (ctx->lengthModifier != lengthModifierNone) return false; if (!appendString(ctx, "%", 1)) return false; @@ -717,43 +718,43 @@ } free(tmp); } - memset(ctx->subformat, 0, MAX_SUBFORMAT_LEN); + memset(ctx->subformat, 0, maxSubformatLen); ctx->subformatLen = 0; - ctx->lengthModifier = LENGTH_MODIFIER_NONE; + ctx->lengthModifier = lengthModifierNone; ctx->useLocale = false; ctx->last = ctx->i + 1; - ctx->state = STATE_STRING; + ctx->state = stateString; return true; } -static bool (*states[])(struct context *) = { +static bool (*states[])(struct Context *) = { stringState, formatFlagsState, formatFieldWidthState, formatLengthModifierState, formatConversionSpecifierState }; int -of_vasprintf(char **string, const char *format, va_list arguments) +OFVASPrintF(char **string, const char *format, va_list arguments) { - struct context ctx; + struct Context ctx; ctx.format = format; ctx.formatLen = strlen(format); - memset(ctx.subformat, 0, MAX_SUBFORMAT_LEN + 1); + memset(ctx.subformat, 0, maxSubformatLen + 1); ctx.subformatLen = 0; va_copy(ctx.arguments, arguments); ctx.bufferLen = 0; ctx.last = 0; - ctx.state = STATE_STRING; - ctx.lengthModifier = LENGTH_MODIFIER_NONE; + ctx.state = stateString; + ctx.lengthModifier = lengthModifierNone; ctx.useLocale = false; if ((ctx.buffer = malloc(1)) == NULL) return -1; @@ -762,11 +763,11 @@ free(ctx.buffer); return -1; } } - if (ctx.state != STATE_STRING) { + if (ctx.state != stateString) { free(ctx.buffer); return -1; } if (!appendString(&ctx, ctx.format + ctx.last, @@ -778,18 +779,5 @@ ctx.buffer[ctx.bufferLen] = 0; *string = ctx.buffer; return (ctx.bufferLen <= INT_MAX ? (int)ctx.bufferLen : -1); } - -int -of_asprintf(char **string, const char *format, ...) -{ - va_list arguments; - int ret; - - va_start(arguments, format); - ret = of_vasprintf(string, format, arguments); - va_end(arguments); - - return ret; -}