Category : C Source Code
Archive   : FORMGENC.ZIP
Filename : FORMGEN.C
/*
Formgen lets you interactively create a data entry form for use with a C
software application. It generates three C functions for you:
(1) a display-the-form function
(2) a fill-the-form function
(3) an edit-the-form function (for data entry)
This version of formgen is IBM PC-specific, and uses video buffering to
increase the speed of forms. The video (and field i/o) routines are
contained in "iolib.c".
Programs which use the generated forms must also include iolib, unless
you change the "get" and "say" commands to operate with something else
(which is easy to do). If you use the "editor-in-a-box" data type
("ed"), you must also link in ioed.obj. This function was separated from
the others so that screens which do not use it aren't penalized for its
size.
This program, iolib and ioed are:
Copyright (c) 1989, John Queern, Belleville IL, (CIS 70120,107)
Placed in the public domain, April 1989.
You may use this program for whatever you like (including commercial
applications). Just don't sell it. Pass it on--it's free.
Improve it--it's fun!
*/
/* Notes:
Data entry field information has been generalized to permit you
to add new field types easily. A data field description structure
is used to describe each "standard" data format and provide
default "get" and "say" command templates for the display and
edit screens:
struct FIELDTYPE {
char descr[20]; e.g., "i" for integer
char *saycommand; default display command template
char *getcommand; default edit command template
}
Special codes which may be used in "say" and "get" command templates:
#X, #Y - insert screen coordinates here
#N - insert variable name here
#W - insert width here
#D - insert decimals here
Note: X and Y are integer values which are automatically generated
for you based on screen position. The rest are all strings, and may
actually be used for anything useful. For example, our "ed" field
type (the editor-in-a-box) uses #D to represent the number of lines
in the edit window.
When you create an actual entry field on a screen, formgen
keeps track of it in a VARTYPE record (which you will fill in
when you create the variable):
struct VARTYPE {
char type[21]; data type (may match FIELDTYPE entry)
char name[31]; name of this one
char width[7]; width of field
char decimals[7]; decimals (or lines, if "ed")
int x,y; position on screen (where token placed)
int flagnum; flag number on screen
char saycomm[46]; actual say command for this var
char getcomm[46]; actual get command fro this var
}
When you select the F2 function ("Field"), formgen checks the
existing variable table to see if there's a field already at
that position. If so, it opens up an edit window and allows you
to edit the contents of the field record.
If not, formgen opens up an edit window for adding the record.
The presence of a data entry field is marked on the form using
a graphic icon which signifies the anchor point for the entry
field (normally, the left side or upper left hand corner), followed
by the field table index value for the entry. The field table is
kept updated (by realign()) to reflect current screen positions.
Future enhancements being considered (your opinion?):
Allow the user to specify/override the field edit sequence (to go
in columns, for example, if desired);
*/
#include
#include
#include
#include
#include
#include
#include "iolib.h"
#include "ioed.h"
#define TRUE 1
#define FALSE 0
#define NEW 1
#define OLD 0
#define MAXVAR 200
#define FMARKER '\020' /* quasi-graphic field anchor char */
struct FIELDTYPE {
char descr[20]; /* field description, e.g., int */
char *saycommand; /* default "say" command line for field type */
char *getcommand; /* default "get" command line for field type */
} field[] = {
/* Note: you may add your own "standard" field type definitions here: */
/* lim: +-------------------------------------------+ 45 chars */
"c", "gotoxy(#X,#Y); cprintf(\"%c\",#N);", /* char */
"rcode = getachar(#X,#Y,N);",
"s", "gotoxy(#X,#Y); cprintf(\"%-#Ws\",#N);", /* string */
"rcode = getstring(#X,#Y,&col,#N,#W);",
"i", "gotoxy(#X,#Y); cprintf(\"%#Wd\",#N);", /* integer */
"rcode = getint(#X,#Y,N,#W);",
"f", "gotoxy(#X,#Y); cprintf(\"%#W.#Dd\",#N);", /* float */
"rcode = getfloat(#X,#Y,N,#W,#D);",
"ed", "redraw((char *)#N,#X,#Y,#W,#D);", /* box editor */
"rcode=edit((char*)#N,#X,#Y,&xp,&yp,#W,#D);",
"","","" /* NULLs to mark the end of the table */
};
struct VARTYPE {
char type[21]; /* data type (may match FIELDTYPE entry) */
char name[31]; /* name of this one */
char width[7]; /* width of field */
char decimals[7]; /* decimals (if appl) */
char saycomm[46]; /* actual say command for this var */
char getcomm[46]; /* actual get command fro this var */
int x,y; /* position on screen (where token placed) */
int flagnum; /* flag number displayed on screen (key) */
} var[MAXVAR];
/* function prototypes */
void funkey_help(void);
void savefile(void);
void getfile(char *infname);
void advance(int n);
void encode(void);
void display_colors(void);
void fill_colors(void);
void edit_colors(void);
void getcolors(void);
void display_parms(void);
void fill_parms(void);
void edit_parms(void);
void getparms(void);
void display_var(void);
void fill_var(struct VARTYPE *v);
void edit_var(struct VARTYPE *v, int age);
int varcmpxy(struct VARTYPE *a, struct VARTYPE *b);
int varcmp(struct VARTYPE *a, struct VARTYPE *b);
void sortxy(void);
void sortnum(void);
void decode(char *str, struct VARTYPE *v);
void realign(void);
void addfield(int x,int y);
char ch,
blank[]=
" ",
bar[] =
"/*----------------------------------------------------------------------*/",
keyhelp[10][9] = { /* function key labels: */
"1 Help ",
"2 Field",
"3 Color",
"4 Parms",
"5 DONE ",
"6 SelBx",
"7 MkBox",
"8 ClrBx",
"9 HLine",
"10 VLin" },
screen[25][81],
color[9][16] = { /* default form colors */
"",
"NOCLEAR", /* background (for clearing screen) */
"",
"WHITE", /* form itself */
"BLUE",
"BLUE", /* field fill */
"LIGHTGRAY",
"BLUE", /* field edit */
"LIGHTGRAY"
},
infname[81],
otfname[81],
w[81],
d[81],
line[101],
temp[101],
parm[10][61] = { /* form parameters: */
"", /* 0. (unused) */
"display_x", /* 1. record display procedure name */
"fill_x(struct X *x)", /* 2. field fill procedure name */
"edit_x(struct X *x)", /* 3. field edit procedure name */
"", /* 4. extra 1st stmt for fill/edit */
"", /* 5. extra last stmt for fill/edit */
"", /* 6. extra statement for display */
"", /* 7. " " " */
"0", /* 8. screen buffer to use */
"" /* 9. (unused) */
};
int x,y,
i,j,o,
p,q,z,n,r,
lines,
vars,
video;
FILE *infile, *otfile;
/*=======================================================================*/
main(int argc,char *argv[])
{
int rcode,col=0,xp,yp;
char choice,*p;
/* init stuff */
binit(3);
textcolor(YELLOW);
textbackground(BLACK);
bfore=YELLOW;
bback=BLACK;
insertx=70;
inserty=24;
clrscr();
cprintf(" FORMGEN C Screen Generator\r\n\n");
if (argc>1) strcpy(infname,argv[1]);
else {
cprintf("Work file to load (CR to bypass)? ");
gets(infname);
}
if (infname[0] != 0) getfile(infname);
xp=yp=0;
trimblanks=FALSE; /* avoid constant trim/untrim during loop */
do { /* edit loop */
funkey_help();
rcode = edit((char *)screen,1,1,&xp,&yp,80,22);
if (vars>0) realign(); /* realign field positions */
switch (rcode) {
case 12 : /* F2 - add field */
addfield(xp,yp);
break;
case 13 : /* F3 - get colors */
getcolors();
break;
case 14 : /* F4 - get parameters */
getparms();
break;
case 7 : /* ctrl-w */
case 8 : /* End */
case 15 : /* F5 - code gen / exit */
gotoxy(1,24);
clreol();
cprintf("Do you wish to generate code now (Y/N)? ");
choice=toupper(getche());
if (choice != 'N') {
gotoxy(1,24);
clreol();
cprintf("Generate code to (S)creen, (P)rinter or (F)ile? ");
choice=toupper(getche());
if (choice=='S') {
otfile = stdout;
clrscr();
video=TRUE;
}
else if (choice=='P') {
otfile = stdprn;
video = FALSE;
}
else if (choice=='F') {
gotoxy(1,24);
clreol();
cprintf("Active file: %s\r\n",infname);
gotoxy(1,25);
clreol();
cprintf("File to save generated code in [.C]? ");
strcpy(otfname,infname);
p=strstr(otfname,".");
if (p!=NULL) *p=0;
col=0;
getstring(48,25,&col,otfname,25);
if (otfname[0]==0) break;
p=strstr(otfname,".");
if (p==NULL) strcat(otfname,".c");
otfile=fopen(otfname,"w");
if (otfile==NULL) {
gotoxy(1,24);
clreol();
cprintf("Unable to open file. Press a key.");
getch();
break;
}
}
else break;
encode();
video=FALSE;
if (choice=='F') fclose(otfile);
}
gotoxy(1,24);
clreol();
cprintf("Do you wish to continue editing (Y/N)? ");
choice=toupper(getche());
gotoxy(1,24);
clreol();
if (choice=='N') {
gotoxy(1,24);
clreol();
cprintf("Do you want to save your work file (Y/N)? ");
choice=toupper(getche());
if (choice != 'N') savefile();
clrscr();
exit(0);
}
break;
default:
;
}
} while (TRUE); /* escape using F5 or End to exit */
}
/*=======================================================================*/
void funkey_help(void)
/* display function key help on 25th line */
{
int i;
textcolor(BLUE);
textbackground(LIGHTGRAY);
for (i=0; i<10; i++) {
gotoxy(i*8+1,25);
cprintf("%s",keyhelp[i]);
}
textcolor(YELLOW);
textbackground(BLACK);
}
/*=======================================================================*/
void savefile(void)
/* save work file for future use */
{
char *p;
int i,col;
col=0;
gotoxy(1,25);
clreol();
cprintf("File to save work sheet in [.FRM]? ");
strcpy(otfname,infname);
p=strstr(otfname,".");
if (p!=NULL) *p=0;
getstring(48,25,&col,otfname,25);
if (otfname[0]==0) return;
p=strstr(otfname,".");
if (p==NULL) strcat(otfname,".frm");
otfile=fopen(otfname,"w");
if (otfile!=NULL) {
for (i=0;i<22; i++) {
trim(screen[i]);
fprintf(otfile,"%s\n",screen[i]);
}
for (i=1; i<=8; i++) {
trim(color[i]);
fprintf(otfile,"%s\n",color[i]);
}
for (i=0; i<10; i++) {
trim(parm[i]);
fprintf(otfile,"%s\n",parm[i]);
}
/* save variable records */
for (i=0; i
fprintf(otfile,"%s\n",var[i].name);
fprintf(otfile,"%s\n",var[i].width);
fprintf(otfile,"%s\n",var[i].decimals);
fprintf(otfile,"%s\n",var[i].saycomm);
fprintf(otfile,"%s\n",var[i].getcomm);
fprintf(otfile,"%d %d %d\n",var[i].x,var[i].y,var[i].flagnum);
}
fclose(otfile);
}
else {
cprintf("Unable to create output file. Press a key...");
getch();
}
}
/*=======================================================================*/
void getfile(char *infname)
/* load input file (if desired) */
{
int i;
if (strstr(infname,".") == NULL) strcat(infname,".frm");
infile = fopen(infname,"r");
if (infile==NULL) {
printf("\nNew file.\n");
return;
}
for (i=0;i<22; i++) {
fgets(screen[i],80,infile);
trim(screen[i]);
pad(screen[i],78);
}
/* get colors */
for (i=1; i<=8; i++) {
fgets(color[i],15,infile);
trim(color[i]);
}
strcpy(parm[8],"2"); /* default current buffer */
/* read parameters */
for (i=0; i<10; i++) {
fgets(parm[i],60,infile);
trim(parm[i]);
}
/* read any variable records which are present */
vars=0;
while (fgets(temp,100,infile) != NULL) {
trim(temp); strcpy(var[vars].type,temp);
fgets(temp,100,infile); trim(temp); strcpy(var[vars].name,temp);
fgets(temp,100,infile); trim(temp); strcpy(var[vars].width,temp);
fgets(temp,100,infile); trim(temp); strcpy(var[vars].decimals,temp);
fgets(temp,100,infile); trim(temp); strcpy(var[vars].saycomm,temp);
fgets(temp,100,infile); trim(temp); strcpy(var[vars].getcomm,temp);
fgets(temp,100,infile);
if (sscanf(temp,"%d %d %d",&var[vars].x,&var[vars].y,&var[vars].flagnum)
!= 0) vars++;
}
fclose(infile);
}
/*=======================================================================*/
int varcmpxy(struct VARTYPE *a, struct VARTYPE *b)
/* compare variable records and return: -1 if ab,
where the comparison is based on an ordering by row (y), then column (x) */
{
int result;
if (a->y > b->y) result=1;
else if (b->y > a->y) result=-1;
else if (a->x > b-> x) result=1;
else if (b->x > a->x) result=-1;
else result=0;
return(result);
}
void sortxy(void)
/* sort variable table so that the variables are in y/x sequence */
{
qsort(var,vars,sizeof(var[0]),varcmpxy);
}
int varcmp(struct VARTYPE *a, struct VARTYPE *b)
/* compare variable records and return: -1 if ab,
where the comparison is based on the field number (index) value */
{
int result;
if (a->flagnum > b->flagnum) result=1;
else if (b->flagnum > a->flagnum) result=-1;
else result=0;
return(result);
}
void sortnum(void)
/* sort variable table by field number */
{
qsort(var,vars,sizeof(var[0]),varcmp);
}
/*=======================================================================*/
void decode(char *str, struct VARTYPE *v)
/* decode any #-parameters in str, and expand them using the data in v */
/* NOTE: this routine destroys str, replacing it with a decoded version
THEREFORE: don't send it your original pattern; send it a copy which
has room for the expansion. */
/*
Codes which are expanded:
#X, #Y - replaced by screen coordinates
#N - replaced by variable name
#W - replaced by field width
#D - replaced by "decimals" entry
*/
{
char *cptr,*pptr,newstr[100],temp[46];
int match;
temp[0]=newstr[0]=0;
pptr = str;
cptr = strstr(str,"#");
while (cptr != NULL) { /* found a #-combo */
match = TRUE;
switch (*(cptr+1)) {
case 'X' : sprintf(temp,"%d",v->x);
break;
case 'Y' : sprintf(temp,"%d",v->y);
break;
case 'N' : strcpy(temp,v->name);
break;
case 'W' : strcpy(temp,v->width);
break;
case 'D' : strcpy(temp,v->decimals);
break;
default: strcpy(temp,"#");
match=FALSE;
}
*cptr=0; /* cut off string before the # */
strcat(newstr,pptr); /* copy up through the # */
strcat(newstr,temp); /* add the decoded # value */
cptr++; /* advance past the # */
if (match) cptr++; /* advance past the code char */
pptr = cptr; /* mark start of next substring */
cptr = strstr(cptr,"#"); /* find next # */
}
strcat(newstr,pptr); /* add any remaining text */
strcpy(str,newstr); /* and send back the results */
}
/*=======================================================================*/
void advance(int n)
/* advance linecounter n lines; pause if using video and lines>20 */
{
lines += n;
if (video && (lines>20)) {
lines=0;
printf("Press a key to continue...");
getch();
clrscr();
}
}
/*=======================================================================*/
void encode(void)
/* generate C source code for present display */
/* assumes destination file (otfile) has been set up by caller */
{
char *cptr;
int i,gets;
/* chop off file type, if given */
cptr = strstr(infname,".");
if (cptr != NULL) *cptr=0;
/* trim all arguments */
for (i=0;i<22; i++) trim(screen[i]);
for (i=1; i<=8; i++) trim(color[i]);
for (i=0; i<10; i++) trim(parm[i]);
/* sort the field variables so they appear in y/x order */
sortxy();
/* generate reminders/comments */
if (!video) {
fprintf(otfile,bar);
fprintf(otfile,"\n");
fprintf(otfile,"/* \n");
fprintf(otfile," Variables used: \n");
for (i=0; i
switch (var[i].type[0]) {
case 'c' : sprintf(temp,"char \t%s;",var[i].name);
break;
case 's' : sprintf(temp,"char \t%s[%s+1];",var[i].name,
var[i].width);
break;
case 'i' : sprintf(temp,"int \t%s;",var[i].name);
break;
case 'f' : sprintf(temp,"float \t%s;",var[i].name);
break;
case 'e' : sprintf(temp,"char \t%s[(%s+1)*%s];",var[i].name,
var[i].width,var[i].decimals);
break;
default: sprintf(temp,"%s \t%s;",var[i].type,var[i].name);
}
fprintf(otfile," %s\n",temp);
}
fprintf(otfile,"*/\n");
}
/*** create the screen form subroutine ***/
fprintf(otfile,bar);
fprintf(otfile,"\n");
fprintf(otfile,"\nvoid %s(void)\n",parm[1]);
fprintf(otfile,"/* screen code generated by formgen using: %s */\n",infname);
fprintf(otfile,"{\n");
lines=7;
if (strcmp(color[1],"NOCLEAR")==0) { /* don't clear the screen */
fprintf(otfile," savescreen(%s);\n",parm[8]);
advance(1);
}
else {
if (color[1][0]!=0) {
fprintf(otfile," bfore = %s; ",color[1]);
fprintf(otfile,"textcolor(%s);\n",color[1]);
advance(1);
}
if (color[2][0]!=0) {
fprintf(otfile," bback = %s; ",color[2]);
fprintf(otfile,"textbackground(%s);\n",color[2]);
advance(1);
}
fprintf(otfile,
" /* change next line from bclear() to savescreen() if you */\n");
fprintf(otfile,
" /* want the form to pop up over existing background */\n");
fprintf(otfile," bclear(%s);\n",parm[8]);
advance(2);
}
if (color[3][0]!=0) {
fprintf(otfile," bfore = %s; ",color[3]);
fprintf(otfile,"textcolor(%s);\n",color[3]);
advance(1);
}
if (color[4][0]!=0) {
fprintf(otfile," bback = %s; ",color[4]);
fprintf(otfile,"textbackground(%s);\n",color[4]);
advance(1);
}
for (y=0; y<20; y++) {
if (nonblank(screen[y])) {
strcpy(line,screen[y]);
x=0;
z=strlen(line)-1;
while ((line[x]==' ') && (x<=z)) x++; /* x=first pos used */
while (line[z]==' ') z--; /* z=last pos used */
/* remove any imbedded field markers */
cptr = strchr(line,FMARKER);
while (cptr != NULL) {
*cptr = ' ';
/* also remove the field number--assume any numeric
digits immediately following the marker are part
of the field number */
cptr++;
while (isdigit(*cptr)) *(cptr++)=' ';
/* and find the next marker */
cptr = strchr(line,FMARKER);
}
/* process remaining (constant) string--for the background image */
/* isolate string in temp */
strcpy(temp,line+x);
temp[z-x+1]=0;
fprintf(otfile," bwrite(%s,%d,%d,\"%s\");\n",
parm[8],x,y,temp);
advance(1);
} /* if nonblank */
} /* for */
if (strcmp(color[1],"NOCLEAR")!=0) { /* if using color[1] */
if (color[1][0]!=0) {
fprintf(otfile," bfore = %s; ",color[1]);
fprintf(otfile,"textcolor(%s);\n",color[1]);
advance(1);
}
if (color[2][0]!=0) {
fprintf(otfile," bback = %s; ",color[2]);
fprintf(otfile,"textbackground(%s);\n",color[2]);
advance(1);
}
}
fprintf(otfile," restorescreen(%s);\n",parm[8]);
advance(1);
if (parm[6][0]!=0) {
fprintf(otfile," %s\n",parm[6]);
advance(1);
}
if (parm[7][0]!=0) {
fprintf(otfile," %s\n",parm[7]);
advance(1);
}
fprintf(otfile,"}\n\n");
fprintf(otfile,"%s\n\n",bar);
advance(4);
if (video) {
printf("Press a key to continue...");
getch();
clrscr();
}
/*** create form fill subroutine ***/
if (vars>0 && strcmp(parm[2],"UNUSED")!=0) {
fprintf(otfile,"void %s\n",parm[2]);
fprintf(otfile,"{\n");
lines=5;
if (parm[4][0]!=0) {
fprintf(otfile," %s\n",parm[4]);
advance(1);
}
if (color[5][0]!=0) {
fprintf(otfile," bfore = %s; ",color[5]);
fprintf(otfile,"textcolor(%s);\n",color[5]);
advance(1);
}
if (color[6][0]!=0) {
fprintf(otfile," bback = %s; ",color[6]);
fprintf(otfile,"textbackground(%s);\n",color[6]);
advance(1);
}
/* generate the sequence of "say" lines, 1 for ea. var */
for (i=0; i
strcpy(temp,var[i].saycomm);
decode(temp,&var[i]);
fprintf(otfile," %s\n",temp);
advance(1);
}
fprintf(otfile,"\n");
if (strcmp(color[1],"NOCLEAR")!=0) { /* if using color[1] */
if (color[1][0]!=0) {
fprintf(otfile," bfore = %s; ",color[1]);
fprintf(otfile,"textcolor(%s);\n",color[1]);
advance(1);
}
if (color[2][0]!=0) {
fprintf(otfile," bback = %s; ",color[2]);
fprintf(otfile,"textbackground(%s);\n",color[2]);
advance(1);
}
}
if (parm[5][0]!=0) {
fprintf(otfile," %s\n",parm[5]);
advance(1);
}
fprintf(otfile,"}\n\n%s\n\n",bar);
} /* if gotsay */
if (video) {
printf("Press a key to continue...");
getch();
clrscr();
}
/*** create the form edit subroutine ***/
if (vars>0 && strcmp(parm[3],"UNUSED")!=0) {
fprintf(otfile,"void %s\n",parm[3]);
fprintf(otfile,"{\n");
fprintf(otfile," int rcode,fieldnumber,col,xp,yp;\n\n");
lines=4;
if (parm[4][0]!=0) {
fprintf(otfile," %s\n",parm[4]);
advance(1);
}
if (color[7][0]!=0) {
fprintf(otfile," bfore = %s; ",color[7]);
fprintf(otfile,"textcolor(%s);\n",color[7]);
advance(1);
}
if (color[8][0]!=0) {
fprintf(otfile," bback = %s; ",color[8]);
fprintf(otfile,"textbackground(%s);\n",color[8]);
advance(1);
}
/* generate switch-case statement */
fprintf(otfile," fieldnumber = 0;\n");
fprintf(otfile," do {\n");
fprintf(otfile," col = xp = yp = rcode = 0;\n");
fprintf(otfile," switch (fieldnumber) {\n");
advance(4);
gets = 0; /* count actual entries as you go */
for (i=0; i
if (var[i].x == -1) continue; /* unused field */
gets++;
/* generate code for one field */
fprintf(otfile," case %d:\n",gets-1);
strcpy(temp,var[i].getcomm);
decode(temp,&var[i]);
fprintf(otfile," %s\n",temp);
fprintf(otfile," break;\n");
advance(3);
} /* end of switch-case items */
fprintf(otfile," } /* switch fieldnumber */\n\n");
if (video) {
printf("Press a key to continue...");
getch();
clrscr();
lines=0;
}
/* now add the logic for advancing to the next field */
fprintf(otfile," switch (rcode) {\n");
fprintf(otfile," case 0:\n");
fprintf(otfile," case 1:\n");
fprintf(otfile," case 5:\n");
fprintf(otfile," case 6:\n");
fprintf(otfile," case 10:\n");
fprintf(otfile," fieldnumber++;\n");
fprintf(otfile," break;\n");
fprintf(otfile," case 3:\n");
fprintf(otfile," case 4:\n");
fprintf(otfile," case 9:\n");
fprintf(otfile," fieldnumber--;\n");
fprintf(otfile," break;\n");
fprintf(otfile," case 2:\n");
fprintf(otfile," case 7:\n");
fprintf(otfile," case 8:\n");
fprintf(otfile," rcode = 8; /* exit loop */\n");
fprintf(otfile," break;\n");
fprintf(otfile," } /* switch rcode */\n\n");
if (video) {
printf("Press a key to continue...");
getch();
clrscr();
lines=0;
}
/* add code to permit field number wrap-around */
fprintf(otfile," if (fieldnumber<0) fieldnumber = %d;\n",
gets-1);
fprintf(otfile," if (fieldnumber>%d) fieldnumber = 0;\n",
gets-1);
advance(2);
/* terminate do loop with a while condition */
fprintf(otfile," } while (rcode != 8);\n");
advance(6);
if (strcmp(color[1],"NOCLEAR")!=0) { /* if using color[1] */
if (color[1][0]!=0) {
fprintf(otfile," bfore = %s; ",color[1]);
fprintf(otfile,"textcolor(%s);\n",color[1]);
advance(1);
}
if (color[2][0]!=0) {
fprintf(otfile," bback = %s; ",color[2]);
fprintf(otfile,"textbackground(%s);\n",color[2]);
advance(1);
}
}
fprintf(otfile," /* insert any special instructions here */\n\n");
if (parm[5][0]!=0) {
fprintf(otfile," %s\n",parm[5]);
advance(1);
}
fprintf(otfile,"}\n\n");
}
if (video) {
printf("Press a key to continue...");
getch();
clrscr();
}
sortnum(); /* resort the fields in field number order */
}
/*======================================================================*/
void display_colors(void)
{
bclear(2);
bwrite(2,10,3,"Set Display Color(s)");
bfore=BLUE;
bback=LIGHTGRAY;
bwrite(2,8,4,"ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»");
bwrite(2,8,5,"º SCREEN (for initial screen clear, or NOCLEAR to avoid clearing) º");
bwrite(2,8,6,"º Foreground: Background: º");
bwrite(2,8,7,"ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹");
bwrite(2,8,8,"º FORM º");
bwrite(2,8,9,"º Foreground: Background: º");
bwrite(2,8,10,"ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹");
bwrite(2,8,11,"º FIELD FILL º");
bwrite(2,8,12,"º Foreground: Background: º");
bwrite(2,8,13,"ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹");
bwrite(2,8,14,"º FIELD EDIT º");
bwrite(2,8,15,"º Foreground: Background: º");
bwrite(2,8,16,"º NOTE: use CAPITAL LETTERS for color names º");
bwrite(2,8,17,"ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
restorescreen(2);
bfore=YELLOW;
bback=BLACK;
}
/*=======================================================================*/
void fill_colors(void)
{
textcolor(WHITE);
textbackground(BLUE);
gotoxy(21,6);
cprintf("%-15s",color[1]);
gotoxy(54,6);
cprintf("%-15s",color[2]);
gotoxy(21,9);
cprintf("%-15s",color[3]);
gotoxy(54,9);
cprintf("%-15s",color[4]);
gotoxy(21,12);
cprintf("%-15s",color[5]);
gotoxy(54,12);
cprintf("%-15s",color[6]);
gotoxy(21,15);
cprintf("%-15s",color[7]);
gotoxy(54,15);
cprintf("%-15s",color[8]);
textcolor(YELLOW);
textbackground(BLACK);
}
/*=======================================================================*/
void edit_colors(void)
{
int rcode,fieldnumber,col;
textcolor(WHITE);
textbackground(BLUE);
fieldnumber=0;
do {
col=0;
switch (fieldnumber) {
case 0: rcode=getstring(21,6,&col,color[1],15);break;
case 1: rcode=getstring(54,6,&col,color[2],15);break;
case 2: rcode=getstring(21,9,&col,color[3],15);break;
case 3: rcode=getstring(54,9,&col,color[4],15);break;
case 4: rcode=getstring(21,12,&col,color[5],15);break;
case 5: rcode=getstring(54,12,&col,color[6],15);break;
case 6: rcode=getstring(21,15,&col,color[7],15);break;
case 7: rcode=getstring(54,15,&col,color[8],15);break;
}
switch (rcode) {
case 2:
case 7:
case 8: rcode=8;
break;
case 3:
case 4: if (fieldnumber>0) fieldnumber--;
else fieldnumber=7;
break;
default:
if (fieldnumber<7) fieldnumber++;
else fieldnumber=0;
break;
}
} while (rcode != 8);
textcolor(YELLOW);
textbackground(BLACK);
}
/*=======================================================================*/
void getcolors(void)
{
savescreen(1);
display_colors();
fill_colors();
edit_colors();
restorescreen(1);
}
/*=======================================================================*/
void display_parms(void)
{
bclear(1);
bwrite(1,25,2,"Miscellaneous FORMGEN Parameters");
bfore=BLUE;
bback=LIGHTGRAY;
bwrite(1,1,3,"ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»");
bwrite(1,1,4,"º FUNCTION NAMES º");
bwrite(1,1,5,"º (omit parameter list for Display fncn, (void) will be assumed) º");
bwrite(1,1,6,"º Display: º");
bwrite(1,1,7,"º Fill: º");
bwrite(1,1,8,"º Edit: º");
bwrite(1,1,9,"ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹");
bwrite(1,1,10,"º Screen Buffer to use: º");
bwrite(1,1,11,"º (0-4) º");
bwrite(1,1,12,"ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹");
bwrite(1,1,13,"º EXTRA LINES (added to top and/or bottom of fill and edit functions) º");
bwrite(1,1,14,"º First: º");
bwrite(1,1,15,"º Last: º");
bwrite(1,1,16,"ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹");
bwrite(1,1,17,"º EXTRA LINES (added to the end of the display function) º");
bwrite(1,1,18,"º 1: º");
bwrite(1,1,19,"º 2: º");
bwrite(1,1,20,"º º");
bwrite(1,1,21,"ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
restorescreen(1);
bfore=YELLOW;
bback=BLACK;
}
/*=======================================================================*/
void fill_parms(void)
{
textcolor(WHITE);
textbackground(BLUE);
gotoxy(14,6);
cprintf("%-60s",parm[1]);
gotoxy(14,7);
cprintf("%-60s",parm[2]);
gotoxy(14,8);
cprintf("%-60s",parm[3]);
gotoxy(14,11);
cprintf("%-60s",parm[8]);
gotoxy(11,14);
cprintf("%-60s",parm[4]);
gotoxy(11,15);
cprintf("%-60s",parm[5]);
gotoxy(7,18);
cprintf("%-60s",parm[6]);
gotoxy(7,19);
cprintf("%-60s",parm[7]);
textcolor(YELLOW);
textbackground(BLACK);
}
/*=======================================================================*/
void edit_parms(void)
{
int rcode,fieldnumber,col;
textcolor(WHITE);
textbackground(BLUE);
fieldnumber=1;
do {
col=0;
switch (fieldnumber) {
case 1: rcode=getstring(14,6,&col,parm[1],60);break;
case 2: rcode=getstring(14,7,&col,parm[2],60);break;
case 3: rcode=getstring(14,8,&col,parm[3],60);break;
case 4: rcode=getstring(14,11,&col,parm[8],60);break;
case 5: rcode=getstring(11,14,&col,parm[4],60);break;
case 6: rcode=getstring(11,15,&col,parm[5],60);break;
case 7: rcode=getstring(7,18,&col,parm[6],60);break;
case 8: rcode=getstring(7,19,&col,parm[7],60);break;
}
switch (rcode) {
case 0:
case 1:
case 5:
case 6:
case 10:
if (fieldnumber<8) fieldnumber++;
else fieldnumber=1;
break;
case 3:
case 4:
case 9:
if (fieldnumber>1) fieldnumber--;
else fieldnumber=9;
break;
case 2:
case 7:
case 8:
rcode=8;
}
} while (rcode != 8);
textcolor(YELLOW);
textbackground(BLACK);
}
/*=======================================================================*/
void getparms(void)
{
savescreen(2);
display_parms();
fill_parms();
edit_parms();
restorescreen(2);
}
/*=======================================================================*/
void display_var(void)
/* screen code generated by formgen using: var */
{
int i;
savescreen(1);
bfore = RED;
bback = LIGHTGRAY;
i=0;
while (field[i].descr[0]!=0 && i<24) {
bwrite(1,71,i+1,field[i].descr);
i++;
}
bfore = BLUE;
bwrite(1,5,1,"ÖÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·");
bwrite(1,5,2,"º Variable Name: º");
bwrite(1,5,3,"º Field Width: Decimals: º");
bwrite(1,5,4,"º Data Type: º");
bwrite(1,5,5,"º Display Command: º");
bwrite(1,5,6,"º Entry Command(*): º");
bwrite(1,5,7,"º º");
bwrite(1,5,8,"º (*) leave blank if no entry allowed º");
bwrite(1,5,9,"º Special Sequences: #X, #Y -- insert screen row, column º");
bwrite(1,5,10,"º #N -- insert variable name º");
bwrite(1,5,11,"º #W, #D -- insert width, decimals º");
bwrite(1,5,12,"ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ");
restorescreen(1);
bfore = YELLOW;
bback = BLACK;
}
/*----------------------------------------------------------------------*/
void fill_var(struct VARTYPE *v)
{
textcolor(WHITE);
textbackground(BLUE);
gotoxy(28,2);
cprintf("%-30s",v->name);
gotoxy(28,3);
cprintf("%-6s",v->width);gotoxy(51,3);
cprintf("%-6s",v->decimals);
gotoxy(28,4);
cprintf("%-20s",v->type);
gotoxy(28,5);
cprintf("%-45s",v->saycomm);
gotoxy(28,6);
cprintf("%-45s",v->getcomm);
}
/*----------------------------------------------------------------------*/
void edit_var(struct VARTYPE *v, int age)
{
int rcode,fieldnumber,col,f,savetrim;
textcolor(WHITE);
textbackground(BLUE);
fieldnumber = 0;
savetrim = trimblanks;
trimblanks = TRUE;
do {
col = 0;
switch (fieldnumber) {
case 0: rcode=getstring(28,2,&col,v->name,30);
break;
case 1: rcode=getstring(28,3,&col,v->width,6);
break;
case 2: rcode=getstring(51,3,&col,v->decimals,6);
break;
case 3: rcode=getstring(28,4,&col,v->type,20);
if (age==NEW) { /* look up reference commands */
f=0;
while (field[f].descr[0]!=0
&& strcmp(field[f].descr,v->type)!=0) f++;
if (strcmp(field[f].descr,v->type)==0) {
strcpy(v->saycomm,field[f].saycommand);
strcpy(v->getcomm,field[f].getcommand);
fill_var(v);
}
else { /* if not found, look for prev use */
f=0;
while (strcmp(var[f].type,v->type)!=0) f++;
if (var[f].flagnum != v->flagnum) {
/* not the one we're working on--
so use it to initialize templates */
strcpy(v->saycomm,var[f].saycomm);
strcpy(v->getcomm,var[f].getcomm);
fill_var(v);
}
}
}
break;
case 4: rcode=getstring(28,5,&col,v->saycomm,45);
break;
case 5: rcode=getstring(28,6,&col,v->getcomm,45);
break;
} /* switch fieldnumber */
switch (rcode) {
case 0:
case 1:
case 5:
case 6:
case 10:
fieldnumber++;
break;
case 3:
case 4:
case 9:
fieldnumber--;
break;
case 2:
case 7:
case 8:
rcode = 8; /* exit loop */
break;
} /* switch rcode */
if (fieldnumber<0) fieldnumber = 5;
if (fieldnumber>5) fieldnumber = 0;
} while (rcode != 8);
trimblanks=savetrim;
}
/*----------------------------------------------------------------------*/
void realign(void)
/* realign x,y coordinates in the field variable table based on the current
picture presented in the screen buffer; mark any fields which no longer
appear with x,y values of -1,-1 (off screen); Note: there is currently
no provision to purge these unused fields from the work file.
*/
{
int i,n,x,y;
char ch,*pptr,*cptr,*fptr;
/* reset all marker positions to 0 first */
for (i=0; i
/* now scan the screen buffer looking for markers, and post their
current position in the variable table */
for (y=0; y<20; y++) {
/* scan screen[y] for field markers; if found, update position */
cptr = strchr(screen[y],FMARKER);
while (cptr != NULL) {
/* read the field number--assume any numeric
digits immediately following the marker are part
of the field number */
fptr=cptr; /* save flag position */
x=cptr-screen[y]; /* save x coordinate */
cptr++;
pptr=cptr; /* beginning of number */
while (isdigit(*cptr)) cptr++;
ch=*cptr; /* save first non-digit */
*cptr=0; /* and temporarily terminate here */
sscanf(pptr,"%d",&n); /* read the number */
*cptr=ch; /* restore the original char */
/* update var[n] with current x,y position */
if (n>=0 && n
if (var[n].flagnum != n) {
gotoxy(1,23);
clreol();
cprintf("WARNING: field sequence out of order. Press a key.");
getch();
gotoxy(1,23);
clreol();
}
else {
var[n].x = x;
var[n].y = y;
}
}
/* and find the next marker */
cptr = strchr(++fptr,FMARKER);
} /* while */
} /* for */
/* now scan the table and look for var's which have disappeared */
/* (possible future addition? right now, they're dragged along) */
}
/*----------------------------------------------------------------------*/
void addfield(int x, int y)
/* add a field at position x,y (where 0,0) is the upper left hand corner */
{
int i;
char *cptr,*tptr;
/* look for a field already at x,y */
for (i=0; i
/* if found, edit it --
future: allow user to delete or move it as well */
if (i
display_var();
fill_var(&var[i]);
edit_var(&var[i],OLD);
restorescreen(2);
}
/* if not found, add the field (provided vars < MAXVAR) */
else {
if (vars>=MAXVAR) {
gotoxy(1,23);
clreol();
cprintf("** maximum fields already in use "
"...press a key **");
getch();
return;
}
vars++;
var[vars-1].x=x;
var[vars-1].y=y;
var[vars-1].flagnum=vars-1;
savescreen(2);
display_var();
fill_var(&var[vars-1]);
edit_var(&var[vars-1],NEW);
restorescreen(2);
/* mark the field by placing a field marker in the line */
cptr=&(screen[y][x]);
pad(screen[y],80); /* expand length first */
*(cptr++)=FMARKER;
/* add the var index number */
sprintf(temp,"%d",vars-1);
tptr=temp;
while (*tptr != 0) *(cptr++) = *(tptr++);
/* trim(screen[y]); */
}
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/