diff options
Diffstat (limited to 'source4/scripting/ejs/smbcalls_string.c')
-rw-r--r-- | source4/scripting/ejs/smbcalls_string.c | 133 |
1 files changed, 122 insertions, 11 deletions
diff --git a/source4/scripting/ejs/smbcalls_string.c b/source4/scripting/ejs/smbcalls_string.c index b729f5dd3a2..7a19ecdf2ca 100644 --- a/source4/scripting/ejs/smbcalls_string.c +++ b/source4/scripting/ejs/smbcalls_string.c @@ -141,23 +141,134 @@ failed: return -1; } + /* - load a file as a string + blergh, C certainly makes this hard! usage: - string = FileLoad(filename); + str = sprintf("i=%d s=%7s", 7, "foo"); */ -static int ejs_FileLoad(MprVarHandle eid, int argc, char **argv) +static int ejs_sprintf(MprVarHandle eid, int argc, struct MprVar **argv) { - char *s; - if (argc != 1) { - ejsSetErrorMsg(eid, "FileLoad invalid arguments"); + const char *format; + const char *p; + char *ret; + int a = 1; + char *(*_asprintf_append)(char *, const char *, ...); + TALLOC_CTX *tmp_ctx; + if (argc < 1 || argv[0]->type != MPR_TYPE_STRING) { + ejsSetErrorMsg(eid, "sprintf invalid arguments"); return -1; } + format = mprToString(argv[0]); + tmp_ctx = talloc_new(mprMemCtx()); + ret = talloc_strdup(tmp_ctx, ""); - s = file_load(argv[0], NULL, mprMemCtx()); - mpr_Return(eid, mprString(s)); - talloc_free(s); - return 0; + /* avoid all the format string warnings */ + _asprintf_append = talloc_asprintf_append; + + /* + hackity hack ... + */ + while ((p = strchr(format, '%'))) { + char *fmt2; + int len, len_count=0; + char *tstr; + ret = talloc_asprintf_append(ret, "%*.*s", + (int)(p-format), (int)(p-format), + format); + if (ret == NULL) goto failed; + format += (int)(p-format); + len = strcspn(p+1, "dxuiofgGpXeEFcs%") + 1; + fmt2 = talloc_strndup(tmp_ctx, p, len+1); + if (fmt2 == NULL) goto failed; + len_count = count_chars(fmt2, '*'); + /* find the type string */ + tstr = &fmt2[len]; + while (tstr > fmt2 && isalpha(tstr[-1])) { + tstr--; + } + if (strcmp(tstr, "%") == 0) { + ret = talloc_asprintf_append(ret, "%%"); + if (ret == NULL) { + goto failed; + } + format += len+1; + continue; + } + if (len_count > 2 || + argc < a + len_count + 1) { + ejsSetErrorMsg(eid, "sprintf: not enough arguments for format"); + goto failed; + } +#define FMT_ARG(fn, type) do { \ + switch (len_count) { \ + case 0: \ + ret = _asprintf_append(ret, fmt2, \ + (type)fn(argv[a])); \ + break; \ + case 1: \ + ret = _asprintf_append(ret, fmt2, \ + (int)mprVarToNumber(argv[a]), \ + (type)fn(argv[a+1])); \ + break; \ + case 2: \ + ret = _asprintf_append(ret, fmt2, \ + (int)mprVarToNumber(argv[a]), \ + (int)mprVarToNumber(argv[a+1]), \ + (type)fn(argv[a+2])); \ + break; \ + } \ + a += len_count + 1; \ + if (ret == NULL) { \ + goto failed; \ + } \ +} while (0) + + if (strcmp(tstr, "s")==0) FMT_ARG(mprToString, const char *); + else if (strcmp(tstr, "c")==0) FMT_ARG(*mprToString, char); + else if (strcmp(tstr, "d")==0) FMT_ARG(mprVarToNumber, int); + else if (strcmp(tstr, "ld")==0) FMT_ARG(mprVarToNumber, long); + else if (strcmp(tstr, "lld")==0) FMT_ARG(mprVarToNumber, long long); + else if (strcmp(tstr, "x")==0) FMT_ARG(mprVarToNumber, int); + else if (strcmp(tstr, "lx")==0) FMT_ARG(mprVarToNumber, long); + else if (strcmp(tstr, "llx")==0) FMT_ARG(mprVarToNumber, long long); + else if (strcmp(tstr, "X")==0) FMT_ARG(mprVarToNumber, int); + else if (strcmp(tstr, "lX")==0) FMT_ARG(mprVarToNumber, long); + else if (strcmp(tstr, "llX")==0) FMT_ARG(mprVarToNumber, long long); + else if (strcmp(tstr, "u")==0) FMT_ARG(mprVarToNumber, int); + else if (strcmp(tstr, "lu")==0) FMT_ARG(mprVarToNumber, long); + else if (strcmp(tstr, "llu")==0) FMT_ARG(mprVarToNumber, long long); + else if (strcmp(tstr, "i")==0) FMT_ARG(mprVarToNumber, int); + else if (strcmp(tstr, "li")==0) FMT_ARG(mprVarToNumber, long); + else if (strcmp(tstr, "lli")==0) FMT_ARG(mprVarToNumber, long long); + else if (strcmp(tstr, "o")==0) FMT_ARG(mprVarToNumber, int); + else if (strcmp(tstr, "lo")==0) FMT_ARG(mprVarToNumber, long); + else if (strcmp(tstr, "llo")==0) FMT_ARG(mprVarToNumber, long long); + else if (strcmp(tstr, "f")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "lf")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "g")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "lg")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "e")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "le")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "E")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "lE")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "F")==0) FMT_ARG(mprVarToFloat, double); + else if (strcmp(tstr, "lF")==0) FMT_ARG(mprVarToFloat, double); + else { + ejsSetErrorMsg(eid, "sprintf: unknown format string '%s'", fmt2); + goto failed; + } + format += len+1; + } + + ret = talloc_asprintf_append(ret, "%s", format); + mpr_Return(eid, mprString(ret)); + talloc_free(tmp_ctx); + return 0; + +failed: + talloc_free(tmp_ctx); + return -1; } /* @@ -168,6 +279,6 @@ void smb_setup_ejs_string(void) ejsDefineStringCFunction(-1, "strlower", ejs_strlower, NULL, MPR_VAR_SCRIPT_HANDLE); ejsDefineStringCFunction(-1, "strupper", ejs_strupper, NULL, MPR_VAR_SCRIPT_HANDLE); ejsDefineStringCFunction(-1, "split", ejs_split, NULL, MPR_VAR_SCRIPT_HANDLE); - ejsDefineStringCFunction(-1, "FileLoad", ejs_FileLoad, NULL, MPR_VAR_SCRIPT_HANDLE); ejsDefineCFunction(-1, "join", ejs_join, NULL, MPR_VAR_SCRIPT_HANDLE); + ejsDefineCFunction(-1, "sprintf", ejs_sprintf, NULL, MPR_VAR_SCRIPT_HANDLE); } |