[comp.windows.x] Tool for Layout of Widgets

DCOOPER%ESDSDF.DECnet@CRDGW1.GE.COM (05/17/89)

Some people have asked about tools for laying out widgets.  I expect that
very soon we will see amazing graphically oriented tools to do this, but
at the moment there is nothing available.  To fill this void I have
constructed a widget layout interpreter.  This package reads a layout
from a text file and displays the corresponding user interface.

There are many limitations some of which are described in the README file.
Hope this comes in use for building sample user interfaces.
The shell archive follows.

Dwight Cooper
GE Electronic Systems Dept.
dcooper@esdsdf.decnet@crd.ge.com

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	README
#	ixtdemo.c
#	sample.Xt
#	xtdefs.h
#	xtdemo.c
#	xtlex.l
#	xtparse.y
# This archive created: Mon May 15 13:42:29 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(484 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
#
# Make xtdemo
#
#	Define DEBUG to debug any problems

INCFLAGS	= -I/X11/include
CFLAGS		= -g $(INCFLAGS)
YFLAGS          = -d
LFLAGS          = -n
OBJECTS		= ixtdemo.o xtparse.o xtlex.o xtdemo.o
LIBS		= -lXaw -lXmu -lXt -lX11 -ll

all:	xtdemo

xtdemo:	$(OBJECTS)
	$(CC) -o xtdemo $(OBJECTS) $(LIBS)

xtparse.c:	xtparse.y

xtlex.c:	xtlex.l

xtokens.h:	xtparse.c
		mv y.tab.h xtokens.h
		touch xtokens.h

ixtdemo.o:	xtdefs.h
xtlex.o:	xtdefs.h xtokens.h
xtparse.o:	xtdefs.h xtokens.h

SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'README'" '(1916 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'


This is a simple interpreter for constructing sample user interfaces from
the Athena Widgets.  Using it provides an easy way to construct demos, and
try out widgets together.  A very simple example is:

	Box "Form 1"
	Label "Label 1"	[
			  string = "This is a test.",
			  width = 100
			]
	Command "Press Here"


To run xtdemo using this as input, put it into a file called test.Xt.
Then run xtdemo using it as input.  You can specify any Toolkit command
line arguments to xtdemo.

	xtdemo -fn variable < test.Xt

Will generate the box with a Label and Form as expected.

You can specify a widget's Parent if it different than the last
Composite widget (Box, Dialog, Form, VPane, or Viewport) specified.

Any resource name can be specified in the [] block after a widget's
name.  Some resource values like background and justify can be
specified as integers even though it is not clean, portable, and
it is really hacking.  

Look at the more extensive example in the file sample.Xt

Currently there is no provision for adding callbacks to a Command Button,
so the demos built using this tool are for display purposes only, and there
is no way to implement a thread of control.

This demo also does not generate source code from which a demo can
be converted into a real application, but this is quite easy to add
by modifying the routine execute_IXTDEMO().

I except to see graphically oriented widget layout tools very soon, but
at the moment this is a simple way of using widgets as building blocks
without writing code.

xtdemo has been tested on a sun3 running SunOS 4.0.1.

xtdemo is free software, it may or may not be useful.  Feel free to
contact me if you have questions or comments, but I will not guarantee
any support.

If nothing else this software is a very simple example of using lex and
yacc to write a small interpreter.


Dwight Cooper
GE Electronic Systems
dcooper%esdsdf.decnet@crd.ge.com

SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'ixtdemo.c'" '(6812 characters)'
if test -f 'ixtdemo.c'
then
	echo shar: will not over-write existing file "'ixtdemo.c'"
else
cat << \SHAR_EOF > 'ixtdemo.c'

/*
 *	This is the interpreter for xtdemo
 */
#include	<stdio.h>
#include	<varargs.h>

#include	<X11/Intrinsic.h>
#include	<X11/Composite.h>

#include	"xtdefs.h"

/*
 *	Structure, variable, and forward references for the list
 *	of widget/string pairs stored after creation.
 */
typedef struct wlist {
	Widget	w;
	char	*string;
	struct wlist *next;
} WLIST;

static WLIST	*wlisttop = NULL;

static Widget	GetWidget();
static char	*GetString();
static void	SetWidget();
static WLIST	*AddOne();

