e87e1680090d4f1a3cd84b2eba69be95c7ddca0b
[framework/uifw/embryo.git] / src / bin / embryo_cc_sc5.c
1 /*
2  *  vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  *
4  *  Small compiler - Error message system
5  *  In fact a very simple system, using only 'panic mode'.
6  *
7  *  Copyright (c) ITB CompuPhase, 1997-2003
8  *
9  *  This software is provided "as-is", without any express or implied warranty.
10  *  In no event will the authors be held liable for any damages arising from
11  *  the use of this software.
12  *
13  *  Permission is granted to anyone to use this software for any purpose,
14  *  including commercial applications, and to alter it and redistribute it
15  *  freely, subject to the following restrictions:
16  *
17  *  1.  The origin of this software must not be misrepresented; you must not
18  *      claim that you wrote the original software. If you use this software in
19  *      a product, an acknowledgment in the product documentation would be
20  *      appreciated but is not required.
21  *  2.  Altered source versions must be plainly marked as such, and must not be
22  *      misrepresented as being the original software.
23  *  3.  This notice may not be removed or altered from any source distribution.
24  *
25  *  Version: $Id: embryo_cc_sc5.c 45192 2010-01-15 19:44:25Z englebass $
26  */
27
28 /*
29  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
30  */
31
32 #ifdef HAVE_CONFIG_H
33 # include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <string.h>
40
41 #ifndef _MSC_VER
42 # include <unistd.h>
43 #endif
44
45 #include "embryo_cc_sc.h"
46 #include "embryo_cc_sc5.scp"
47
48 static int errflag;
49 static int errstart;    /* line number at which the instruction started */
50
51 /*  error
52  *
53  *  Outputs an error message (note: msg is passed optionally).
54  *  If an error is found, the variable "errflag" is set and subsequent
55  *  errors are ignored until lex() finds a semicolumn or a keyword
56  *  (lex() resets "errflag" in that case).
57  *
58  *  Global references: inpfname   (reffered to only)
59  *                     fline      (reffered to only)
60  *                     fcurrent   (reffered to only)
61  *                     errflag    (altered)
62  */
63 int
64 error(int number, ...)
65 {
66    static int          lastline, lastfile, errorcount;
67    char               *msg;
68    va_list             argptr;
69    char                string[1024];
70    int start;
71
72    /* errflag is reset on each semicolon.
73     * In a two-pass compiler, an error should not be reported twice. Therefore
74     * the error reporting is enabled only in the second pass (and only when
75     * actually producing output). Fatal errors may never be ignored.
76     */
77    if (((errflag) || (sc_status != statWRITE)) &&
78        ((number < 100) || (number >= 200)))
79      return 0;
80
81    if (number < 100)
82      {
83         msg = errmsg[number - 1];
84         errflag = TRUE; /* set errflag (skip rest of erroneous expression) */
85         errnum++;
86      }
87    else if (number < 200)
88      {
89         msg = fatalmsg[number - 100];
90         errnum++; /* a fatal error also counts as an error */
91      }
92    else
93      {
94         msg = warnmsg[number - 200];
95         warnnum++;
96      }
97
98    strexpand(string, (unsigned char *)msg, sizeof string, SCPACK_TABLE);
99
100    va_start(argptr, number);
101
102    start = (errstart == fline) ? -1 : errstart;
103
104    if (sc_error(number, string, inpfname, start, fline, argptr))
105    {
106       sc_closeasm(outf);
107       outf = NULL;
108       longjmp(errbuf, 3);
109    }
110
111    va_end(argptr);
112
113    if (((number >= 100) && (number < 200)) || (errnum > 250))
114      {
115         va_start(argptr, number);
116         sc_error(0, "\nCompilation aborted.", NULL, 0, 0, argptr);
117         va_end(argptr);
118
119         if (outf != NULL)
120           {
121              sc_closeasm(outf);
122              outf = NULL;
123           }                     /* if */
124         longjmp(errbuf, 2);     /* fatal error, quit */
125      }                          /* if */
126
127    /* check whether we are seeing many errors on the same line */
128    if (((errstart < 0) && (lastline != fline)) ||
129        (lastline < errstart) || (lastline > fline) || (fcurrent != lastfile))
130       errorcount = 0;
131    lastline = fline;
132    lastfile = fcurrent;
133    if (number < 200)
134       errorcount++;
135    if (errorcount >= 3)
136       error(107); /* too many error/warning messages on one line */
137    return 0;
138 }
139
140 void
141 errorset(int code)
142 {
143    switch (code)
144      {
145       case sRESET:
146         errflag = FALSE;        /* start reporting errors */
147         break;
148       case sFORCESET:
149         errflag = TRUE;         /* stop reporting errors */
150         break;
151       case sEXPRMARK:
152         errstart = fline;       /* save start line number */
153         break;
154       case sEXPRRELEASE:
155         errstart = -1;          /* forget start line number */
156         break;
157       default:
158         break;
159      }
160 }