dvander@370: /** ds@653: * vim: set ts=4 : dvander@370: * =============================================================== dvander@370: * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. dvander@370: * =============================================================== dvander@370: * dvander@370: * This file is not open source and may not be copied without explicit dvander@370: * written permission of AlliedModders LLC. This file may not be redistributed dvander@370: * in whole or significant part. dvander@370: * For information, see LICENSE.txt or http://www.sourcemod.net/license.php dvander@370: * dvander@370: * Version: $Id$ dvander@370: */ dvander@370: faluco@230: #include faluco@230: #include faluco@274: #include faluco@227: #include "sm_stringutil.h" dvander@592: #include "Logger.h" faluco@389: #include "PluginSys.h" dvander@591: #include "Translator.h" dvander@591: #include "PlayerManager.h" faluco@227: faluco@227: #define LADJUST 0x00000004 /* left adjustment */ faluco@227: #define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */ ds@609: #define UPPERDIGITS 0x00000200 /* make alpha digits uppercase */ faluco@227: #define to_digit(c) ((c) - '0') faluco@227: #define is_digit(c) ((unsigned)to_digit(c) <= 9) faluco@227: faluco@288: #define CHECK_ARGS(x) \ faluco@288: if ((arg+x) > args) { \ dvander@599: pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "String formatted incorrectly - parameter %d (total %d)", arg, args); \ faluco@288: return 0; \ faluco@227: } faluco@227: faluco@422: inline bool TryServerLanguage(const char *serverlang, unsigned int *langid) faluco@389: { faluco@422: if (!g_Translator.GetLanguageByCode(serverlang, langid)) faluco@422: { faluco@422: if (!g_Translator.GetLanguageByCode("en", langid)) faluco@422: { faluco@422: return false; faluco@422: } faluco@422: } faluco@422: return true; faluco@422: } faluco@389: faluco@422: inline bool TryTranslation(CPlugin *pl, const char *key, unsigned int langid, unsigned int langcount, Translation *pTrans) faluco@422: { faluco@422: TransError err = Trans_BadLanguage; faluco@389: CPhraseFile *phrfl; faluco@389: faluco@389: for (size_t i=0; iGetLangFileByIndex(i)); faluco@422: err = phrfl->GetTranslation(key, langid, pTrans); faluco@389: } faluco@389: faluco@422: return (err == Trans_Okay) ? true : false; faluco@422: } faluco@422: faluco@422: size_t Translate(char *buffer, size_t maxlen, IPluginContext *pCtx, const char *key, cell_t target, const cell_t *params, int *arg, bool *error) faluco@422: { faluco@422: unsigned int langid; ds@661: const char *langname = NULL; faluco@422: *error = false; dvander@464: Translation pTrans; dvander@464: CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext()); dvander@464: size_t langcount = pl->GetLangFileCount(); dvander@464: void *new_params[MAX_TRANSLATE_PARAMS]; dvander@464: unsigned int max_params = 0; faluco@422: faluco@422: try_serverlang: faluco@422: if (target == LANG_SERVER) faluco@389: { ds@661: langname = g_Translator.GetServerLanguageCode(); faluco@422: if (!TryServerLanguage(langname ? langname : "en", &langid)) faluco@422: { ds@470: pCtx->ThrowNativeError("Translation failure: English language not found"); faluco@422: goto error_out; faluco@422: } dvander@448: } else if ((target >= 1) && (target <= g_Players.GetMaxClients())) { ds@661: langname = g_Translator.GetServerLanguageCode(); /* :TODO: read player's lang */ faluco@422: if (!langname || !g_Translator.GetLanguageByCode(langname, &langid)) faluco@422: { faluco@422: if (langname && !strcmp(langname, "en")) faluco@422: { ds@470: pCtx->ThrowNativeError("Translation failure: English language not found"); faluco@422: goto error_out; faluco@422: } faluco@422: target = LANG_SERVER; faluco@422: goto try_serverlang; faluco@422: } faluco@422: } else { faluco@422: pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Translation failed: invalid client index %d", target); faluco@422: goto error_out; faluco@422: } faluco@422: faluco@422: if (!TryTranslation(pl, key, langid, langcount, &pTrans)) faluco@422: { faluco@422: if (target != LANG_SERVER) faluco@422: { faluco@422: target = LANG_SERVER; faluco@422: goto try_serverlang; faluco@422: } else { faluco@422: if (!g_Translator.GetLanguageByCode("en", &langid) faluco@422: || !TryTranslation(pl, key, langid, langcount, &pTrans)) faluco@422: { faluco@422: pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Language phrase \"%s\" not found", key); faluco@422: goto error_out; faluco@422: } faluco@422: } faluco@389: } faluco@389: dvander@474: max_params = pTrans.fmt_count; dvander@474: faluco@389: for (size_t i=0; iLocalToPhysAddr(params[*arg], reinterpret_cast(&new_params[i])); faluco@389: (*arg)++; faluco@389: if ((*arg) + i > (size_t)params[0]) faluco@389: { faluco@422: pCtx->ThrowNativeErrorEx(SP_ERROR_PARAMS_MAX, "Translation string formatted incorrectly - parameter %d (total %d)", (*arg) + i, params[0]); faluco@422: goto error_out; faluco@389: } faluco@389: } faluco@389: faluco@389: return g_Translator.Translate(buffer, maxlen, new_params, &pTrans); faluco@422: error_out: faluco@422: *error = true; faluco@422: return 0; faluco@389: } faluco@389: dvander@276: //:TODO: review this code before we choose a license dvander@276: faluco@227: void AddString(char **buf_p, size_t &maxlen, const char *string, int width, int prec) faluco@227: { faluco@227: int size = 0; faluco@227: char *buf; faluco@227: static char nlstr[] = {'(','n','u','l','l',')','\0'}; faluco@227: faluco@227: buf = *buf_p; faluco@227: faluco@227: if (string == NULL) faluco@227: { faluco@227: string = nlstr; faluco@227: prec = -1; faluco@227: } faluco@227: faluco@227: if (prec >= 0) faluco@227: { faluco@227: for (size = 0; size < prec; size++) faluco@227: { faluco@227: if (string[size] == '\0') faluco@227: { faluco@227: break; faluco@227: } faluco@227: } faluco@227: } else { faluco@227: while (string[size++]); faluco@227: size--; faluco@227: } faluco@227: faluco@227: if (size > (int)maxlen) faluco@227: { faluco@227: size = maxlen; faluco@227: } faluco@227: faluco@227: maxlen -= size; faluco@227: width -= size; faluco@227: faluco@227: while (size--) faluco@227: { faluco@227: *buf++ = *string++; faluco@227: } faluco@227: faluco@227: while ((width-- > 0) && maxlen) faluco@227: { faluco@227: *buf++ = ' '; faluco@227: maxlen--; faluco@227: } faluco@227: faluco@227: *buf_p = buf; faluco@227: } faluco@227: faluco@227: void AddFloat(char **buf_p, size_t &maxlen, double fval, int width, int prec) faluco@227: { faluco@227: char text[32]; faluco@227: int digits; faluco@227: double signedVal; faluco@227: char *buf; faluco@227: int val; faluco@227: faluco@227: // get the sign faluco@227: signedVal = fval; faluco@227: if (fval < 0) faluco@227: { faluco@227: fval = -fval; faluco@227: } faluco@227: faluco@227: // write the float number faluco@227: digits = 0; faluco@227: val = (int)fval; faluco@227: do faluco@227: { faluco@227: text[digits++] = '0' + val % 10; faluco@227: val /= 10; faluco@227: } while (val); faluco@227: faluco@227: if (signedVal < 0) faluco@227: { faluco@227: text[digits++] = '-'; faluco@227: } faluco@227: faluco@227: buf = *buf_p; faluco@227: faluco@227: while ((digits < width) && maxlen) faluco@227: { faluco@227: *buf++ = ' '; faluco@227: width--; faluco@227: maxlen--; faluco@227: } faluco@227: faluco@227: while ((digits--) && maxlen) faluco@227: { faluco@227: *buf++ = text[digits]; faluco@227: maxlen--; faluco@227: } faluco@227: faluco@227: *buf_p = buf; faluco@227: faluco@227: if (prec < 0) faluco@227: { faluco@227: prec = 6; faluco@227: } faluco@227: // write the fraction faluco@227: digits = 0; faluco@227: while (digits < prec) faluco@227: { faluco@227: fval -= (int)fval; faluco@227: fval *= 10.0; faluco@227: val = (int)fval; faluco@227: text[digits++] = '0' + val % 10; faluco@227: } faluco@227: faluco@227: if ((digits > 0) && maxlen) faluco@227: { faluco@227: buf = *buf_p; faluco@227: *buf++ = '.'; faluco@227: maxlen--; faluco@227: for (prec = 0; maxlen && (prec < digits); prec++) faluco@227: { faluco@227: *buf++ = text[prec]; faluco@227: maxlen--; faluco@227: } faluco@227: *buf_p = buf; faluco@227: } faluco@227: } faluco@227: faluco@227: void AddUInt(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags) faluco@227: { faluco@227: char text[32]; faluco@227: int digits; faluco@227: char *buf; faluco@227: faluco@227: digits = 0; faluco@227: do faluco@227: { faluco@227: text[digits++] = '0' + val % 10; faluco@227: val /= 10; faluco@227: } while (val); faluco@227: faluco@227: buf = *buf_p; faluco@227: faluco@227: if (!(flags & LADJUST)) faluco@227: { faluco@227: while (digits < width && maxlen) faluco@227: { faluco@227: *buf++ = (flags & ZEROPAD) ? '0' : ' '; faluco@227: width--; faluco@227: maxlen--; faluco@227: } faluco@227: } faluco@227: faluco@227: while (digits-- && maxlen) faluco@227: { faluco@227: *buf++ = text[digits]; faluco@227: width--; faluco@227: maxlen--; faluco@227: } faluco@227: faluco@227: if (flags & LADJUST) faluco@227: { faluco@227: while (width-- && maxlen) faluco@227: { faluco@227: *buf++ = (flags & ZEROPAD) ? '0' : ' '; faluco@227: maxlen--; faluco@227: } faluco@227: } faluco@227: faluco@227: *buf_p = buf; faluco@227: } faluco@227: faluco@227: void AddInt(char **buf_p, size_t &maxlen, int val, int width, int flags) faluco@227: { faluco@227: char text[32]; faluco@227: int digits; faluco@227: int signedVal; faluco@227: char *buf; faluco@227: unsigned int unsignedVal; faluco@227: faluco@227: digits = 0; faluco@227: signedVal = val; faluco@227: if (val < 0) faluco@227: { faluco@227: /* we want the unsigned version */ faluco@227: unsignedVal = abs(val); faluco@227: } else { faluco@227: unsignedVal = val; faluco@227: } faluco@227: do faluco@227: { faluco@227: text[digits++] = '0' + unsignedVal % 10; faluco@227: unsignedVal /= 10; faluco@227: } while (unsignedVal); faluco@227: faluco@227: if (signedVal < 0) faluco@227: { faluco@227: text[digits++] = '-'; faluco@227: } faluco@227: faluco@227: buf = *buf_p; faluco@227: faluco@227: if (!(flags & LADJUST)) faluco@227: { faluco@227: while ((digits < width) && maxlen) faluco@227: { faluco@227: *buf++ = (flags & ZEROPAD) ? '0' : ' '; faluco@227: width--; faluco@227: maxlen--; faluco@227: } faluco@227: } faluco@227: faluco@227: while (digits-- && maxlen) faluco@227: { faluco@227: *buf++ = text[digits]; faluco@227: width--; faluco@227: maxlen--; faluco@227: } faluco@227: faluco@227: if (flags & LADJUST) faluco@227: { faluco@227: while (width-- && maxlen) faluco@227: { faluco@227: *buf++ = (flags & ZEROPAD) ? '0' : ' '; faluco@227: maxlen--; faluco@227: } faluco@227: } faluco@227: faluco@227: *buf_p = buf; faluco@227: } faluco@227: ds@544: void AddHex(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags) ds@544: { ds@544: char text[32]; ds@544: int digits; ds@544: char *buf; ds@544: char digit; ds@544: int hexadjust; ds@544: ds@544: if (flags & UPPERDIGITS) ds@544: { ds@544: hexadjust = 'A' - '9' - 1; ds@544: } else { ds@544: hexadjust = 'a' - '9' - 1; ds@544: } ds@544: ds@544: digits = 0; ds@544: do ds@544: { ds@544: digit = ('0' + val % 16); ds@544: if (digit > '9') ds@544: { ds@544: digit += hexadjust; ds@544: } ds@544: ds@544: text[digits++] = digit; ds@544: val /= 16; ds@544: } while(val); ds@544: ds@544: buf = *buf_p; ds@544: ds@544: if (!(flags & LADJUST)) ds@544: { ds@544: while (digits < width && maxlen) ds@544: { ds@544: *buf++ = (flags & ZEROPAD) ? '0' : ' '; ds@544: width--; ds@544: maxlen--; ds@544: } ds@544: } ds@544: ds@544: while (digits-- && maxlen) ds@544: { ds@544: *buf++ = text[digits]; ds@544: width--; ds@544: maxlen--; ds@544: } ds@544: ds@544: if (flags & LADJUST) ds@544: { ds@544: while (width-- && maxlen) ds@544: { ds@544: *buf++ = (flags & ZEROPAD) ? '0' : ' '; ds@544: maxlen--; ds@544: } ds@544: } ds@544: ds@544: *buf_p = buf; ds@544: } ds@544: dvander@276: size_t gnprintf(char *buffer, size_t maxlen, const char *format, void **args) dvander@276: { dvander@276: if (!buffer || !maxlen) dvander@276: { dvander@276: return 0; dvander@276: } dvander@276: dvander@276: int arg = 0; dvander@276: char *buf_p; dvander@276: char ch; dvander@276: int flags; dvander@276: int width; dvander@276: int prec; dvander@276: int n; dvander@276: char sign; dvander@276: const char *fmt; dvander@276: size_t llen = maxlen - 1; dvander@276: dvander@276: buf_p = buffer; dvander@276: fmt = format; dvander@276: dvander@276: while (true) dvander@276: { dvander@276: // run through the format string until we hit a '%' or '\0' dvander@276: for (ch = *fmt; llen && ((ch = *fmt) != '\0') && (ch != '%'); fmt++) dvander@276: { dvander@276: *buf_p++ = ch; dvander@276: llen--; dvander@276: } dvander@276: if ((ch == '\0') || (llen <= 0)) dvander@276: { dvander@276: goto done; dvander@276: } dvander@276: dvander@276: // skip over the '%' dvander@276: fmt++; dvander@276: dvander@276: // reset formatting state dvander@276: flags = 0; dvander@276: width = 0; dvander@276: prec = -1; dvander@276: sign = '\0'; dvander@276: dvander@276: rflag: dvander@276: ch = *fmt++; dvander@276: reswitch: dvander@276: switch(ch) dvander@276: { dvander@276: case '-': dvander@276: { dvander@276: flags |= LADJUST; dvander@276: goto rflag; dvander@276: } dvander@276: case '.': dvander@276: { dvander@276: n = 0; dvander@276: while(is_digit((ch = *fmt++))) dvander@276: { dvander@276: n = 10 * n + (ch - '0'); dvander@276: } dvander@276: prec = (n < 0) ? -1 : n; dvander@276: goto reswitch; dvander@276: } dvander@276: case '0': dvander@276: { dvander@276: flags |= ZEROPAD; dvander@276: goto rflag; dvander@276: } dvander@276: case '1': dvander@276: case '2': dvander@276: case '3': dvander@276: case '4': dvander@276: case '5': dvander@276: case '6': dvander@276: case '7': dvander@276: case '8': dvander@276: case '9': dvander@276: { dvander@276: n = 0; dvander@276: do dvander@276: { dvander@276: n = 10 * n + (ch - '0'); dvander@276: ch = *fmt++; dvander@276: } while(is_digit(ch)); dvander@276: width = n; dvander@276: goto reswitch; dvander@276: } dvander@276: case 'c': dvander@276: { dvander@276: if (!llen) dvander@276: { dvander@276: goto done; dvander@276: } dvander@276: char *c = (char *)args[arg]; dvander@276: *buf_p++ = *c; dvander@276: llen--; dvander@276: arg++; dvander@276: break; dvander@276: } dvander@276: case 'd': dvander@276: case 'i': dvander@276: { dvander@276: int *value = (int *)args[arg]; dvander@276: AddInt(&buf_p, llen, *value, width, flags); dvander@276: arg++; dvander@276: break; dvander@276: } dvander@276: case 'u': dvander@276: { dvander@276: unsigned int *value = (unsigned int *)args[arg]; dvander@276: AddUInt(&buf_p, llen, *value, width, flags); dvander@276: arg++; dvander@276: break; dvander@276: } dvander@276: case 'f': dvander@276: { dvander@276: float *value = (float *)args[arg]; dvander@276: AddFloat(&buf_p, llen, *value, width, prec); dvander@276: arg++; dvander@276: break; dvander@276: } dvander@276: case 's': dvander@276: { dvander@276: const char *str = (const char *)args[arg]; dvander@276: AddString(&buf_p, llen, str, width, prec); dvander@276: arg++; dvander@276: break; dvander@276: } ds@544: case 'X': ds@544: { ds@544: unsigned int *value = (unsigned int *)args[arg]; ds@544: flags |= UPPERDIGITS; ds@544: AddHex(&buf_p, llen, *value, width, flags); ds@544: arg++; ds@544: break; ds@544: } ds@544: case 'x': ds@544: { ds@544: unsigned int *value = (unsigned int *)args[arg]; ds@544: AddHex(&buf_p, llen, *value, width, flags); ds@544: arg++; ds@544: break; ds@544: } dvander@276: case '%': dvander@276: { dvander@276: if (!llen) dvander@276: { dvander@276: goto done; dvander@276: } dvander@276: *buf_p++ = ch; dvander@276: llen--; dvander@276: break; dvander@276: } dvander@276: case '\0': dvander@276: { dvander@276: if (!llen) dvander@276: { dvander@276: goto done; dvander@276: } dvander@276: *buf_p++ = '%'; dvander@276: llen--; dvander@276: goto done; dvander@276: } dvander@276: default: dvander@276: { dvander@276: if (!llen) dvander@276: { dvander@276: goto done; dvander@276: } dvander@276: *buf_p++ = ch; dvander@276: llen--; dvander@276: break; dvander@276: } dvander@276: } dvander@276: } dvander@276: dvander@276: done: dvander@276: *buf_p = '\0'; dvander@276: dvander@276: return (maxlen - llen - 1); dvander@276: } dvander@276: faluco@227: size_t atcprintf(char *buffer, size_t maxlen, const char *format, IPluginContext *pCtx, const cell_t *params, int *param) faluco@227: { dvander@276: if (!buffer || !maxlen) dvander@276: { dvander@276: return 0; dvander@276: } dvander@276: faluco@227: int arg; faluco@288: int args = params[0]; faluco@227: char *buf_p; faluco@227: char ch; faluco@227: int flags; faluco@227: int width; faluco@227: int prec; faluco@227: int n; faluco@227: char sign; faluco@227: const char *fmt; faluco@230: size_t llen = maxlen - 1; faluco@227: faluco@227: buf_p = buffer; faluco@227: arg = *param; faluco@227: fmt = format; faluco@227: faluco@227: while (true) faluco@227: { faluco@227: // run through the format string until we hit a '%' or '\0' faluco@227: for (ch = *fmt; llen && ((ch = *fmt) != '\0') && (ch != '%'); fmt++) faluco@227: { faluco@227: *buf_p++ = ch; faluco@227: llen--; faluco@227: } faluco@227: if ((ch == '\0') || (llen <= 0)) faluco@227: { faluco@227: goto done; faluco@227: } faluco@227: faluco@227: // skip over the '%' faluco@227: fmt++; faluco@227: faluco@227: // reset formatting state faluco@227: flags = 0; faluco@227: width = 0; faluco@227: prec = -1; faluco@227: sign = '\0'; faluco@227: faluco@227: rflag: faluco@227: ch = *fmt++; faluco@227: reswitch: faluco@227: switch(ch) faluco@227: { faluco@227: case '-': faluco@227: { faluco@227: flags |= LADJUST; faluco@227: goto rflag; faluco@227: } faluco@227: case '.': faluco@227: { faluco@227: n = 0; faluco@227: while(is_digit((ch = *fmt++))) faluco@227: { faluco@227: n = 10 * n + (ch - '0'); faluco@227: } faluco@227: prec = (n < 0) ? -1 : n; faluco@227: goto reswitch; faluco@227: } faluco@227: case '0': faluco@227: { faluco@227: flags |= ZEROPAD; faluco@227: goto rflag; faluco@227: } faluco@227: case '1': faluco@227: case '2': faluco@227: case '3': faluco@227: case '4': faluco@227: case '5': faluco@227: case '6': faluco@227: case '7': faluco@227: case '8': faluco@227: case '9': faluco@227: { faluco@227: n = 0; faluco@227: do faluco@227: { faluco@227: n = 10 * n + (ch - '0'); faluco@227: ch = *fmt++; faluco@227: } while(is_digit(ch)); faluco@227: width = n; faluco@227: goto reswitch; faluco@227: } faluco@227: case 'c': faluco@227: { faluco@227: CHECK_ARGS(0); faluco@230: if (!llen) faluco@227: { faluco@227: goto done; faluco@227: } faluco@227: char *c; faluco@227: pCtx->LocalToString(params[arg], &c); faluco@227: *buf_p++ = *c; faluco@227: llen--; faluco@227: arg++; faluco@227: break; faluco@227: } faluco@227: case 'd': faluco@227: case 'i': faluco@227: { faluco@227: CHECK_ARGS(0); faluco@227: cell_t *value; faluco@227: pCtx->LocalToPhysAddr(params[arg], &value); faluco@227: AddInt(&buf_p, llen, static_cast(*value), width, flags); faluco@227: arg++; faluco@227: break; faluco@227: } faluco@227: case 'u': faluco@227: { faluco@227: CHECK_ARGS(0); faluco@227: cell_t *value; faluco@227: pCtx->LocalToPhysAddr(params[arg], &value); faluco@227: AddUInt(&buf_p, llen, static_cast(*value), width, flags); faluco@227: arg++; faluco@227: break; faluco@227: } faluco@227: case 'f': faluco@227: { faluco@227: CHECK_ARGS(0); faluco@227: cell_t *value; faluco@227: pCtx->LocalToPhysAddr(params[arg], &value); dvander@233: AddFloat(&buf_p, llen, sp_ctof(*value), width, prec); faluco@227: arg++; faluco@227: break; faluco@227: } faluco@227: case 's': faluco@227: { faluco@227: CHECK_ARGS(0); faluco@227: char *str; dvander@535: int err; dvander@535: if ((err=pCtx->LocalToString(params[arg], &str)) != SP_ERROR_NONE) dvander@535: { dvander@535: pCtx->ThrowNativeErrorEx(err, "Could not deference string"); dvander@535: return 0; dvander@535: } faluco@227: AddString(&buf_p, llen, str, width, prec); faluco@227: arg++; faluco@227: break; faluco@227: } faluco@389: case 'T': faluco@389: { faluco@389: CHECK_ARGS(0); faluco@389: char *key; faluco@422: bool error; faluco@422: size_t res; faluco@389: cell_t target = params[arg++]; faluco@389: pCtx->LocalToString(params[arg++], &key); faluco@422: res = Translate(buf_p, llen, pCtx, key, target, params, &arg, &error); faluco@422: if (error) faluco@422: { faluco@422: return 0; faluco@422: } faluco@422: buf_p += res; faluco@422: llen -= res; faluco@422: break; faluco@422: } faluco@422: case 't': faluco@422: { faluco@422: CHECK_ARGS(0); faluco@422: char *key; faluco@422: bool error; faluco@422: size_t res; faluco@422: cell_t target = g_SourceMod.GetGlobalTarget(); faluco@422: pCtx->LocalToString(params[arg++], &key); faluco@422: res = Translate(buf_p, llen, pCtx, key, target, params, &arg, &error); faluco@422: if (error) faluco@422: { faluco@422: return 0; faluco@422: } faluco@422: buf_p += res; faluco@422: llen -= res; faluco@389: break; faluco@389: } ds@544: case 'X': ds@544: { ds@544: CHECK_ARGS(0); ds@544: cell_t *value; ds@544: pCtx->LocalToPhysAddr(params[arg], &value); ds@544: flags |= UPPERDIGITS; ds@544: AddHex(&buf_p, llen, static_cast(*value), width, flags); ds@544: arg++; ds@544: break; ds@544: } ds@544: case 'x': ds@544: { ds@544: CHECK_ARGS(0); ds@544: cell_t *value; ds@544: pCtx->LocalToPhysAddr(params[arg], &value); ds@544: AddHex(&buf_p, llen, static_cast(*value), width, flags); ds@544: arg++; ds@544: break; ds@544: } faluco@227: case '%': faluco@227: { faluco@230: if (!llen) faluco@227: { faluco@227: goto done; faluco@227: } faluco@227: *buf_p++ = ch; faluco@227: llen--; faluco@227: break; faluco@227: } faluco@227: case '\0': faluco@227: { faluco@230: if (!llen) faluco@227: { faluco@227: goto done; faluco@227: } faluco@227: *buf_p++ = '%'; faluco@227: llen--; faluco@227: goto done; faluco@227: } faluco@227: default: faluco@227: { faluco@230: if (!llen) faluco@227: { faluco@227: goto done; faluco@227: } faluco@227: *buf_p++ = ch; faluco@227: llen--; faluco@227: break; faluco@227: } faluco@227: } faluco@227: } faluco@227: faluco@227: done: faluco@227: *buf_p = '\0'; faluco@227: *param = arg; faluco@236: return (maxlen - llen - 1); faluco@227: } faluco@230: faluco@230: const char *stristr(const char *str, const char *substr) faluco@230: { faluco@230: if (!*substr) faluco@230: { faluco@230: return ((char *)str); faluco@230: } faluco@230: faluco@230: char *needle = (char *)substr; faluco@230: char *prevloc = (char *)str; faluco@230: char *haystack = (char *)str; faluco@230: faluco@230: while (*haystack) faluco@230: { faluco@230: if (tolower(*haystack) == tolower(*needle)) faluco@230: { faluco@230: haystack++; faluco@230: if (!*++needle) faluco@230: { faluco@230: return prevloc; faluco@230: } faluco@230: } else { faluco@230: haystack = ++prevloc; faluco@230: needle = (char *)substr; faluco@230: } faluco@230: } faluco@230: faluco@230: return NULL; faluco@230: } faluco@230: dvander@233: unsigned int strncopy(char *dest, const char *src, size_t count) faluco@230: { faluco@230: if (!count) faluco@230: { faluco@230: return 0; faluco@230: } faluco@230: faluco@230: char *start = dest; faluco@230: while ((*src) && (--count)) faluco@230: { faluco@230: *dest++ = *src++; faluco@230: } faluco@230: *dest = '\0'; faluco@230: faluco@230: return (dest - start); faluco@230: } faluco@274: faluco@274: size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) faluco@274: { faluco@274: va_list ap; faluco@274: va_start(ap, fmt); faluco@274: size_t len = vsnprintf(buffer, maxlength, fmt, ap); faluco@274: va_end(ap); faluco@274: faluco@651: if (len >= maxlength) faluco@651: { faluco@651: buffer[maxlength - 1] = '\0'; faluco@651: return (maxlength - 1); faluco@651: } else { faluco@651: return len; faluco@651: } dvander@351: } dvander@351: ds@504: char *sm_strdup(const char *str) ds@504: { ds@504: char *ptr = new char[strlen(str)+1]; ds@504: strcpy(ptr, str); ds@504: return ptr; ds@504: }