198 lines
4.3 KiB
C
198 lines
4.3 KiB
C
|
/** \file
|
||
|
* \brief IUP binding for Lua 5.
|
||
|
* IupScanf special implementation.
|
||
|
*
|
||
|
* See Copyright Notice in "iup.h"
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <lua.h>
|
||
|
#include <lauxlib.h>
|
||
|
|
||
|
#include "iup.h"
|
||
|
#include "iuplua.h"
|
||
|
|
||
|
#include "il.h"
|
||
|
|
||
|
#include "iup_str.h"
|
||
|
#include "iup_predialogs.h"
|
||
|
|
||
|
#define ALLOC(n,t) ((t *)calloc((n),sizeof(t)))
|
||
|
#define REQUIRE(b) {if (!(b)) goto cleanup;}
|
||
|
|
||
|
int iupluaScanf(lua_State *L)
|
||
|
{
|
||
|
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; */
|
||
|
int total = 0;
|
||
|
|
||
|
format = (char*)luaL_checkstring(L, 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 = iupStrDupUntil((const char**)&s, '\n');
|
||
|
REQUIRE(title != NULL);
|
||
|
for (i = 0; i < fields; ++i) {
|
||
|
int n;
|
||
|
prompt[i] = iupStrDupUntil((const char**)&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 = iupStrDupUntil((const char**)&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, (long)luaL_checkinteger(L, indParam++));
|
||
|
else if (s[-3] == 'h')
|
||
|
sprintf(text[i], outf, (short)luaL_checkinteger(L, indParam++));
|
||
|
else
|
||
|
sprintf(text[i], outf, (int)luaL_checkinteger(L, indParam++));
|
||
|
break;
|
||
|
case 'e':
|
||
|
case 'f':
|
||
|
case 'g':
|
||
|
case 'E':
|
||
|
case 'G':
|
||
|
if (s[-3] == 'l')
|
||
|
sprintf(text[i], outf, (double)luaL_checknumber(L, indParam++));
|
||
|
else
|
||
|
sprintf(text[i], outf, (float)luaL_checknumber(L, indParam++));
|
||
|
break;
|
||
|
case 's':
|
||
|
sprintf(text[i], outf, (char *)luaL_checkstring(L, 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_pushinteger(L, l);
|
||
|
total++;
|
||
|
} else if (s[-3] == 'h') {
|
||
|
short l = 0;
|
||
|
sscanf(text[i], "%hd", &l);
|
||
|
lua_pushinteger(L, l);
|
||
|
total++;
|
||
|
} else {
|
||
|
int l = 0;
|
||
|
sscanf(text[i], "%d", &l);
|
||
|
lua_pushinteger(L, l);
|
||
|
total++;
|
||
|
}
|
||
|
break;
|
||
|
case 'i':
|
||
|
case 'o':
|
||
|
case 'x':
|
||
|
case 'X':
|
||
|
if (s[-3] == 'l') {
|
||
|
long l = 0;
|
||
|
sscanf(text[i], "%li", &l);
|
||
|
lua_pushinteger(L, l);
|
||
|
total++;
|
||
|
} else if (s[-3] == 'h') {
|
||
|
short l = 0;
|
||
|
sscanf(text[i], "%hi", &l);
|
||
|
lua_pushinteger(L, l);
|
||
|
total++;
|
||
|
} else {
|
||
|
int l = 0;
|
||
|
sscanf(text[i], "%i", &l);
|
||
|
lua_pushinteger(L, l);
|
||
|
total++;
|
||
|
}
|
||
|
break;
|
||
|
case 'e':
|
||
|
case 'f':
|
||
|
case 'g':
|
||
|
case 'E':
|
||
|
case 'G':
|
||
|
if (s[-3] == 'l') {
|
||
|
double l = 0;
|
||
|
sscanf(text[i], "%lf", &l);
|
||
|
lua_pushnumber(L, l);
|
||
|
total++;
|
||
|
} else {
|
||
|
float l = 0;
|
||
|
sscanf(text[i], "%f", &l);
|
||
|
lua_pushnumber(L, l);
|
||
|
total++;
|
||
|
}
|
||
|
break;
|
||
|
case 's':
|
||
|
lua_pushstring(L, text[i]);
|
||
|
total++;
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
|