2 Unix SMB/CIFS implementation.
4 provide access to string functions
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "scripting/ejs/smbcalls.h"
25 #include "lib/ejs/ejs.h"
26 #include "system/passwd.h"
30 var len = strlen(str);
32 static int ejs_strlen(MprVarHandle eid, int argc, char **argv)
35 ejsSetErrorMsg(eid, "strlen invalid arguments");
38 mpr_Return(eid, mprCreateIntegerVar(strlen_m(argv[0])));
44 var s = strlower("UPPER");
46 static int ejs_strlower(MprVarHandle eid, int argc, char **argv)
50 ejsSetErrorMsg(eid, "strlower invalid arguments");
53 s = strlower_talloc(mprMemCtx(), argv[0]);
54 mpr_Return(eid, mprString(s));
61 var s = strupper("lower");
63 static int ejs_strupper(MprVarHandle eid, int argc, char **argv)
67 ejsSetErrorMsg(eid, "strupper invalid arguments");
70 s = strupper_talloc(mprMemCtx(), argv[0]);
71 mpr_Return(eid, mprString(s));
78 list = split(".", "a.foo.bar");
80 NOTE: does not take a regular expression, unlink perl split()
82 static int ejs_split(MprVarHandle eid, int argc, char **argv)
84 const char *separator;
88 TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
90 ejsSetErrorMsg(eid, "split invalid arguments");
96 ret = mprObject("list");
98 while ((p = strstr(s, separator))) {
99 char *s2 = talloc_strndup(tmp_ctx, s, (int)(p-s));
100 mprAddArray(&ret, count++, mprString(s2));
102 s = p + strlen(separator);
105 mprAddArray(&ret, count++, mprString(s));
107 talloc_free(tmp_ctx);
108 mpr_Return(eid, ret);
115 str = join("DC=", list);
117 static int ejs_join(MprVarHandle eid, int argc, struct MprVar **argv)
120 const char *separator;
123 TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
125 argv[0]->type != MPR_TYPE_STRING ||
126 argv[1]->type != MPR_TYPE_OBJECT) {
127 ejsSetErrorMsg(eid, "join invalid arguments");
131 separator = mprToString(argv[0]);
132 list = mprToArray(tmp_ctx, argv[1]);
134 if (list == NULL || list[0] == NULL) {
135 talloc_free(tmp_ctx);
136 mpr_Return(eid, mprString(NULL));
140 ret = talloc_strdup(tmp_ctx, list[0]);
144 for (i=1;list[i];i++) {
145 ret = talloc_asprintf_append(ret, "%s%s", separator, list[i]);
150 mpr_Return(eid, mprString(ret));
151 talloc_free(tmp_ctx);
154 ejsSetErrorMsg(eid, "out of memory");
160 blergh, C certainly makes this hard!
162 str = sprintf("i=%d s=%7s", 7, "foo");
164 static int ejs_sprintf(MprVarHandle eid, int argc, struct MprVar **argv)
170 char *(*_asprintf_append)(char *, const char *, ...);
172 if (argc < 1 || argv[0]->type != MPR_TYPE_STRING) {
173 ejsSetErrorMsg(eid, "sprintf invalid arguments");
176 format = mprToString(argv[0]);
177 tmp_ctx = talloc_new(mprMemCtx());
178 ret = talloc_strdup(tmp_ctx, "");
180 /* avoid all the format string warnings */
181 _asprintf_append = talloc_asprintf_append;
186 while ((p = strchr(format, '%'))) {
188 int len, len_count=0;
190 ret = talloc_asprintf_append(ret, "%*.*s",
191 (int)(p-format), (int)(p-format),
193 if (ret == NULL) goto failed;
194 format += (int)(p-format);
195 len = strcspn(p+1, "dxuiofgGpXeEFcs%") + 1;
196 fmt2 = talloc_strndup(tmp_ctx, p, len+1);
197 if (fmt2 == NULL) goto failed;
198 len_count = count_chars(fmt2, '*');
199 /* find the type string */
201 while (tstr > fmt2 && isalpha(tstr[-1])) {
204 if (strcmp(tstr, "%") == 0) {
205 ret = talloc_asprintf_append(ret, "%%");
213 argc < a + len_count + 1) {
214 ejsSetErrorMsg(eid, "sprintf: not enough arguments for format");
217 #define FMT_ARG(fn, type) do { \
218 switch (len_count) { \
220 ret = _asprintf_append(ret, fmt2, \
221 (type)fn(argv[a])); \
224 ret = _asprintf_append(ret, fmt2, \
225 (int)mprVarToNumber(argv[a]), \
226 (type)fn(argv[a+1])); \
229 ret = _asprintf_append(ret, fmt2, \
230 (int)mprVarToNumber(argv[a]), \
231 (int)mprVarToNumber(argv[a+1]), \
232 (type)fn(argv[a+2])); \
235 a += len_count + 1; \
241 if (strcmp(tstr, "s")==0) FMT_ARG(mprToString, const char *);
242 else if (strcmp(tstr, "c")==0) FMT_ARG(*mprToString, char);
243 else if (strcmp(tstr, "d")==0) FMT_ARG(mprVarToNumber, int);
244 else if (strcmp(tstr, "ld")==0) FMT_ARG(mprVarToNumber, long);
245 else if (strcmp(tstr, "lld")==0) FMT_ARG(mprVarToNumber, long long);
246 else if (strcmp(tstr, "x")==0) FMT_ARG(mprVarToNumber, int);
247 else if (strcmp(tstr, "lx")==0) FMT_ARG(mprVarToNumber, long);
248 else if (strcmp(tstr, "llx")==0) FMT_ARG(mprVarToNumber, long long);
249 else if (strcmp(tstr, "X")==0) FMT_ARG(mprVarToNumber, int);
250 else if (strcmp(tstr, "lX")==0) FMT_ARG(mprVarToNumber, long);
251 else if (strcmp(tstr, "llX")==0) FMT_ARG(mprVarToNumber, long long);
252 else if (strcmp(tstr, "u")==0) FMT_ARG(mprVarToNumber, int);
253 else if (strcmp(tstr, "lu")==0) FMT_ARG(mprVarToNumber, long);
254 else if (strcmp(tstr, "llu")==0) FMT_ARG(mprVarToNumber, long long);
255 else if (strcmp(tstr, "i")==0) FMT_ARG(mprVarToNumber, int);
256 else if (strcmp(tstr, "li")==0) FMT_ARG(mprVarToNumber, long);
257 else if (strcmp(tstr, "lli")==0) FMT_ARG(mprVarToNumber, long long);
258 else if (strcmp(tstr, "o")==0) FMT_ARG(mprVarToNumber, int);
259 else if (strcmp(tstr, "lo")==0) FMT_ARG(mprVarToNumber, long);
260 else if (strcmp(tstr, "llo")==0) FMT_ARG(mprVarToNumber, long long);
261 else if (strcmp(tstr, "f")==0) FMT_ARG(mprVarToFloat, double);
262 else if (strcmp(tstr, "lf")==0) FMT_ARG(mprVarToFloat, double);
263 else if (strcmp(tstr, "g")==0) FMT_ARG(mprVarToFloat, double);
264 else if (strcmp(tstr, "lg")==0) FMT_ARG(mprVarToFloat, double);
265 else if (strcmp(tstr, "e")==0) FMT_ARG(mprVarToFloat, double);
266 else if (strcmp(tstr, "le")==0) FMT_ARG(mprVarToFloat, double);
267 else if (strcmp(tstr, "E")==0) FMT_ARG(mprVarToFloat, double);
268 else if (strcmp(tstr, "lE")==0) FMT_ARG(mprVarToFloat, double);
269 else if (strcmp(tstr, "F")==0) FMT_ARG(mprVarToFloat, double);
270 else if (strcmp(tstr, "lF")==0) FMT_ARG(mprVarToFloat, double);
272 ejsSetErrorMsg(eid, "sprintf: unknown format string '%s'", fmt2);
278 ret = talloc_asprintf_append(ret, "%s", format);
279 mpr_Return(eid, mprString(ret));
280 talloc_free(tmp_ctx);
284 talloc_free(tmp_ctx);
289 used to build your own print function
290 str = vsprintf(args);
292 static int ejs_vsprintf(MprVarHandle eid, int argc, struct MprVar **argv)
294 struct MprVar **args, *len, *v;
296 if (argc != 1 || argv[0]->type != MPR_TYPE_OBJECT) {
297 ejsSetErrorMsg(eid, "vsprintf invalid arguments");
301 len = mprGetProperty(v, "length", NULL);
303 ejsSetErrorMsg(eid, "vsprintf takes an array");
306 length = mprToInt(len);
307 args = talloc_array(mprMemCtx(), struct MprVar *, length);
312 for (i=0;i<length;i++) {
314 mprItoa(i, idx, sizeof(idx));
315 args[i] = mprGetProperty(v, idx, NULL);
318 ret = ejs_sprintf(eid, length, args);
324 setup C functions that be called from ejs
326 void smb_setup_ejs_string(void)
328 ejsDefineStringCFunction(-1, "strlen", ejs_strlen, NULL, MPR_VAR_SCRIPT_HANDLE);
329 ejsDefineStringCFunction(-1, "strlower", ejs_strlower, NULL, MPR_VAR_SCRIPT_HANDLE);
330 ejsDefineStringCFunction(-1, "strupper", ejs_strupper, NULL, MPR_VAR_SCRIPT_HANDLE);
331 ejsDefineStringCFunction(-1, "split", ejs_split, NULL, MPR_VAR_SCRIPT_HANDLE);
332 ejsDefineCFunction(-1, "join", ejs_join, NULL, MPR_VAR_SCRIPT_HANDLE);
333 ejsDefineCFunction(-1, "sprintf", ejs_sprintf, NULL, MPR_VAR_SCRIPT_HANDLE);
334 ejsDefineCFunction(-1, "vsprintf", ejs_vsprintf, NULL, MPR_VAR_SCRIPT_HANDLE);