Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dthelp / parser / canon1 / helptag / custom.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: custom.c /main/3 1995/11/08 09:29:32 rswiston $ */
24 /*
25 Copyright (c) 1988, 1989 Hewlett-Packard Co.
26 */
27
28 /* Custom.c contains standard PARSER functions, customized for the HP
29    HelpTag formatting system. */
30
31 #include "userinc.h"
32 #include "globdec.h"
33 #include <stdlib.h>
34
35
36 #if defined(MSDOS)
37 /* Standard startup code doesn't have room to load inherited environments
38    in some cases.  Since they're not used, don't bother.  (Using Microsoft
39    C compiler).  */
40 void _setenvp(M_NOPAR);
41 void _setenvp(){}
42 #endif
43
44 /* Write input file and line number for an error message */
45 void m_dumpline(file, line)
46 M_WCHAR *file;
47 int line;
48 {
49 char buffer[10];
50 char *mbyte;
51
52 m_errline("Line ");
53 sprintf(buffer, "%d", line);
54 m_errline(buffer);
55 if (!file)
56     { /* no entity file */
57     if (inputname)
58         { /* use main input, instead.  Only if set though. */
59         mbyte = MakeMByteString(inputname);
60         m_errline(" of ");
61         m_errline(mbyte);
62         m_free(mbyte, "multi-byte string");
63         }
64     }   
65 else
66     { /* yes, entity file */
67     mbyte = MakeMByteString(file);
68     m_errline(" of ");
69     m_errline(mbyte);
70     m_free(mbyte, "multi-byte string");
71     }
72 }
73
74 /* Write error message prefix */
75 void m_eprefix(M_NOPAR)
76 {
77 m_errline("\n*****\n");
78 m_dumpline(m_thisfile(), m_thisline());
79 m_errline(",\n");
80 }
81
82 /* Process error message text */
83 void m_errline(p)
84 char *p;
85 {
86 char c;
87
88 for ( ; *p ; p++)
89     {
90     if (m_errfile) putc(*p, m_errfile);
91     putc(*p, stderr);
92     }
93 }
94
95 #if defined(MSDOS)
96 #include <process.h>
97 #endif
98 /* Write error message suffix */
99 void m_esuffix(M_NOPAR)
100 {
101 m_errline(":\n");
102 m_lastchars();
103 if (++m_errcnt == m_errlim)
104     {
105     m_error("Too many errors, processing stopped");
106     m_exit(TRUE);
107     }
108 }
109
110 /* Exit procedure */
111 void m_exit(status)
112 int status;
113 {
114 if (filefound)
115     {
116     if (m_outfile != stdout)
117         {
118         if (have_index)
119             {  /* sph: is this really necessary? */
120             fseek(m_outfile, 0L, SEEK_END);
121             }
122         fclose(m_outfile);
123         if (prebye == postpreamble)
124             m_error("No text in document");
125         }
126     }
127
128 if (status)
129     {
130     if (status == 77) /* tell helptag to re-run for forward xrefs */
131         {
132         if (stoponerror)
133             {
134             if (m_errcnt == 0)
135                 exit(77);
136             else
137                 exit(1);
138             }
139         else
140             exit(66);
141         }
142
143     if (stoponerror)
144         exit(1); /* tell helptag to quit */
145
146     exit(2); /* tell helptag to continue to next phases */
147     }
148
149 exit(0);
150 }
151
152 /* Get-char procedure */
153 int m_getc(m_ptr)
154 void *m_ptr;
155 {
156 int  c;
157 M_WCHAR wc;
158 char badch[2];
159 char mbyte[32]; /* make this bigger than any possible multi-byte char */
160 int  length;
161 static M_WCHAR wcr = 0, wsb, wsp, wtb;
162 char tab, space;
163
164 /* Unix/Dos compatibility: 0D0A handling */ 
165 if (!wcr)
166     {
167     mbtowc(&wcr, "\r", 1);
168     mbtowc(&wsb, "\032", 1);
169
170     space = M_SPACE;
171     mbtowc(&wsp, &space, 1);
172
173     tab = M_TAB;
174     mbtowc(&wtb, &tab, 1);
175     }
176
177 do  {
178     length = 0;
179     if ((c = getc((FILE *) m_ptr)) == EOF) return(EOF);
180     while (1)
181         {
182         mbyte[length++] = c;
183         mbyte[length]   = 0;
184         if (mblen(mbyte,length) != -1) break; /* hurray! */
185         if (length == MB_CUR_MAX)
186             { /* reached max without a hit */
187             m_error("An invalid multi-byte character was found in the input");
188             c = ' ';
189             length = 1;
190             break;
191             }
192         if ((c = getc((FILE *) m_ptr)) == EOF)
193             { /* huh? */
194             m_error("End-of-file found in within a multi-byte character");
195             return(EOF);
196             }
197         }
198     mbtowc(&wc,mbyte,length);
199     }
200 while ((wc == wcr) || (wc == wsb));
201
202 /* Change tabs to spaces */
203 if (wc == wtb) return((int) wsp);
204 return((int) wc);
205 }
206
207 /* Open SYSTEM entity procedure */
208 void *m_openent(entcontent)
209 M_WCHAR *entcontent;
210 {
211 FILE *open;
212 char *filename;
213 SEARCH *searchp;
214 char *mb_entcontent;
215
216 mb_entcontent = MakeMByteString(entcontent);
217 if (!*mb_entcontent) return NULL; /* null file name, don't open a directory */
218
219 open = fopen(mb_entcontent, "r");
220 if (open)
221     {
222     m_free(mb_entcontent, "multi-byte string");
223     return((void *) open);
224     }
225
226 for (searchp = path ; searchp ; searchp = searchp->next)
227     {
228     filename = (char *)
229              m_malloc(strlen(searchp->directory) +
230                         strlen(mb_entcontent) + 1,
231                       "filename");
232     strcpy(filename, searchp->directory);
233     strcat(filename, mb_entcontent);
234     open = fopen(filename, "r");
235     m_free(filename, "filename");
236     if (open)
237         {
238         m_free(mb_entcontent, "multi-byte string");
239         return((void *) open);
240         }
241     }
242
243 m_free(mb_entcontent, "multi-byte string");
244 return(NULL);
245 }
246
247 /* Open input file */
248 void *m_openfirst(M_NOPAR)
249 {
250 FILE *first;
251 char *input;
252 int   length;
253
254 if (defaultext)
255     {
256     input = (char *)
257         m_malloc(strlen(m_argv[1]) + strlen(".htg") + 1, "input file name");
258     strcpy(input, m_argv[1]);
259     strcat(input, ".htg");
260     m_openchk(&first, input, "r");
261     if (filelist) puts(input);
262     /* keep name for global use */
263     length = strlen(input);
264     inputname = (M_WCHAR *) m_malloc(length + 1, "saved input file name");
265     mbstowcs(inputname, input, length + 1);
266     m_free(input, "input file name");
267     }
268 else
269     {
270     if (filelist) puts(m_argv[1]);
271     m_openchk(&first, m_argv[1], "r");
272     length = strlen(m_argv[1]);
273     inputname = (M_WCHAR *) m_malloc(length + 1, "saved input file name");
274     mbstowcs(inputname, m_argv[1], length + 1);
275     }
276
277 /* Set E option (to suppress error message on duplicate entity
278    declarations) if file begins with "<!--Index" */
279 if (first)
280     {
281     filefound = TRUE;
282     }
283 return((void *) first);
284 }
285
286 /* Set program options */
287 void m_setoptions()
288   {
289     /* F option used for FILELIST (checking done in basename, which is
290        called before this function is called) */
291     if (m_argc > 2) {
292       m_optstring(m_argv[2]);
293       if (strchr(m_argv[2], 'o')) tracetostd = TRUE;
294       if (strchr(m_argv[2], 'O')) tracetostd = TRUE;
295       /* Option "p" tells the search path to look at paths one level
296          higher when relative pathes are specified.
297                                 
298          The following two lines of code should be here, but they are moved
299          to global START-CODE of tex.if.  For some reason, global START-CODE
300          is executed before this procedure is called (parser.c), but we need
301          to have the order reversed.  Moving this procedure to a spot earlier
302          is risky, since we don't know full reasons of why things are in a
303          particular order.  This way, we minimize the damage:
304
305                         if (strchr(m_argv[2], 'p')) parentsrch = TRUE;
306       if (strchr(m_argv[2], 'P')) parentsrch = TRUE;
307       */
308       }
309     }
310
311 /* Process signon message text, stripping out MARKUP version number, so
312    only one version number will appear */
313 void m_signmsg(p)
314   char *p;
315   {
316     char *q;
317     char *pCopy;
318
319     if (q = strstr(p, VERSION)) {
320       pCopy = strdup(p);
321       q = strstr(pCopy, VERSION);
322       *q = M_EOS;
323       m_errline(pCopy);
324       free(pCopy);
325       return;
326       }
327     m_errline(p);
328     }
329
330 /* All entity declarations have been processed.  Can now check if .TEX
331    file uptodate and open appropriate output file */
332 void m_startdoc()
333 {
334 LOGICAL init = TRUE;
335 unsigned char type;
336 M_WCHAR *content;
337 unsigned char wheredef;
338 M_WCHAR *name;
339 M_WCHAR *qfile;
340 char *mbyte;
341
342 /* set locale */  
343 SetDefaultLocale();
344
345 if (! filelist)
346     {
347     texinit();
348     }
349 else
350     { /* list files that make up document */
351     while (name = m_cyclent(init, &type, &content, &wheredef))
352         {
353         init = FALSE;
354         qfile = NULL;
355         if (type == M_SYSTEM)
356             qfile = searchforfile(content);
357         if (qfile)
358             {
359             mbyte = MakeMByteString(qfile);
360             puts(mbyte);
361             m_free(qfile, "figure filename");
362             m_free(mbyte, "multi-byte string");
363             }
364         else if (type == M_SYSTEM)
365           m_err2("Can't find file %s (declared in entity %s)", content, name);
366         }
367     if (idxpath) puts(idxpath);
368     exit(m_errexit);
369     }
370 }
371
372 /* Write debugging trace information */
373 void m_trace(p)
374 char *p;
375 {
376 if (tracetostd) fputs(p, stdout);
377 else fputs(p, m_outfile);
378 }
379
380
381 void m_wctrace(p)
382 M_WCHAR *p;
383 {
384 char *mb_p;
385
386 mb_p = MakeMByteString(p);
387 m_trace(mb_p);
388 m_free(mb_p,"multi-byte string");
389 }