/** \file * \brief Iup API in Lua * * See Copyright Notice in "iup.h" */ #include #include #include #include #include #include "iup.h" #include "iuplua.h" #include "il.h" #include "iup_str.h" #include "iup_predial.h" #define ALLOC(n,t) ((t *)calloc((n),sizeof(t))) #define REQUIRE(b) {if (!(b)) goto cleanup;} void iupluaScanf(void) { char *format; int i; int fields; int *width = NULL; int *scroll = NULL; char **prompt = NULL; char **text = NULL; char *title = NULL; char *s = NULL; char *s1 = NULL; char *outf = NULL; int indParam; /* va_list va; */ format = luaL_check_string(1); fields = iupStrCountChar(format, '\n') - 1; REQUIRE(fields > 0); width = ALLOC(fields, int); REQUIRE(width != NULL); scroll = ALLOC(fields, int); REQUIRE(scroll != NULL); prompt = ALLOC(fields, char *); REQUIRE(prompt != NULL); text = ALLOC(fields, char *); REQUIRE(text != NULL); indParam = 2; /* va_start(va,format); */ REQUIRE((s1 = s = (char *) iupStrDup(format)) != NULL); title = iupStrCopyUntil(&s, '\n'); REQUIRE(title != NULL); for (i = 0; i < fields; ++i) { int n; prompt[i] = iupStrCopyUntil(&s, '%'); REQUIRE(prompt[i] != NULL); n = sscanf(s, "%d.%d", width + i, scroll + i); REQUIRE(n == 2); s = strchr(s, '%'); REQUIRE(s != NULL); if (outf) free(outf); outf = iupStrCopyUntil(&s, '\n'); text[i] = ALLOC(width[i] + 1, char); REQUIRE(text[i] != NULL); switch (s[-2]) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': if (s[-3] == 'l') sprintf(text[i], outf, luaL_check_long(indParam++)); else if (s[-3] == 'h') sprintf(text[i], outf, (short)luaL_check_int(indParam++)); else sprintf(text[i], outf, luaL_check_int(indParam++)); break; case 'e': case 'f': case 'g': case 'E': case 'G': if (s[-3] == 'l') sprintf(text[i], outf, luaL_check_number(indParam++)); else sprintf(text[i], outf, (float)luaL_check_number(indParam++)); break; case 's': sprintf(text[i], outf, (char *)luaL_check_string(indParam++)); break; default: goto cleanup; } } /* va_end(va); */ REQUIRE(iupDataEntry(fields, width, scroll, title, prompt, text)>0); /* va_start(va,format); */ s = strchr(format, '\n') + 1; for (i = 0; i < fields; ++i) { s = strchr(s, '\n') + 1; switch (s[-2]) { case 'd': case 'u': if (s[-3] == 'l') { long l = 0; sscanf(text[i], "%ld", &l); lua_pushnumber(l); } else if (s[-3] == 'h') { short l = 0; sscanf(text[i], "%hd", &l); lua_pushnumber(l); } else { int l = 0; sscanf(text[i], "%d", &l); lua_pushnumber(l); } break; case 'i': case 'o': case 'x': case 'X': if (s[-3] == 'l') { long l = 0; sscanf(text[i], "%li", &l); lua_pushnumber(l); } else if (s[-3] == 'h') { short l = 0; sscanf(text[i], "%hi", &l); lua_pushnumber(l); } else { int l = 0; sscanf(text[i], "%i", &l); lua_pushnumber(l); } break; case 'e': case 'f': case 'g': case 'E': case 'G': if (s[-3] == 'l') { double l = 0; sscanf(text[i], "%lg", &l); lua_pushnumber(l); } else { float l = 0; sscanf(text[i], "%g", &l); lua_pushnumber(l); } break; case 's': lua_pushstring(text[i]); break; } } /* va_end(va); */ cleanup: if (s1) free(s1); if (title) free(title); if (width) free(width); if (scroll) free(scroll); if (outf) free(outf); if (prompt) { for (i = 0; i < fields; ++i) if (prompt[i]) free(prompt[i]); free(prompt); } if (text) { for (i = 0; i < fields; ++i) if (text[i]) free(text[i]); free(text); } }