extern char *malloc();

/*
 *	global constants
 */
#define	CODE_SIZE	1000		/* Max instructions 	*/
#define	STACK_SIZE	100
#define	MAX_ARGS	1

typedef	struct	{			/* an instruction 	*/
	OPCODE	opcode;			/*	- what to do	*/
	ARG	arg[MAX_ARGS];		/*	- argument for 	*/
} INSTRUCTION;

/*
 *	module global variables
 */
static	INSTRUCTION	code[CODE_SIZE];	/* generated code */
static	int		pc;			/* program counter */
static	VALUE		stack[STACK_SIZE];
static	int		sp = 0;

/*
 *	stack macros
 */
#define	push(value)	stack[sp++].i = value
#define	pop()		stack[--sp].i
#define	fpush(value)	stack[sp++].f = value
#define	fpop(value)	stack[--sp].f
#define	spush(value)	stack[sp++].str = value
#define	spop(value)	stack[--sp].str
#define	reset_stack()	sp = 0;

/*
 *	Initialize the interpreter, called before emiting instructions.
 */
void	init_IXTDEMO()
{
	pc = 0;				/* reset PC */
}

/*
 *	emit instructions for the interpreter.
 */
void	emit_IXTDEMO(va_alist)
va_dcl
{
	OPCODE		op;		/* instruction opcode */
	va_list		ap;		/* vararg pointer */
	
	va_start(ap);			/* begin arg processing */
	op = va_arg(ap, OPCODE);	/* Get opcode */
	code[pc].opcode = op;		/* fill in opcode */
	switch (op) {

	/************************************************/		
	/* No operands.					*/
	/************************************************/
	case OP_NOOP:
	case OP_START:
	case OP_END:
	case OP_INITARGS:
		break;

	/************************************************/		
	/* One integer operand.				*/
	/************************************************/
	case OP_PUSHI:
	case OP_SETI:
		code[pc].arg[0].value.i = va_arg(ap, int);
		break;

	/************************************************/		
	/* One float operand.				*/
	/************************************************/
	case OP_PUSHF:
	case OP_SETF:
		code[pc].arg[0].value.f = va_arg(ap, double);
		break;

	/************************************************/		
	/* One WidgetClass operand.			*/
	/************************************************/
	case OP_SET_CLASS:
		code[pc].arg[0].value.w = va_arg(ap, WidgetClass);
		break;

	/************************************************/		
	/* One string operand.				*/
	/************************************************/
	case OP_PUSHS:
	case OP_SETS:
	case OP_CREATE:
	case OP_SET_PARENT:
		code[pc].arg[0].value.str = va_arg(ap, char *);
		break;
			
	default:
		errorf("Error: %d is an invalid opcode.\n", op);
		exit(-1);
	}
	va_end(ap);			/* end var arg processing */
	pc++;
}

/*
 *	Execute the instructions.
 */
