1036 lines
24 KiB
C
Executable File
1036 lines
24 KiB
C
Executable File
/** \file
|
|
* \brief LED to C converter
|
|
*
|
|
* See Copyright Notice in "iup.h"
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
|
|
#include "ledc.h"
|
|
|
|
#define alloc(type) ((type*)malloc(sizeof(type)))
|
|
|
|
static FILE* outfile = NULL;
|
|
static long vetsizepos;
|
|
|
|
/* used in y.tab.c */
|
|
char *filename;
|
|
char *outname = 0;
|
|
char *funcname = 0;
|
|
int nocode = 0;
|
|
int static_image = 0;
|
|
|
|
typedef struct {
|
|
char* name;
|
|
int used;
|
|
} Tname;
|
|
|
|
static Tlist* all_names;
|
|
static Tlist* all_elems;
|
|
static Tlist* all_images;
|
|
|
|
static Tlist* all_named;
|
|
static Tlist* all_late;
|
|
|
|
static int nerrors = 0;
|
|
|
|
#define nheaders 9
|
|
|
|
static struct {
|
|
char* name;
|
|
int used;
|
|
} headerfile[nheaders] = {
|
|
{ "iup", 1 },
|
|
{ "iupcontrols",0 },
|
|
{ "iupgl", 0 },
|
|
{ "iupglcontrols",0 },
|
|
{ "iupole", 0 },
|
|
{ "iupweb", 0 },
|
|
{ "iup_plot", 0 },
|
|
{ "iup_mglplot", 0 },
|
|
{ "iup_scintilla", 0 }
|
|
};
|
|
|
|
enum headers {
|
|
IUP_H,
|
|
IUPCONTROLS_H,
|
|
IUPGL_H,
|
|
IUPGLCONTROLS_H,
|
|
IUPOLE_H,
|
|
IUPWEB_H,
|
|
IUPPLOT_H,
|
|
IUPMGLPLOT_H,
|
|
IUPSCINTILLA_H
|
|
};
|
|
|
|
static void check_empty( Telem* elem );
|
|
static void check_image( Telem* elem );
|
|
static void check_imagergb( Telem* elem );
|
|
static void check_imagergba( Telem* elem );
|
|
static void check_string( Telem* elem );
|
|
static void check_string2( Telem* elem );
|
|
static void check_cb( Telem* elem );
|
|
static void check_elem( Telem* elem );
|
|
static void check_elemlist( Telem* elem );
|
|
static void check_elemlist2( Telem* elem );
|
|
static void check_elemlist_rep( Telem* elem );
|
|
static void check_string_cb( Telem* elem );
|
|
static void check_string_elem( Telem* elem );
|
|
static void check_unknown(Telem* elem);
|
|
|
|
static void code_image( Telem* elem );
|
|
static void code_unknown(Telem* elem);
|
|
static void code_empty( Telem* elem );
|
|
static void code_string( Telem* elem );
|
|
static void code_string2( Telem* elem );
|
|
static void code_elem( Telem* elem );
|
|
static void code_elemlist( Telem* elem );
|
|
static void code_elemlist2( Telem* elem );
|
|
static void code_string_elem( Telem* elem );
|
|
|
|
typedef void(*function)(Telem*);
|
|
|
|
#define IMAGE 0
|
|
#define IMAGERGB 1
|
|
#define IMAGERGBA 2
|
|
|
|
static struct {
|
|
char* name;
|
|
void (*code)(Telem*);
|
|
void (*check)(Telem*);
|
|
int header;
|
|
}
|
|
elems[] =
|
|
{
|
|
{ "Image", code_image, check_image, 0 },
|
|
{ "ImageRGB", code_image, check_imagergb, 0 },
|
|
{ "ImageRGBA", code_image, check_imagergba, 0 },
|
|
{ "Timer", code_empty, check_empty, 0 },
|
|
{ "User", code_empty, check_empty, 0 },
|
|
{ "Button", code_string2, check_string_cb, 0 },
|
|
{ "Canvas", code_string, check_cb, 0 },
|
|
{ "FlatButton", code_string, check_string, 0 },
|
|
{ "FlatToggle", code_string, check_string, 0 },
|
|
{ "Dialog", code_elem, check_elem, 0 },
|
|
{ "Fill", code_empty, check_empty, 0 },
|
|
{ "FileDlg", code_empty, check_empty, 0 },
|
|
{ "MessageDlg", code_empty, check_empty, 0 },
|
|
{ "ColorDlg", code_empty, check_empty, 0 },
|
|
{ "FontDlg", code_empty, check_empty, 0 },
|
|
{ "ProgressBar", code_empty, check_empty, 0 },
|
|
{ "Frame", code_elem, check_elem, 0 },
|
|
{ "FlatFrame", code_elem, check_elem, 0 },
|
|
{ "Hbox", code_elemlist, check_elemlist, 0 },
|
|
{ "Item", code_string2, check_string_cb, 0 },
|
|
{ "Label", code_string, check_string, 0 },
|
|
{ "FlatLabel", code_string, check_string, 0 },
|
|
{ "List", code_string, check_cb, 0 },
|
|
{ "FlatList", code_empty, check_empty, 0 },
|
|
{ "Sbox", code_elem, check_elem, 0 },
|
|
{ "ScrollBox", code_elem, check_elem, 0 },
|
|
{ "FlatScrollBox",code_elem, check_elem, 0 },
|
|
{ "DetachBox", code_elem, check_elem, 0 },
|
|
{ "BackgroundBox",code_elem, check_elem, 0 },
|
|
{ "Expander", code_elem, check_elem, 0 },
|
|
{ "DropButton", code_elem, check_elem, 0 },
|
|
{ "Menu", code_elemlist, check_elemlist, 0 },
|
|
{ "MultiLine", code_string, check_cb, 0 },
|
|
{ "Radio", code_elem, check_elem, 0 },
|
|
{ "Separator", code_empty, check_empty, 0 },
|
|
{ "Submenu", code_string_elem, check_string_elem, 0 },
|
|
{ "Text", code_string, check_cb, 0 },
|
|
{ "Val", code_string, check_string, 0 },
|
|
{ "FlatVal", code_string, check_string, 0 },
|
|
{ "FlatTree", code_empty, check_empty, 0 },
|
|
{ "Tree", code_empty, check_empty, 0 },
|
|
{ "Tabs", code_elemlist, check_elemlist, 0 },
|
|
{ "FlatTabs", code_elemlist, check_elemlist, 0 },
|
|
{ "Toggle", code_string2, check_string_cb, 0 },
|
|
{ "Vbox", code_elemlist, check_elemlist, 0 },
|
|
{ "Zbox", code_elemlist, check_elemlist, 0 },
|
|
{ "GridBox", code_elemlist, check_elemlist, 0 },
|
|
{ "MultiBox", code_elemlist, check_elemlist, 0 },
|
|
{ "Normalizer", code_elemlist, check_elemlist_rep,0 },
|
|
{ "Link", code_string2, check_string2, 0 },
|
|
{ "Cbox", code_elemlist, check_elemlist, 0 },
|
|
{ "FlatSeparator",code_empty, check_empty, 0 },
|
|
{ "Space", code_empty, check_empty, 0 },
|
|
{ "Spin", code_empty, check_empty, 0 },
|
|
{ "Spinbox", code_elem, check_elem, 0 },
|
|
{ "Split", code_elemlist2, check_elemlist2, 0 },
|
|
{ "Gauge", code_empty, check_empty, 0 },
|
|
{ "Colorbar", code_empty, check_empty, 0 },
|
|
{ "ColorBrowser", code_empty, check_empty, 0 },
|
|
{ "Dial", code_string, check_string, 0 },
|
|
{ "AnimatedLabel",code_elem, check_elem, 0 },
|
|
{ "Cells", code_empty, check_empty, IUPCONTROLS_H },
|
|
{ "Matrix", code_string, check_cb, IUPCONTROLS_H },
|
|
{ "MatrixList", code_empty, check_empty, IUPCONTROLS_H },
|
|
{ "MatrixEx", code_empty, check_empty, IUPCONTROLS_H },
|
|
{ "GLCanvas", code_string, check_cb, IUPGL_H },
|
|
{ "GLBackgroundBox", code_elem, check_elem, IUPGL_H },
|
|
{ "OleControl", code_string, check_cb, IUPOLE_H },
|
|
{ "Plot", code_empty, check_empty, IUPPLOT_H },
|
|
{ "MglPlot", code_empty, check_empty, IUPMGLPLOT_H },
|
|
{ "Scintilla", code_empty, check_empty, IUPSCINTILLA_H },
|
|
{ "WebBrowser", code_empty, check_empty, IUPWEB_H },
|
|
{ "GLCanvasBox", code_elemlist, check_elemlist, IUPGLCONTROLS_H },
|
|
{ "GLSubCanvas", code_empty, check_empty, IUPGLCONTROLS_H },
|
|
{ "GLLabel", code_string, check_string, IUPGLCONTROLS_H },
|
|
{ "GLSeparator", code_empty, check_empty, IUPGLCONTROLS_H },
|
|
{ "GLButton", code_string, check_string, IUPGLCONTROLS_H },
|
|
{ "GLToggle", code_string, check_string, IUPGLCONTROLS_H },
|
|
{ "GLText", code_string, check_empty, IUPGLCONTROLS_H },
|
|
{ "GLProgressBar",code_empty, check_empty, IUPGLCONTROLS_H },
|
|
{ "GLVal", code_empty, check_empty, IUPGLCONTROLS_H },
|
|
{ "GLLink", code_string2, check_string2, IUPGLCONTROLS_H },
|
|
{ "GLFrame", code_elem, check_elem, IUPGLCONTROLS_H },
|
|
{ "GLExpander", code_elem, check_elem, IUPGLCONTROLS_H },
|
|
{ "GLScrollBox", code_elem, check_elem, IUPGLCONTROLS_H },
|
|
{ "GLSizeBox", code_elem, check_elem, IUPGLCONTROLS_H },
|
|
{ "@@@", code_unknown, check_unknown, 0 }
|
|
};
|
|
#define nelems (sizeof(elems)/sizeof(elems[0]))
|
|
|
|
static int mystricmp(char *s1, char *s2)
|
|
{
|
|
int i = 0;
|
|
if (s1 == s2) return 0;
|
|
while ((int)s1[i] && (int)s2[i] && tolower((int)s1[i])==tolower((int)s2[i])) i++;
|
|
if (s1[i] == s2[i]) return 0;
|
|
else if (s1[i]<s2[i]) return -1;
|
|
return 1;
|
|
}
|
|
|
|
void error( char* fmt, ... )
|
|
{
|
|
va_list args;
|
|
fprintf(stderr, "%s:%d: error: ", filename, yylineno );
|
|
va_start(args, fmt);
|
|
vfprintf(stderr, fmt, args);
|
|
va_end(args);
|
|
fprintf(stderr, "\n" );
|
|
nerrors++;
|
|
}
|
|
|
|
static void warning( char* fmt, ... )
|
|
{
|
|
va_list args;
|
|
fprintf(stderr, "%s:%d: warning: ", filename, yylineno );
|
|
va_start(args, fmt);
|
|
vfprintf(stderr, fmt, args);
|
|
fprintf(stderr, "\n" );
|
|
va_end(args);
|
|
}
|
|
|
|
/* used in y.tab.c */
|
|
void named( char* name )
|
|
{
|
|
Tname *n = alloc(Tname);
|
|
n->name = name;
|
|
n->used = 0;
|
|
addlist( all_names, n );
|
|
}
|
|
|
|
/* used also in y.tab.c */
|
|
void checkused( char* name )
|
|
{
|
|
Telemlist* p = all_names->first;
|
|
if (!name) return;
|
|
while (p)
|
|
{
|
|
Tname* n = (Tname*)p->data;
|
|
|
|
if (!strcmp(name,n->name))
|
|
{
|
|
if (n->used)
|
|
error("element '%s' already used in line %d", name, n->used );
|
|
else
|
|
n->used = yylineno;
|
|
break;
|
|
}
|
|
p = p->next;
|
|
}
|
|
}
|
|
|
|
static int iselem( char* name )
|
|
{
|
|
Telemlist* p = all_names->first;
|
|
while (p)
|
|
{
|
|
Tname* n = (Tname*)p->data;
|
|
if (!strcmp(name,n->name)) return 1;
|
|
p = p->next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int verify_nparams( int min, int max, Telem* elem )
|
|
{
|
|
if (min!=-1 && elem->nparams < min )
|
|
{
|
|
error("too few arguments for %s", elem->elemname );
|
|
return 0;
|
|
}
|
|
if (max!=-1 && elem->nparams >max )
|
|
{
|
|
error("too many arguments for %s", elem->elemname );
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void param_elem( Tparam* p[], int n, int rep )
|
|
{
|
|
switch (p[n-1]->tag)
|
|
{
|
|
case ELEM_PARAM:
|
|
if (p[n-1]->data.elem->elemidx == IMAGE ||
|
|
p[n-1]->data.elem->elemidx == IMAGERGB ||
|
|
p[n-1]->data.elem->elemidx == IMAGERGBA )
|
|
error( "%s is not a valid child", p[n-1]->data.elem->elemname );
|
|
break;
|
|
case NAME_PARAM:
|
|
if (!iselem(p[n-1]->data.name))
|
|
warning( "undeclared control '%s' (argument #%d)", p[n-1]->data.name, n );
|
|
else if (!rep)
|
|
checkused( p[n-1]->data.name );
|
|
break;
|
|
case STRING_PARAM:
|
|
error( "control expected (argument #%d)", n );
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void param_string( Tparam* p[], int n )
|
|
{
|
|
switch (p[n-1]->tag)
|
|
{
|
|
case ELEM_PARAM:
|
|
error( "string expected (argument #%d)", n );
|
|
break;
|
|
case NAME_PARAM:
|
|
warning( "string expected (argument #%d)", n );
|
|
break;
|
|
case STRING_PARAM:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void param_number( Tparam* p[], int n )
|
|
{
|
|
switch (p[n-1]->tag)
|
|
{
|
|
case ELEM_PARAM:
|
|
error( "number expected (argument #%d)", n );
|
|
break;
|
|
case NAME_PARAM:
|
|
break;
|
|
case STRING_PARAM:
|
|
error( "number expected (argument #%d)", n );
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void param_callback( Tparam* p[], int n )
|
|
{
|
|
switch (p[n-1]->tag)
|
|
{
|
|
case ELEM_PARAM:
|
|
error( "callback expected (argument #%d)", n );
|
|
break;
|
|
case NAME_PARAM:
|
|
break;
|
|
case STRING_PARAM:
|
|
warning( "callback expected (argument #%d)", n );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
static void check_empty( Telem* elem )
|
|
{
|
|
verify_nparams( 0, 0, elem );
|
|
}
|
|
|
|
static void check_image( Telem* elem )
|
|
{
|
|
int i, w, h, size;
|
|
if (!verify_nparams( 2, -1, elem )) return;
|
|
param_number( elem->params, 1 );
|
|
param_number( elem->params, 2 );
|
|
w = atoi( elem->params[0]->data.name );
|
|
h = atoi( elem->params[1]->data.name );
|
|
size = w*h;
|
|
if (!verify_nparams( size+2, size+2, elem )) return;
|
|
for (i=0; i<size; i++)
|
|
param_number( elem->params, i+3 );
|
|
|
|
elem->data.image.w = w;
|
|
elem->data.image.h = h;
|
|
elem->data.image.d = 1;
|
|
}
|
|
|
|
static void check_imagergb( Telem* elem )
|
|
{
|
|
int i, w, h, size;
|
|
if (!verify_nparams( 2, -1, elem )) return;
|
|
param_number( elem->params, 1 );
|
|
param_number( elem->params, 2 );
|
|
w = atoi( elem->params[0]->data.name );
|
|
h = atoi( elem->params[1]->data.name );
|
|
size = w*h*3;
|
|
if (!verify_nparams( size+2, size+2, elem )) return;
|
|
for (i=0; i<size; i++)
|
|
param_number( elem->params, i+3 );
|
|
|
|
elem->data.image.w = w;
|
|
elem->data.image.h = h;
|
|
elem->data.image.d = 3;
|
|
}
|
|
|
|
static void check_imagergba( Telem* elem )
|
|
{
|
|
int i, w, h, size;
|
|
if (!verify_nparams( 2, -1, elem )) return;
|
|
param_number( elem->params, 1 );
|
|
param_number( elem->params, 2 );
|
|
w = atoi( elem->params[0]->data.name );
|
|
h = atoi( elem->params[1]->data.name );
|
|
size = w*h*4;
|
|
if (!verify_nparams( size+2, size+2, elem )) return;
|
|
for (i=0; i<size; i++)
|
|
param_number( elem->params, i+3 );
|
|
|
|
elem->data.image.w = w;
|
|
elem->data.image.h = h;
|
|
elem->data.image.d = 4;
|
|
}
|
|
|
|
static void check_string( Telem* elem )
|
|
{
|
|
if (!verify_nparams( 1, 1, elem )) return;
|
|
param_string( elem->params, 1 );
|
|
}
|
|
|
|
static void check_cb( Telem* elem )
|
|
{
|
|
if (!verify_nparams( 1, 1, elem )) return;
|
|
param_callback( elem->params, 1 );
|
|
}
|
|
|
|
static void check_elem( Telem* elem )
|
|
{
|
|
if (!verify_nparams( -1, 1, elem )) return;
|
|
if (elem->nparams == 1)
|
|
param_elem( elem->params, 1, 0 );
|
|
}
|
|
|
|
static void check_elemlist( Telem* elem )
|
|
{
|
|
int i;
|
|
if (!verify_nparams( -1, -1, elem )) return;
|
|
for (i=0; i<elem->nparams; i++)
|
|
param_elem( elem->params, i+1, 0 );
|
|
}
|
|
|
|
static void check_elemlist_rep( Telem* elem )
|
|
{
|
|
int i;
|
|
if (!verify_nparams( -1, -1, elem )) return;
|
|
for (i=0; i<elem->nparams; i++)
|
|
param_elem( elem->params, i+1, 1);
|
|
}
|
|
|
|
static void check_elemlist2( Telem* elem )
|
|
{
|
|
int i;
|
|
if (!verify_nparams( -1, 2, elem )) return;
|
|
for (i=0; i<elem->nparams; i++)
|
|
param_elem( elem->params, i+1, 0 );
|
|
}
|
|
|
|
static void check_string_cb( Telem* elem )
|
|
{
|
|
if (!verify_nparams( 2, 2, elem )) return;
|
|
param_string( elem->params, 1 );
|
|
param_callback( elem->params, 2 );
|
|
}
|
|
|
|
static void check_string2( Telem* elem )
|
|
{
|
|
if (!verify_nparams( 2, 2, elem )) return;
|
|
param_string( elem->params, 1 );
|
|
param_string( elem->params, 2 );
|
|
}
|
|
|
|
static void check_string_elem( Telem* elem )
|
|
{
|
|
if (!verify_nparams( 2, 2, elem )) return;
|
|
param_string( elem->params, 1 );
|
|
param_elem( elem->params, 2, 0 );
|
|
}
|
|
|
|
static void check_unknown(Telem* elem)
|
|
{
|
|
warning( "Unknown control %s used", elem->elemname );
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
static int indentcol = 0;
|
|
static int nameds = 0;
|
|
|
|
static void indent(void) { indentcol++; }
|
|
static void unindent(void) { indentcol--; }
|
|
|
|
static void codeindent(void)
|
|
{
|
|
int i;
|
|
for (i=0; i<indentcol; i++)
|
|
fprintf( outfile, " " );
|
|
}
|
|
|
|
static void generatename( Telem *e )
|
|
{
|
|
static char name[15];
|
|
if (e->name)
|
|
{
|
|
sprintf( name, "named[%d]", nameds++ );
|
|
e->codename = strdup( name );
|
|
addlist( all_named, e );
|
|
addlist( all_late, e );
|
|
}
|
|
else
|
|
{
|
|
e->codename = 0;
|
|
}
|
|
}
|
|
|
|
static int codename( Telem* elem )
|
|
{
|
|
if (elem->elemidx == IMAGE ||
|
|
elem->elemidx == IMAGERGB ||
|
|
elem->elemidx == IMAGERGBA )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (elem->name && elem->codename)
|
|
{
|
|
fprintf( outfile, "%s", elem->codename );
|
|
return 1;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static void codeelemname( Telem *elem )
|
|
{
|
|
if (elem->elemidx < nelems-1)
|
|
fprintf( outfile, "Iup%s", elems[elem->elemidx].name );
|
|
else
|
|
{
|
|
fprintf( outfile, "Iup%c%s", (char)toupper((int)elem->elemname[0]), elem->elemname+1 );
|
|
}
|
|
}
|
|
|
|
static void code_attrs( Telem* elem )
|
|
{
|
|
fprintf( outfile, ", " );
|
|
if (elem->attrs)
|
|
{
|
|
Telemlist *p = elem->attrs->first;
|
|
indent();
|
|
while (p)
|
|
{
|
|
fprintf( outfile, "\n" );
|
|
codeindent();
|
|
fprintf( outfile, "\"%s\", \"%s\", ",
|
|
((Tattr*)(p->data))->name, ((Tattr*)(p->data))->value );
|
|
p = p ->next;
|
|
}
|
|
unindent();
|
|
}
|
|
fprintf( outfile, "NULL )" );
|
|
}
|
|
|
|
static void code_start( Telem* elem )
|
|
{
|
|
codeindent();
|
|
if (elem->name &&
|
|
elem->elemidx != IMAGE &&
|
|
elem->elemidx != IMAGERGB &&
|
|
elem->elemidx != IMAGERGBA)
|
|
generatename( elem );
|
|
if ( codename( elem ) )
|
|
fprintf( outfile, " = " );
|
|
if (elem->name)
|
|
fprintf( outfile, "IupSetAtt( \"%s\", ", elem->name );
|
|
else
|
|
fprintf( outfile, "IupSetAtt( NULL, " );
|
|
codeelemname( elem );
|
|
}
|
|
|
|
static void code_c_name( char* name )
|
|
{
|
|
char *ant = name;
|
|
char *p = name;
|
|
while ( (p = strpbrk( p, "+-." )) != NULL )
|
|
{
|
|
char c = p[0];
|
|
p[0] = 0;
|
|
fprintf( outfile, "%s", ant );
|
|
switch (c)
|
|
{
|
|
case '+': fprintf( outfile, "%s", "_plus_" ); break;
|
|
case '-': fprintf( outfile, "%s", "_minus_" ); break;
|
|
case '.': fprintf( outfile, "%s", "_dot_" ); break;
|
|
}
|
|
p[0] = c;
|
|
ant = ++p;
|
|
}
|
|
fprintf( outfile, "%s", ant );
|
|
}
|
|
|
|
static void code_decl( Telem *e )
|
|
{
|
|
if (e->name || e->attrs)
|
|
{
|
|
code_start( e );
|
|
elems[e->elemidx].code( e );
|
|
code_attrs( e );
|
|
}
|
|
else
|
|
{
|
|
codeindent();
|
|
if (e->name &&
|
|
e->elemidx != IMAGE &&
|
|
e->elemidx != IMAGERGB &&
|
|
e->elemidx != IMAGERGBA)
|
|
generatename( e );
|
|
if ( codename( e ) )
|
|
fprintf( outfile, " = " );
|
|
codeelemname( e );
|
|
elems[e->elemidx].code( e );
|
|
}
|
|
}
|
|
|
|
static Telem* namedelem( char *name )
|
|
{
|
|
Telemlist* p = all_named->first;
|
|
while (p)
|
|
{
|
|
Telem* n = (Telem*)p->data;
|
|
if (!strcmp(n->name,name))
|
|
{
|
|
return n;
|
|
}
|
|
p = p->next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void codeelemparam( Tparam* param )
|
|
{
|
|
if (param->tag == ELEM_PARAM)
|
|
{
|
|
code_decl( param->data.elem );
|
|
}
|
|
else
|
|
{
|
|
Telem *e = namedelem( param->data.name );
|
|
codeindent();
|
|
if (e)
|
|
{
|
|
codename( e );
|
|
fprintf( outfile, " /* %s */", param->data.name );
|
|
}
|
|
else
|
|
{
|
|
fprintf( outfile, "IupGetHandle( \"%s\" )", param->data.name );
|
|
}
|
|
}
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
static void code_unknown(Telem* elem)
|
|
{
|
|
int i=0;
|
|
indent();
|
|
fprintf( outfile, "( " );
|
|
for (i=0; i<elem->nparams; i++)
|
|
{
|
|
if (elem->params[i]->tag == ELEM_PARAM)
|
|
{
|
|
fprintf( outfile, "\n" );
|
|
codeindent();
|
|
codeelemparam( elem->params[i] );
|
|
}
|
|
else
|
|
{
|
|
fprintf( outfile, "\"%s\"", elem->params[i]->data.name );
|
|
}
|
|
if (i+1<elem->nparams) fprintf( outfile, ", " );
|
|
}
|
|
fprintf( outfile, ")" );
|
|
unindent();
|
|
}
|
|
|
|
static void code_image( Telem* elem )
|
|
{
|
|
int i,
|
|
d = elem->data.image.d,
|
|
w = elem->data.image.w,
|
|
h = elem->data.image.h;
|
|
|
|
fprintf( outfile, "static void image_" );
|
|
code_c_name( elem->name );
|
|
fprintf( outfile,
|
|
" (void)\n"
|
|
"{\n"
|
|
" %sunsigned char map[] = {", static_image? "static ": "" );
|
|
|
|
for (i=0; i<w*h*d; i++)
|
|
{
|
|
if (i%(w*d) == 0) fprintf( outfile, "\n " );
|
|
fprintf( outfile, "%2d,", atoi(elem->params[i+2]->data.name) );
|
|
}
|
|
|
|
fprintf( outfile,
|
|
"\n"
|
|
" 0 };\n\n" );
|
|
indent();
|
|
code_start( elem );
|
|
fprintf( outfile, "( %d, %d, map )", elem->data.image.w, elem->data.image.h );
|
|
code_attrs( elem );
|
|
fprintf( outfile, ";\n}\n\n" );
|
|
unindent();
|
|
}
|
|
|
|
static void code_empty( Telem* elem )
|
|
{
|
|
(void) elem;
|
|
fprintf( outfile, "()" );
|
|
}
|
|
|
|
static void code_string( Telem* elem )
|
|
{
|
|
fprintf( outfile, "( \"%s\" )", elem->params[0]->data.name );
|
|
}
|
|
|
|
static void code_string2( Telem* elem )
|
|
{
|
|
fprintf( outfile, "( \"%s\", \"%s\" )", elem->params[0]->data.name, elem->params[1]->data.name );
|
|
}
|
|
|
|
static void code_elem( Telem* elem )
|
|
{
|
|
fprintf( outfile, "(\n" );
|
|
indent();
|
|
if (elem->nparams == 1)
|
|
{
|
|
codeelemparam( elem->params[0] );
|
|
fprintf( outfile, "\n" );
|
|
}
|
|
unindent();
|
|
codeindent();
|
|
if (elem->nparams == 1)
|
|
fprintf( outfile, ")" );
|
|
else
|
|
fprintf( outfile, "NULL)" );
|
|
}
|
|
|
|
static void code_elemlist( Telem* elem )
|
|
{
|
|
int i=0;
|
|
fprintf( outfile, "(\n" );
|
|
indent();
|
|
for (i=0; i<elem->nparams; i++)
|
|
{
|
|
codeelemparam( elem->params[i] );
|
|
fprintf( outfile, ",\n" );
|
|
}
|
|
unindent();
|
|
codeindent();
|
|
fprintf( outfile, "NULL)" );
|
|
}
|
|
|
|
static void code_elemlist2( Telem* elem )
|
|
{
|
|
int i=0;
|
|
fprintf( outfile, "(\n" );
|
|
indent();
|
|
for (i=0; i<2; i++)
|
|
{
|
|
if (i < elem->nparams)
|
|
codeelemparam( elem->params[i] );
|
|
else
|
|
fprintf( outfile, "NULL" );
|
|
|
|
if (i == 1)
|
|
fprintf( outfile, "\n" );
|
|
else
|
|
fprintf( outfile, ",\n" );
|
|
}
|
|
unindent();
|
|
codeindent();
|
|
fprintf( outfile, ")" );
|
|
}
|
|
|
|
static void code_string_elem( Telem* elem )
|
|
{
|
|
fprintf( outfile, "( \"%s\",\n", elem->params[0]->data.name );
|
|
indent();
|
|
codeelemparam( elem->params[1] );
|
|
fprintf( outfile, "\n" );
|
|
unindent();
|
|
codeindent();
|
|
fprintf( outfile, ")" );
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
static char* strlower( char* str )
|
|
{
|
|
int i=0;
|
|
while (str[i]) { str[i]=(char)tolower((int)str[i]); i++; }
|
|
return str;
|
|
}
|
|
|
|
static int lookupelem( char* name )
|
|
{
|
|
int i;
|
|
for (i=0; i<nelems && mystricmp(name, elems[i].name); i++ );
|
|
return i<nelems ? i : nelems-1;
|
|
}
|
|
|
|
Tattr* attr( char* name, char* value )
|
|
{
|
|
Tattr* ret = alloc(Tattr);
|
|
ret->name = name;
|
|
ret->value = value;
|
|
return ret;
|
|
}
|
|
|
|
Tparam* param( int tag, void* value )
|
|
{
|
|
Tparam* ret = alloc(Tparam);
|
|
ret->tag = tag;
|
|
switch (tag)
|
|
{
|
|
case NAME_PARAM:
|
|
case STRING_PARAM:
|
|
ret->data.name = (char*)value;
|
|
break;
|
|
case ELEM_PARAM:
|
|
ret->data.elem = (Telem*)value;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/* used in y.tab.c */
|
|
Telem* elem( char* name, Tlist* attrs, Tlist* params )
|
|
{
|
|
Telem* ret = alloc(Telem);
|
|
ret->name = 0;
|
|
ret->elemname = strlower(name);
|
|
ret->attrs = attrs;
|
|
if (params)
|
|
{
|
|
ret->nparams = params->size;
|
|
ret->params = list2param( params );
|
|
}
|
|
else
|
|
{
|
|
ret->nparams = 0;
|
|
ret->params = 0;
|
|
}
|
|
ret->elemidx = lookupelem( name );
|
|
elems[ret->elemidx].check(ret);
|
|
headerfile[elems[ret->elemidx].header].used = 1;
|
|
return ret;
|
|
}
|
|
|
|
Tlist* list( void )
|
|
{
|
|
Tlist* ret = alloc(Tlist);
|
|
ret->first = 0;
|
|
ret->size = 0;
|
|
return ret;
|
|
}
|
|
|
|
Tlist* addlist( Tlist* l, void* data )
|
|
{
|
|
Telemlist* ne = alloc(Telemlist);
|
|
ne->data = data;
|
|
ne->next = l->first;
|
|
l->first = ne;
|
|
l->size++;
|
|
return l;
|
|
}
|
|
|
|
void cleanlist( Tlist* l )
|
|
{
|
|
l->first = 0;
|
|
l->size = 0;
|
|
}
|
|
|
|
|
|
void decl( Telem* e )
|
|
{
|
|
if (!e->name) warning("%s declared without a name", e->elemname );
|
|
else
|
|
{
|
|
if (nerrors || nocode) return;
|
|
if (e->elemidx == IMAGE || e->elemidx == IMAGERGB || e->elemidx == IMAGERGBA)
|
|
{
|
|
code_image( e );
|
|
addlist( all_images, e );
|
|
}
|
|
else
|
|
{
|
|
addlist( all_elems, e );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static Telemlist* revert( Telemlist* elem )
|
|
{
|
|
if (!elem->next)
|
|
{
|
|
return elem;
|
|
}
|
|
else
|
|
{
|
|
Telemlist *ret;
|
|
ret = revert( elem->next );
|
|
elem->next->next = elem;
|
|
elem->next = 0;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
Tlist* revertlist( Tlist* l )
|
|
{
|
|
if (l->first)
|
|
l->first = revert( l->first );
|
|
return l;
|
|
}
|
|
|
|
Tparam** list2param( Tlist* params )
|
|
{
|
|
int i = params->size;
|
|
if (i)
|
|
{
|
|
Tparam** ret = (Tparam**)malloc(i*sizeof(Tparam*));
|
|
Telemlist *p = params->first;
|
|
while (p)
|
|
{
|
|
ret[--i] = (Tparam*)p->data;
|
|
p = p->next;
|
|
}
|
|
return ret;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
|
|
void init(void)
|
|
{
|
|
all_names = list();
|
|
all_elems = list();
|
|
all_images = list();
|
|
all_named = list();
|
|
all_late = list();
|
|
|
|
if (nocode) return;
|
|
outfile = stdout;
|
|
|
|
outfile = fopen( outname, "wb" );
|
|
if (!outfile)
|
|
{
|
|
perror( outname );
|
|
exit(-1);
|
|
}
|
|
|
|
fprintf( outfile,
|
|
"/* Automatically generated by Iup 3 LED Compiler to C. */\n"
|
|
"\n"
|
|
"#include <stdlib.h>\n"
|
|
"#include <stdarg.h>\n"
|
|
"#include <iup.h>\n"
|
|
"\n"
|
|
"static Ihandle* named[ " );
|
|
vetsizepos = ftell( outfile );
|
|
fprintf( outfile,
|
|
" ];\n"
|
|
"\n" );
|
|
}
|
|
|
|
void finish(void)
|
|
{
|
|
int i;
|
|
Telemlist *p;
|
|
|
|
if (nerrors || nocode) return;
|
|
|
|
for (i=1; i<nheaders; i++)
|
|
{
|
|
if (headerfile[i].used)
|
|
{
|
|
fprintf( outfile, "#include <%s.h>\n", headerfile[i].name );
|
|
}
|
|
}
|
|
|
|
fprintf( outfile, "\nvoid %s (void)\n{\n", funcname );
|
|
|
|
revertlist( all_images );
|
|
p = all_images->first;
|
|
while (p)
|
|
{
|
|
Telem* e = (Telem*)(p->data);
|
|
fprintf(outfile, " image_" );
|
|
code_c_name( e->name );
|
|
fprintf(outfile, " ();\n" );
|
|
p = p->next;
|
|
}
|
|
|
|
indent();
|
|
revertlist( all_elems );
|
|
p = all_elems->first;
|
|
while (p)
|
|
{
|
|
Telem* e = (Telem*)(p->data);
|
|
code_decl( e );
|
|
fprintf( outfile, ";\n" );
|
|
p = p->next;
|
|
}
|
|
unindent();
|
|
|
|
fprintf( outfile, "}\n" );
|
|
fseek( outfile, vetsizepos, SEEK_SET );
|
|
fprintf( outfile, "%6d", nameds+1 );
|
|
|
|
fclose( outfile );
|
|
}
|
|
|
|
/* necessario para o Linux ?? */
|
|
int gettxt( char *v1, char *v2);
|
|
int gettxt( char *v1, char *v2)
|
|
{
|
|
fprintf(stderr, "%s: %s\n", v1, v2);
|
|
return 0;
|
|
}
|
|
|