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