1 /*  File: freeout.c
2  *  Author: Danielle et jean Thierry-Mieg (mieg@mrc-lmba.cam.ac.uk)
3  *  Copyright (C) J Thierry-Mieg and R Durbin, 1995
4  *-------------------------------------------------------------------
5  * This file is part of the ACEDB genome database package, written by
6  * 	Richard Durbin (MRC LMB, UK) rd@mrc-lmba.cam.ac.uk, and
7  *	Jean Thierry-Mieg (CRBM du CNRS, France) mieg@frmop11.bitnet
8  *
9  * Description:
10  * Exported functions: see regular.h
11  * HISTORY:
12  * Last edited: Sep 11 10:09 1998 (edgrif)
13  * * Sep 11 09:26 1998 (edgrif): Add messExit function registering.
14  * * Dec 14 16:47 1995 (mieg)
15  * Created: Thu Dec  7 22:22:33 1995 (mieg)
16  *-------------------------------------------------------------------
17  */
18 
19 /* $Id: freeout.c,v 1.1 2002/11/14 20:00:06 lstein Exp $ */
20 
21 #include "freeout.h"
22 #include <ctype.h>
23 
24 typedef struct outStruct { int magic ;
25 			   FILE *fil ;
26 			   Stack s ;
27 			   int line ;  /* line number */
28 			   int pos ;   /* char number in line */
29 			   int byte ;  /* total byte length */
30 			   int level ;
31 			   struct outStruct *next ;
32 			 } OUT ;
33 
34 static int MAGIC = 245393 ;
35 static int outLevel = 0 ;
36 static Array outArray = 0 ;
37 static OUT *outCurr ;
38 static Stack outBuf = 0 ;  /* buffer for messages */
39 #define BUFSIZE 65536
40 
41 static void freeMessOut (char*) ;
42 
43 /************************************************/
44 
freeOutInit(void)45 void freeOutInit (void)
46 {
47   static BOOL isInitialised = FALSE ;
48 
49   if (!isInitialised)
50     { isInitialised = TRUE ;
51       outLevel = 0 ;
52       outCurr = 0 ;
53       outArray = arrayCreate (6, OUT) ;
54       freeOutSetFile (stdout) ;
55       outBuf = stackCreate (BUFSIZE) ;
56       messOutRegister (freeMessOut) ;
57       messErrorRegister (freeMessOut) ;
58       messExitRegister (freeMessOut) ;
59 				/* what about prompt/query? */
60     }
61 }
62 
63 /************************************************/
64 
freeOutSetFileStack(FILE * fil,Stack s)65 static int freeOutSetFileStack (FILE *fil, Stack s)
66 { int i = 0 ;
67 
68   freeOutInit () ;
69   while (array (outArray, i, OUT).magic) i++ ;
70 
71   outLevel++ ;
72   outCurr = arrayp (outArray, i, OUT) ;
73   if (fil) outCurr->fil = fil ;
74   else if (s) outCurr->s = s ;
75   outCurr->line = outCurr->pos = outCurr->byte = 0 ;
76   outCurr->next = 0 ;
77   outCurr->level = outLevel ;
78   outCurr->magic = MAGIC ;
79   return outLevel ;
80 }
81 
freeOutSetFile(FILE * fil)82 int freeOutSetFile (FILE *fil)
83 { return freeOutSetFileStack (fil, 0) ;
84 }
85 
freeOutSetStack(Stack s)86 int freeOutSetStack (Stack s)
87 { return freeOutSetFileStack (0, s) ;
88 }
89 
90 /************************************************/
91 
freeOutClose(int level)92 void freeOutClose (int level)
93 { int  i = arrayMax (outArray) ;
94   OUT *out ;
95 
96   while (i--)
97     { out = arrayp (outArray, i, OUT) ;
98       if (!out->magic)
99 	continue ;
100       if (out->magic != MAGIC)
101 	messcrash("bad magic in freeOutClose") ;
102       if (out->level >= outLevel)  /* close all tees */
103 	{ /* do NOT close fil, because freeOutSetFile did not open it */
104 	  out->s = 0 ; out->fil = 0 ;
105 	  outCurr->line = outCurr->pos = outCurr->byte = 0 ;
106 	  out->next = 0 ;
107 	  out->magic = 0 ;
108 	  out->level = 0 ;
109 	}
110       else
111 	break ;
112     }
113   outLevel-- ;
114   outCurr = arrayp (outArray, i, OUT) ;
115   if (outCurr->level != outLevel)
116     messcrash ("anomaly in freeOutClose") ;
117 }
118 
119 /************************************************/
120 
freeOut(char * text)121 void freeOut (char *text)
122 { OUT *out = outCurr ;
123   char *cp ;
124   int pos = 0, line = 0, ln  ;
125 
126   cp = text ;
127   ln = strlen(text) ;
128   while (*cp)
129     if (*cp++ == '\n')
130       { pos = 0 ; line++ ;}
131     else
132       pos++ ;
133   while (out)
134     { if (out->s)
135 	catText(out->s, text) ;
136       if (out->fil)
137 	fputs(text, out->fil) ; /* fprintf over interprets % and \ */
138       out->byte += ln ;
139       if (line)
140 	{ out->line += line ; out->pos = pos ; }
141       else
142 	out->pos += pos ;
143       out = out->next ;
144     }
145 }
146 
freeMessOut(char * text)147 static void freeMessOut (char* text)
148 {
149   freeOut ("// ") ;
150   freeOut (text) ;
151   freeOut ("\n") ;
152 }
153 
154 /*************************************************************/
155 /* copy a binary structure onto a text stack */
freeOutBinary(char * data,int size)156 void freeOutBinary (char *data, int size)
157 {
158   OUT *out = outCurr ;
159   if (out->fil)
160     fwrite(data,size,1,out->fil);
161   else if (out->s) {
162     catBinary (out->s,data,size);
163     /* acts like a newline was added */
164     out->pos = 0;
165     out->line++;
166   }
167 }
168 
169 /*************************************************************/
170 
freeOutxy(char * text,int x,int y)171 void freeOutxy (char *text, int x, int y)
172 { static Array buf = 0 ;
173   OUT *out = outCurr ;
174   int i, j, k = 0 ;
175 
176   i = x - out->pos , j = y - out->line ;
177   if (i || j)
178     { buf = arrayReCreate (buf, 100, char) ;
179       k = 0 ;
180       if (j > 0)
181 	{ while (j--)
182 	    array (buf, k++, char) = '\n' ;
183 	  i = x ;
184 	}
185       if (i < 0)
186 	{ array (buf, k++, char) = '\n' ;
187 	  i = x ; out->line-- ; /* kludge, user should ignore this line feed */
188 	}
189       if (i > 0)
190 	{ while (i--)
191 	    array (buf, k++, char) = ' ' ;
192 	}
193       array (buf, k++, char) = 0 ;
194       freeOut (arrp(buf, 0, char)) ;
195     }
196   freeOut (text) ;
197 }
198 
199 /************************************************/
200 
freeOutf(char * format,...)201 void freeOutf (char *format,...)
202 {
203   va_list args ;
204 
205   stackClear (outBuf) ;
206   va_start (args,format) ;
207     vsprintf (stackText (outBuf,0), format,args) ;
208   va_end (args) ;
209 
210   if (strlen(stackText (outBuf,0)) >= BUFSIZE)
211     messcrash ("abusing freeOutf with too long a string: \n%s",
212 	       outBuf) ;
213 
214   freeOut (stackText (outBuf,0)) ;
215 }
216 
217 /************************************************/
218 
freeOutLine(void)219 int freeOutLine (void)
220 { return outCurr->line ; }
221 
freeOutByte(void)222 int freeOutByte (void)
223 { return outCurr->byte ; }
224 
freeOutPos(void)225 int freeOutPos (void)
226 { return outCurr->pos ; }
227 
228 /************************************************/
229 /************************************************/
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245