int	execute_IXTDEMO(argc, argv)
int	argc;
char	*argv[];
{
	register INSTRUCTION	*i;		/* current instruction */
	Arg			args[20];
	int			a;
	char			*rname;
	WidgetClass		wc;
	static	Widget		parent = NULL;
	Widget			toplevel;
	static	int		zero = 0;	
	pc = 0;					/* init instruction pointer */
	reset_stack();				/* reset expression stack */

#ifdef DEBUG
printf("\nSuccessful parse, executing...\n\n");
#endif
	while (code[pc].opcode != OP_END) {
	    i = &code[pc++];

	    switch (i->opcode) {

		case OP_NOOP:
			errorf("Warning: Hit an unpatched OP_NOOP intruction.\n");
			break;

		case OP_START:
			toplevel = XtInitialize("XTdemo", "XTdemo", NULL, 0,
					&argc, argv);
			parent = toplevel;
#ifdef DEBUG
printf("parent is toplevel\n");
#endif
			break;
			
		case OP_INITARGS:
			a = 0;
			break;
			
		case OP_PUSHI:
			push(i->arg[0].value.i);
			break;

		case OP_PUSHF:
			fpush(i->arg[0].value.f);
			break;

		case OP_PUSHS:
			spush(i->arg[0].value.str);
			break;
			
		case OP_SETI:
			rname = spop();
#ifdef DEBUG
printf("\tset [%d] %s = %d\n", a, rname, i->arg[0].value.i);
#endif
			XtSetArg(args[a], rname, i->arg[0].value.i);	a++;
			break;

		case OP_SETF:
			rname = spop();
#ifdef DEBUG
printf("\tset [%d] %s = %f\n", a, rname, i->arg[0].value.f);
#endif
			XtSetArg(args[a], rname, i->arg[0].value.f);	a++;
			break;
			
		case OP_SETS: {
			char *sval;
			
			rname = spop();
			sval = i->arg[0].value.str;
#ifdef DEBUG
printf("\tset [%d] %s = %s\n", a, rname, sval);
#endif
			if ((strcmp(rname, "fromVert") == 0) ||
			    (strcmp(rname, "fromHoriz") == 0)) {
			    	XtSetArg(args[a], rname, GetWidget(sval));
			    	a++;
			} else {
				XtSetArg(args[a], rname, i->arg[0].value.str);
				a++;
			}
			break;
		}
		case OP_SET_CLASS:
			wc = i->arg[0].value.w;
			break;

		case OP_SET_PARENT: {
			char *pstr;
			
			pstr = i->arg[0].value.str;

			parent = GetWidget(pstr);
#ifdef DEBUG
printf("parent is %s\n", pstr);
#endif
			break;
		}
		case OP_CREATE: {
			Widget w;
			char	*wstr;
			
			wstr = i->arg[0].value.str;
			
#ifdef DEBUG
printf("\tcreating %s (%s) [%d]\n", wstr, GetString(parent), a);
#endif
			w = XtCreateManagedWidget(wstr, wc,
				parent, args, a);
			SetWidget(wstr, w);
			if (XtIsSubclass(w, compositeWidgetClass)) {
			    	parent = w;
#ifdef DEBUG
printf("parent is %s\n", wstr);
#endif
			}
			break;
		}
	    }
	}
#ifdef DEBUG
printf("realizing\n");
#endif
	XtRealizeWidget(toplevel);
	XtMainLoop();
}

/*
 *	Find the widget associated with a name.
 */
static Widget GetWidget(string)
char *string;
{
	WLIST	*wptr;
	
	wptr = wlisttop;
	while (wptr) {
		if (strcmp(string, wptr->string) == 0) {
			return wptr->w;
		}
		wptr = wptr->next;
	}
	errorf("Warning: Widget %s not found\n", string);
	return NULL;
}

/*
 *	Find the name associated with a widget.
 */
static char	*GetString(widget)
Widget widget;
{
	WLIST	*wptr;
	
	wptr = wlisttop;
	while (wptr) {
		if (widget == wptr->w) {
			return wptr->string;
		}
		wptr = wptr->next;
	}
	return NULL;
}

/*
 *	Add a widget/string pair to the widget list.
 */
static void SetWidget(string, widget)
char *string;
Widget widget;
{
	WLIST	*wptr;
	WLIST	*pptr;
	
	if (wlisttop == NULL) {
		wlisttop = AddOne(string, widget);
	} else {
		pptr = wptr = wlisttop;
		while (wptr) {
			if (strcmp(string, wptr->string) == 0) {
				errorf("Warning: More than one widget has the name %s.\n",
					string);
			}
			pptr = wptr;
			wptr = wptr->next;
		}
		wptr = AddOne(string, widget);
		pptr->next = wptr;
	}
}

/*
 *	Allocation routine used by SetWidget.
 */
