summaryrefslogtreecommitdiff
path: root/support/flow/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'support/flow/flow.c')
-rw-r--r--support/flow/flow.c846
1 files changed, 846 insertions, 0 deletions
diff --git a/support/flow/flow.c b/support/flow/flow.c
new file mode 100644
index 0000000000..525cfb96f8
--- /dev/null
+++ b/support/flow/flow.c
@@ -0,0 +1,846 @@
+#define VERSION "0.99f"
+
+/*
+
+flow.c 22/1/93 (C) 2005 Terry Brown
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/*
+
+flow - a flow-chart -> LaTeX generator. Parses a file in a flow-chart
+specification language, then produces a corresponding LaTeX
+pic environment.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+typedef int bool;
+
+#define TRUE 1
+#define FALSE 0
+
+typedef struct {float x,y;} coord;
+
+typedef struct {char name[80];
+ int Params;
+ coord size;
+ bool HasText;
+ } FlowCom;
+
+#define ParamLen 120
+#define LineLen 120
+
+typedef char param[ParamLen];
+
+#define MaxBoxes 2048 /* could not possibly have more than this */
+
+#define Commands 16
+
+FlowCom fcom[Commands] = {
+ { "SetTrack", 1, {0,0}, FALSE },
+ { "Up", 1, {0,0}, FALSE },
+ { "Down", 1, {0,0}, FALSE },
+ { "Left", 1, {0,0}, FALSE },
+ { "Right", 1, {0,0}, FALSE },
+ { "Box", 0, {4,2}, TRUE },
+ { "Oval", 0, {4,2}, TRUE },
+ { "Choice", 4, {4,4}, TRUE },
+ { "Tag", 0, {0,0}, FALSE },
+ { "ToTag", 0, {0,0}, FALSE },
+ { "Scale", 2, {0,0}, FALSE },
+ { "Tilt", 0, {4,2}, TRUE },
+ { "Text", 0, {4,2}, TRUE },
+ { "TxtPos", 4, {0,0}, FALSE },
+ { "Skip", 2, {0,0}, FALSE },
+ { "%", 0, {0,0}, FALSE }
+};
+
+typedef enum {SetTrack,
+ Up,
+ Down,
+ Left,
+ Right,
+ Box,
+ Oval,
+ Choice,
+ Tag,
+ ToTag,
+ Scale,
+ Tilt,
+ Text,
+ TxtPos,
+ Skip,
+ Comment
+ } TheCommands;
+
+typedef enum {ArrowS, LineS, NoneS} trackSymb;
+typedef enum {UpD, DownD, LeftD, RightD} direcs;
+
+typedef struct ATAG {coord pos;
+ coord size;
+ struct ATAG *next;
+ } aTag;
+
+typedef struct {
+ coord min;
+ coord max;
+} boundingBox;
+
+
+/* state / position tracking variables */
+
+boundingBox pic = {{0,0},{0,0}};
+coord Coords[MaxBoxes] = {{0,0}}; /* just initialise first coord */
+int CurCoord = 0;
+int CurTrack = ArrowS;
+int CurDirec = DownD;
+coord CurScale = {1.,1.};
+coord CurSize = {0.,0.};
+aTag *CurTag = NULL;
+char CurPos[20] = "[c]";
+char CurBoxPos[20] = "[c]";
+char leader[20]="";
+char tailer[20]="";
+float TrackX = 1.;
+float TrackY = 1.;
+int InputLine = 0;
+char line[LineLen];
+
+float VertGap=1.;
+float HorzGap=1.;
+
+FILE *inFile, *outFile; /* global input output streams */
+
+int doText();
+
+void checkBounds(boundingBox *b, coord *c) {
+
+ if (b->min.x > c->x) b->min.x = c->x;
+ if (b->max.x < c->x) b->max.x = c->x;
+ if (b->min.y > c->y) b->min.y = c->y;
+ if (b->max.y < c->y) b->max.y = c->y;
+}
+void checkBoundsRng(
+ boundingBox *b,
+ float x,
+ float y,
+ float sx,
+ float sy
+ ) {
+
+ if (b->min.x > x) b->min.x = x;
+ if (b->max.x < x+sx) b->max.x = x+sx;
+ if (b->min.y > y) b->min.y = y;
+ if (b->max.y < y+sy) b->max.y = y+sy;
+}
+
+int getCommand(char line[], param plist) {
+/*
+tries to interpret the next line of inFile as a command, returns -1 if it can't
+*/
+
+ int i=0, command = -1;
+
+ while (i<Commands) {
+
+ if ( strncmp(fcom[i].name,line,strlen(fcom[i].name)) == 0) {
+ command = i;
+ break;
+ }
+ i++;
+ }
+
+ if (command == -1) {
+ if (!feof(inFile) && line[0] != '\n')
+ fprintf(stderr,"flow error : can't interpret line %d\n",InputLine);
+ return command;
+ }
+
+ strncpy(plist, line+strlen(fcom[command].name), ParamLen);
+
+ return command;
+
+}
+
+
+int doCommand(int command, param pList) {
+/*
+output the LaTeX bits for this command, updating the coords, coord list
+etc. as required
+*/
+
+ static int init = 0;
+ aTag *tempTag;
+ char params[10][80];
+ char *trackStr = "vector";
+ float dimen,x,y,x1,y1;
+ int i,xs,ys;
+ coord t;
+
+ dimen = 0.;
+
+ params[0][0]=0; /* so Up / Down / Left / Right can find *'s for line
+ drawing */
+
+
+ if (CurTrack == LineS) trackStr = "line";
+
+ if (fcom[command].HasText) {
+ if ((command != Choice && sscanf(pList,"%f %f",&x,&y) == 2) ||
+ (command == Choice && sscanf(pList,"%s %s %s %s %f %f",
+ params[0],
+ params[0],
+ params[0],
+ params[0],
+ &x,&y) == 6)) {
+ fcom[command].size.x = x;
+ fcom[command].size.y = y;
+ }
+ }
+
+ if (!init && CurSize.x == 0. && CurSize.y == 0.) {
+ CurSize.x = fcom[command].size.x*CurScale.x;
+ CurSize.y = fcom[command].size.y*CurScale.y;
+ }
+
+ if ( init && (fcom[command].size.x != 0 || fcom[command].size.y != 0 )) {
+
+ switch (CurDirec) {
+
+ case DownD :
+
+ t.x = Coords[CurCoord].x+CurSize.x/2;
+ t.y = Coords[CurCoord].y-CurSize.y;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ 0,-1,
+ VertGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x*CurScale.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y
+ - VertGap;
+
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ case UpD :
+
+ t.x = Coords[CurCoord].x+CurSize.x/2;
+ t.y = Coords[CurCoord].y;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ 0,1,
+ VertGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x*CurScale.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y +
+ fcom[command].size.y*CurScale.y
+ + VertGap;
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ case RightD :
+
+ t.x = Coords[CurCoord].x+CurSize.x;
+ t.y = Coords[CurCoord].y-CurSize.y/2;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ 1,0,
+ HorzGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x
+ + HorzGap;
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2 +
+ fcom[command].size.y*CurScale.y / 2;
+
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ case LeftD :
+
+ t.x = Coords[CurCoord].x;
+ t.y = Coords[CurCoord].y-CurSize.y/2;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ -1,0,
+ HorzGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x -
+ fcom[command].size.x*CurScale.x
+ - HorzGap;
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2 +
+ fcom[command].size.y*CurScale.y / 2;
+
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ default:
+ break;
+ }
+ CurCoord++;
+ CurSize.x = fcom[command].size.x*CurScale.x;
+ CurSize.y = fcom[command].size.y*CurScale.y;
+
+ }
+
+ switch (command) {
+
+ case Skip :
+ if (sscanf(pList,"%f %f %f %f",&x,&y,&x1,&y1) == 4) {
+ VertGap = y;
+ HorzGap = x;
+ TrackX = x1;
+ TrackY = y1;
+ }
+ break;
+
+ case TxtPos :
+ CurPos[0]=CurBoxPos[0]=leader[0]=tailer[0]=0;
+ sscanf(pList,"%s %s %s %s",CurPos,CurBoxPos,leader,tailer);
+ break;
+
+ case Box :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\framebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos);
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+
+ break;
+
+ case Tilt :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos);
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+1./6.*CurSize.y,
+ Coords[CurCoord].y,
+ 1,0,
+ CurSize.x);
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x-1./6.*CurSize.y,
+ Coords[CurCoord].y-CurSize.y,
+ 1,0,
+ CurSize.x);
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x-1./6.*CurSize.y,
+ Coords[CurCoord].y-CurSize.y,
+ 1,3,
+ CurSize.y*1./3.);
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x-1./6.*CurSize.y+CurSize.x,
+ Coords[CurCoord].y-CurSize.y,
+ 1,3,
+ CurSize.y*1./3.);
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x-1./6.*CurSize.y,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x + 1./6.*CurSize.y,
+ CurSize.y
+ );
+
+ break;
+
+ case Text :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos);
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+ break;
+
+ case Oval :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\oval(%3.4f,%3.4f)}\n",
+ Coords[CurCoord].x+CurSize.x/2,
+ Coords[CurCoord].y-CurSize.y/2,
+ CurSize.x,
+ CurSize.y );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos );
+ doText();
+ fprintf(outFile,"}}}\n");
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+
+ break;
+
+ case Choice :
+
+ init=1;
+
+ xs = (int)CurSize.x; ys = (int)CurSize.y;
+
+ for (i = (xs>ys) ? xs : ys; i>1; i--) {
+ if ( (xs % i) == 0 && (ys % i) == 0 ) {
+ xs /= i;
+ ys /= i;
+ i = (xs>ys) ? xs : ys;
+ }
+ }
+
+ if (xs>6) {
+ fprintf(stderr,"Flow warning - illegal Choice aspect ratio\n");
+ xs = 6;
+ }
+ if (ys>6) {
+ fprintf(stderr,"Flow warning - illegal Choice aspect ratio\n");
+ ys = 6;
+ }
+
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y/2,
+ xs,ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y/2,
+ xs,-ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x,
+ Coords[CurCoord].y-CurSize.y/2,
+ -xs,-ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x,
+ Coords[CurCoord].y-CurSize.y/2,
+ -xs,ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos );
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ sscanf(pList,"%s %s %s %s",params[0],params[1],params[2],params[3]);
+
+ if (params[0][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[lt]{%s}}\n",
+ Coords[CurCoord].x+
+ CurSize.x*0.65,
+ Coords[CurCoord].y,
+ params[0]
+ );
+
+ if (params[1][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[rt]{%s}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-
+ CurSize.y/2.*0.7,
+ params[1]
+ );
+
+ if (params[2][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[lt]{%s}}\n",
+ Coords[CurCoord].x+
+ CurSize.x,
+ Coords[CurCoord].y-
+ CurSize.y/2.*0.7,
+ params[2]
+ );
+
+ if (params[3][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[lb]{%s}}\n",
+ Coords[CurCoord].x+
+ CurSize.x*0.65,
+ Coords[CurCoord].y-
+ CurSize.y,
+ params[3]
+ );
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+ break;
+
+ case SetTrack :
+ sscanf(pList,"%s",params[0]);
+
+ if ( strcmp("arrow",params[0]) == 0)
+ CurTrack = ArrowS;
+ if ( strcmp("line",params[0]) == 0)
+ CurTrack = LineS;
+ if ( strcmp("none",params[0]) == 0)
+ CurTrack = NoneS;
+
+ break;
+
+ case Scale :
+ sscanf(pList,"%f %f",&CurScale.x,&CurScale.y);
+ break;
+
+ case Tag :
+ tempTag = (aTag*)malloc(sizeof(aTag));
+ tempTag->size.x = CurSize.x;
+ tempTag->size.y = CurSize.y;
+ tempTag->pos.x = Coords[CurCoord].x;
+ tempTag->pos.y = Coords[CurCoord].y;
+ tempTag->next = CurTag;
+ CurTag = tempTag;
+ break;
+
+ case ToTag :
+
+ if (CurTag == NULL) {
+ fprintf(stderr,"flow error - Tag stack empty \n");
+ break;
+ }
+ tempTag = CurTag;
+ CurSize.x = tempTag->size.x;
+ CurSize.y = tempTag->size.y;
+ Coords[CurCoord].x = tempTag->pos.x;
+ Coords[CurCoord].y = tempTag->pos.y;
+
+ CurTag = tempTag->next;
+
+ free(tempTag);
+
+ break;
+
+ case Right :
+ CurDirec = RightD;
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackX;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x,
+ Coords[CurCoord].y-CurSize.y/2,
+ (params[0][0]=='*')?"vector":"line",
+ 1,0,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x +
+ dimen;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+ break;
+
+ case Down :
+ CurDirec = DownD;
+
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackY;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x/2,
+ Coords[CurCoord].y-CurSize.y,
+ (params[0][0]=='*')?"vector":"line",
+ 0,-1,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y
+ - dimen;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+
+ break;
+
+ case Left :
+ CurDirec = LeftD;
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackX;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y/2,
+ (params[0][0]=='*')?"vector":"line",
+ -1,0,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x -
+ dimen;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+ break;
+
+ case Up :
+ CurDirec = UpD;
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackY;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x/2,
+ Coords[CurCoord].y,
+ (params[0][0]=='*')?"vector":"line",
+ 0,1,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y +
+ dimen;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+ break;
+
+ case Comment :
+ break;
+
+ default:
+ fprintf(stderr,"flow error : unknown command %4d\n",command);
+ return 0;
+ }
+
+ if (command != Scale) CurScale.x = CurScale.y = 1.;
+
+ if (fcom[command].HasText == FALSE) {
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+ }
+
+ return 1;
+
+}
+
+int doText() {
+/*
+output text for those commands that require it, spit out all lines that start
+with white space (0x20, 0x09)
+*/
+
+ int i;
+
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+
+ while (!feof(inFile) && (
+ line[0] == 0x20 ||
+ line[0] == 0x09 )
+ ) {
+
+ line[strlen(line)-1]=0;
+ for (i=0; i<strlen(line) &&
+ (line[i] == 0x09 || line[i] == 0x20); i++);
+
+ fprintf(outFile,"%s%s%s",leader,line+i,tailer);
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+
+ if (line[0] == 0x20 || line[0] == 0x09 )
+ fprintf(outFile,"\\\\\n");
+ else
+ fprintf(outFile,"\n");
+
+ }
+
+ return 1;
+}
+
+void applyPicWrapper(FILE *inFile, FILE *outFile) {
+
+ char buf[1024];
+
+ fprintf(outFile,"\\begin{picture}(%f,%f)(%f,%f)\n",
+ pic.max.x - pic.min.x,
+ pic.max.y - pic.min.y,
+ pic.min.x,
+ pic.min.y
+ );
+
+ while (!feof(inFile)) {
+
+ fwrite(buf,fread(buf,1,1024,inFile),1,outFile);
+
+ }
+
+ fprintf(outFile,"\\end{picture}\n");
+}
+
+int main(int argc, char **argv) {
+
+ param params;
+ int command=0;
+ char tmpfileNm[80];
+
+
+ inFile = stdin; outFile = stdout;
+
+ tmpnam(tmpfileNm);
+ outFile = fopen(tmpfileNm,"w");
+
+ if (argc > 1) {
+ inFile = fopen(argv[1],"r");
+ if (inFile == NULL) {
+ fprintf(stderr,"Couldn't open input file %s\n",argv[1]);
+ exit(0);
+ }
+ }
+
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+
+ fprintf(outFile,"%% picture environment flowchart generated by flow ");
+ fprintf(outFile,"%s\n",VERSION);
+
+ while (command != -1) {
+
+ command = getCommand(line,params);
+
+ if (command != -1)
+ if (!doCommand(command, params)) return 10;
+ }
+
+ fclose(inFile);
+ fclose(outFile);
+
+ outFile = stdout;
+ if (argc > 2) {
+ outFile = fopen(argv[2],"w");
+ if (outFile == NULL) {
+ fprintf(stderr,"Couldn't open output file %s\n",argv[2]);
+ fclose(inFile);
+ exit(0);
+ }
+ }
+
+ inFile = fopen(tmpfileNm,"r");
+
+ applyPicWrapper(inFile,outFile);
+ if (outFile != stdout) fclose(outFile);
+ fclose(inFile);
+ remove(tmpfileNm);
+
+ exit(0);
+
+ return 0; /* just to suppress the warning */
+
+}