static WLIST *AddOne(string, widget)
char *string;
Widget widget;
{
	WLIST	*wptr;
	
	wptr = (WLIST *) malloc(sizeof(WLIST));
	wptr->string = (char *) malloc(strlen(string) + 1);
	strcpy(wptr->string, string);
	wptr->w = widget;
	wptr->next = NULL;	
	return wptr;
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'sample.Xt'" '(2990 characters)'
if test -f 'sample.Xt'
then
	echo shar: will not over-write existing file "'sample.Xt'"
else
cat << \SHAR_EOF > 'sample.Xt'
#
#	This is a sample Tactical Control Panel
#
Pane	"Pane 1"	[ height = 320 ]

Label	"Tactical Control Panel" [ foreground = 0, background = 1, min = 30 ]

Form	"Form 1"

Form	"Form 2" Parent "Form 1" [ borderWidth = 0 ]
Command "Apply" [ width = 60 ]
Command "Halt"	[ fromVert = "Apply", width = 60 ]
Command "Edit"  [ fromVert = "Halt", width = 60 ]
Command "Quit"	[ fromVert = "Edit", width = 60 ]

Form	"Form 3"  Parent "Form 1" [ fromHoriz = "Form 2", borderWidth = 0 ]
Command "Button 1"	[ label = " ", background = 1 ]
Label	"Label 1"	[
			  label = "Force Function",
			  width = 120,
			  fromHoriz = "Button 1",
			  justify = 0,
			  borderWidth = 0
			]
Text	"Text 1"	[
			  string = "20",
			  fromHoriz = "Label 1",
			  width = 200,
			  insertPosition = 2,
			]
Command "Button 2"	[ label = " ", fromVert = "Button 1" ]
Label	"Label 2"	[
			  label = "Stim",
			  width = 120,
			  fromHoriz = "Button 2",
			  fromVert = "Label 1",
			  justify = 0,
			  borderWidth = 0
			]
Text	"Text 2"	[
			  string = "stim_1",
			  fromHoriz = "Label 2",
			  fromVert = "Text 1",
			  width = 200,
			]
Command "Button 3"	[ label = " ", fromVert = "Button 2" ]
Label	"Label 3"	[
			  label = "Stim Stack",
			  width = 120,
			  fromHoriz = "Button 3",
			  fromVert = "Label 2",
			  justify = 0,
			  borderWidth = 0
			]
Text	"Text 3"	[
			  fromHoriz = "Label 3",
			  fromVert = "Text 2",
			  width = 200,
			]
Command "Button 4"	[ label = " ", fromVert = "Button 3" ]
Label	"Label 4"	[
			  label = "Tactical Returns",
			  width = 120,
			  fromHoriz = "Button 4",
			  fromVert = "Label 3",
			  justify = 0,
			  borderWidth = 0
			]
Text	"Text 4"	[
			  string = "Tactical-Returns",
			  fromHoriz = "Label 4",
			  fromVert = "Text 3",
			  width = 200,
			]


Form	"Form 4"  Parent "Pane 1"
Label "Mode Label 1"	[
			  label = "Abort on Error",
			  justify = 0,
			  borderWidth = 0,
			  width = 150,
			]
Command "Mode Command 1"	[ label = "No", fromHoriz = "Mode Label 1" ]
Label "Mode Label 2"	[
			  label = "Mode",
			  justify = 0,
			  borderWidth = 0,
			  fromVert = "Mode Label 1",
			  width = 150,
			]
Command "Mode Command 2"	[
			  label = "Non-Continuous",
			  fromHoriz = "Mode Label 2",
			  fromVert = "Mode Command 1",
			]
Label "Mode Label 3"	[
			  label = "Repeat Count",
			  justify = 0,
			  borderWidth = 0,
			  fromVert = "Mode Label 2",
			  width = 150,
			]
Command "Mode Command 3"	[
			  label = "2",
			  fromHoriz = "Mode Label 3",
			  fromVert = "Mode Command 2",
			]
Label "Mode Label 4"	[
			  label = "I/O Timeout Limit (msec)",
			  justify = 0,
			  borderWidth = 0,
			  fromVert = "Mode Label 3",
			  width = 150,
			]
Command "Mode Command 4"	[
			  label = "1",
			  fromHoriz = "Mode Label 4",
			  fromVert = "Mode Command 3",
			]

Form	"Form 5"  Parent "Pane 1" [ fromVert = "Form 4", defaultDistance = 0 ]
Text	"Status Text"	[
			  string = "Interface Ready",
			  textOptions = 2,
			  insertPosition = 15,
			]
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'xtdefs.h'" '(862 characters)'
if test -f 'xtdefs.h'
then
	echo shar: will not over-write existing file "'xtdefs.h'"
else
cat << \SHAR_EOF > 'xtdefs.h'

/*   ***  %W%  %G%  ***  */

/**************/
/* data types */
/**************/

typedef unsigned        char    BYTE;   /* 8-bits                       */
typedef BYTE            BOOLEAN;

typedef enum {
	ITYPE,				/*	integer		*/
	FTYPE,				/*	float		*/
	STYPE,				/*	string		*/
	WTYPE,				/*	WidgetClass	*/
} TYPE;

typedef union {				/* arguments for instructions	*/
	int		i;		/*	- an int		*/
	float		f;		/*	- any float		*/
	char		*str;		/*	- any text		*/
	WidgetClass	w;		/*	- WidgetClass		*/
} VALUE;

typedef struct {
	TYPE	type;
	VALUE	value;
} ARG;

/****************************************/
/* Opcodes for the interpreter		*/
/****************************************/
typedef	enum {	
	OP_NOOP,
	
	OP_PUSHI,
	OP_PUSHF,
	OP_PUSHS,

	OP_INITARGS,
	OP_SETI,
	OP_SETF,
	OP_SETS,

	OP_CREATE,
	OP_SET_CLASS,
	OP_SET_PARENT,
	OP_END,
	OP_START,
	
} OPCODE;
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'xtdemo.c'" '(438 characters)'
if test -f 'xtdemo.c'
then
	echo shar: will not over-write existing file "'xtdemo.c'"
else
cat << \SHAR_EOF > 'xtdemo.c'

#include <stdio.h>
#include <varargs.h>

int	main(argc, argv)
int	argc;
char	*argv[];
{
	init_IXTDEMO();
	yyparse();
	execute_IXTDEMO(argc, argv);
}

void    yyerror(s)
char    *s;
{
	extern  int     yylineno;

	errorf("\nError: Line %d: %s\n", yylineno, s);
	exit(-1);
}

errorf(va_alist)
va_dcl
{
	va_list	list;
	char	*format;
	
        va_start(list);
	format = va_arg(list, char *);
	vfprintf(stderr, format, list);
	va_end(list);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'xtlex.l'" '(1456 characters)'
if test -f 'xtlex.l'
then
	echo shar: will not over-write existing file "'xtlex.l'"
else
cat << \SHAR_EOF > 'xtlex.l'

%{

#include	<stdio.h>

typedef struct _WidgetClassRec *WidgetClass;

#include	"xtdefs.h"
#include	"xtokens.h"

extern char *malloc();

%}
digit		[0-9]
alpha		[a-zA-Z]
white		[ \t]+
any		[^\n]
dot		\.
float		{digit}*{dot}{digit}*
nl		[\n]
dq-string	\"[^\"]*\"
sq-string	\'[^\']*\'
string		({dq-string}|{sq-string})
box		[Bb][Oo][Xx]
pane		[Pp][Aa][Nn][Ee]
command		[Cc][Oo][Mm][Mm][Aa][Nn][Dd]
dialog		[Dd][Ii][Aa][Ll][Oo][Gg]
form		[Ff][Oo][Rr][Mm]
label		L[Aa][Bb][Ee][Ll]
text		[Tt][Ee][Xx][Tt]
scroll		[Ss][Cc][Rr][Oo][Ll][Ll]
viewport	[Vv][Ii][Ee][Ww][Pp][Oo][Rr][Tt]
parent		[Pp][Aa][Rr][Ee][Nn][Tt]
%%
{nl}		;
{white}		;
","		return(',');
"["		return('[');
"]"		return(']');
"="		return('=');
^"#"{any}*	{	/* Comment */	}
{box}		return BOX;
{pane}		return PANE;
{command}	return COMMAND;
{dialog}	return DIALOG;
{form}		return FORM;
{label}		return LABEL;
{text}		return TEXT;
{scroll}	return SCROLL;
{viewport}	return VIEWPORT;
{parent}	return PARENT;
{string}	{
			yylval.sval = malloc(strlen(yytext) + 1);
			strcpy(yylval.sval, yytext+1);
			yylval.sval[strlen(yylval.sval) - 1] = '\0';
			return STRING;
		}
{digit}+	{
			yylval.ival = atoi(yytext);
			return VALUE;
		}
{float}		{
			yylval.fval = atof(yytext);
			return FLOAT;
		}
{alpha}+	{
			yylval.sval = malloc(strlen(yytext) + 1);
			strcpy(yylval.sval, yytext);
			return RNAME;
		}
{any}		{
			errorf("Warning: Invalid character '%c' at line %d\n",
				*yytext, yylineno);
		}


%%
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'xtparse.y'" '(2327 characters)'
if test -f 'xtparse.y'
then
	echo shar: will not over-write existing file "'xtparse.y'"
else
cat << \SHAR_EOF > 'xtparse.y'

%{

/*
 *	This is the parser for xtdemo.  As we parse the input file we
 *	emit instructions.  When we emit an OP_END the instructions are
 *	all executed.
 */
 
#include	<stdio.h>

#include	<X11/Intrinsic.h>
#include	<X11/Box.h>
#include	<X11/Command.h>
#include	<X11/Dialog.h>
#include	<X11/Form.h>
#include	<X11/Label.h>
#include	<X11/VPaned.h>
#include	<X11/Scroll.h>
#include	<X11/AsciiText.h>
#include	<X11/Viewport.h>

#include	"xtdefs.h"

%}

%union
{
	int		ival;
	float		fval;
	char		*sval;
	WidgetClass	wval;
}

%token	','
%token	'['
%token	']'
%token	'='

%token	BOX	COMMAND	DIALOG	FORM	LABEL	PANE
%token	PARENT	SCROLL	TEXT	VIEWPORT

%token	<ival>	VALUE
%token	<fval>	FLOAT
%token	<sval>	RNAME	STRING

%type	<ival>	value
%type	<fval>	float
%type	<sval>	name rname string
%type	<wval>	widget

%start	program

%%

program
	:	{  emit_IXTDEMO(OP_START);  }
		block {	emit_IXTDEMO(OP_END);	}
	;

block
	:	line ;
	|       block line
	;

line
	:	widget name opt_parent opt_resources
		{  emit_IXTDEMO(OP_CREATE, $2);  }
	;
	
widget
	:	BOX
		{  emit_IXTDEMO(OP_SET_CLASS, boxWidgetClass);	}
	|	COMMAND
		{  emit_IXTDEMO(OP_SET_CLASS, commandWidgetClass);	}
	|	DIALOG
		{  emit_IXTDEMO(OP_SET_CLASS, dialogWidgetClass);	}
	|	FORM
		{  emit_IXTDEMO(OP_SET_CLASS, formWidgetClass);	}
	|	LABEL
		{  emit_IXTDEMO(OP_SET_CLASS, labelWidgetClass);	}
	|	PANE
		{  emit_IXTDEMO(OP_SET_CLASS, vPanedWidgetClass);	}
	|	SCROLL
		{  emit_IXTDEMO(OP_SET_CLASS, scrollbarWidgetClass);	}
	|	TEXT
		{  emit_IXTDEMO(OP_SET_CLASS, asciiStringWidgetClass);	}
	|	VIEWPORT
		{  emit_IXTDEMO(OP_SET_CLASS, viewportWidgetClass);	}
	;
	
opt_parent
	:	PARENT name
		{ emit_IXTDEMO(OP_SET_PARENT, $2); }
	|
	;

opt_resources
	:	'[' { emit_IXTDEMO(OP_INITARGS); }
		resource_list close_list
	|	{ emit_IXTDEMO(OP_INITARGS);  }
	;
	
close_list
	:	',' ']'
	|	']'
	;
	
resource_list
	:	resource
	|	resource_list ',' resource
	;

resource
	:	rname '=' rval
	;
	
rname
	:	RNAME
		{	emit_IXTDEMO(OP_PUSHS, $1);	}
	;
	
rval
	:	value
		{	emit_IXTDEMO(OP_SETI, $1);	}
	|	float
		{	emit_IXTDEMO(OP_SETF, $1);	}
	|	string
		{	emit_IXTDEMO(OP_SETS, $1);	}
	;
	
name
	:	string
	;
	
string
	:	STRING
		{
#ifdef DEBUG
			printf("string = '%s'\n", $1);
#endif
		}
	;

value
	:	VALUE
		{
#ifdef DEBUG
			printf("value = %d\n", $1);
#endif
		}
	;

float
	:	FLOAT
	;
%%

SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0