Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / lint / lpass2 / read.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: read.c,v 1.8 1994/06/24 12:25:57 ceriel Exp $ */
6
7 #include        "l_class.h"
8 #include        "class.h"
9 #include        "inpdef.h"
10
11 #include        <ctype.h>
12
13 #define INP_NPUSHBACK 1
14
15 #include        <inp_pkg.spec>
16 #include        <inp_pkg.body>
17
18 #include        "private.h"
19
20 int LineNr = 1;
21
22 /* Two dangerous macro's. They replace a single statement by
23  * two statements
24  */
25 #define loadchar(ch) LoadChar(ch); if (ch=='\n') LineNr++
26 #define pushback(ch) PushBack(); if (ch=='\n') LineNr--
27
28 /* all the ReadX() functions return 0 upon EOI */
29 PRIVATE int ReadString();
30 PRIVATE int ReadInt();
31 PRIVATE int ReadArgs();
32 PRIVATE int ReadArg();
33
34 PRIVATE SkipChar();
35
36 int
37 get_id(id)
38         struct inpdef *id;
39 {
40         /* A low-level function which just reads a definition */
41
42         if (!ReadString(id->id_name, ':', NAMESIZE))
43                 return 0;
44         if (!ReadInt(&id->id_statnr))
45                 return 0;
46         SkipChar(':');
47
48         loadchar(id->id_class);
49         if (id->id_class == EOI)
50                 return 0;
51         SkipChar(':');
52
53         if (is_class(id, CL_FUNC|CL_DEF) || is_class(id, CL_FUNC|CL_USAGE)) {
54                 /* read the argument information */
55                 id->id_args = 1;
56                 if (!ReadInt(&id->id_nrargs))
57                         return 0;
58                 SkipChar(':');
59                 if (!ReadArgs(id->id_nrargs, id->id_argtps))
60                         return 0;
61                 if (id->id_class == FC) {
62                         /* function call */
63                         if (!ReadInt(&id->id_valused))
64                                 return 0;
65                 }
66                 else {
67                         /* function definition */
68                         if (!ReadInt(&id->id_valreturned))
69                                 return 0;
70                 }
71                 SkipChar(':');
72         }
73         else {
74                 id->id_args = 0;
75         }
76
77         if (!ReadString(id->id_type, ':', TYPESIZE))
78                 return 0;
79         if (!ReadInt(&id->id_line))
80                 return 0;
81         SkipChar(':');
82
83         if (!ReadString(id->id_file, '\n', FNAMESIZE))
84                 return 0;
85         return 1;
86 }
87
88 PRIVATE int
89 ReadString(buf, delim, maxsize)
90         char *buf;
91 {
92         /*      Reads a string until 'delim' is encountered; delim is
93                 discarded.
94                 If 'maxsize-1' is exceeded or the string contains a newline
95                 panic() is called (unless delim == newline).
96                 A '\0' is appended to the string.
97         */
98
99         int ch = 0;
100         int nread = 0;
101
102         while (nread < maxsize - 1) {
103                 loadchar(ch);
104                 if (ch == EOI)
105                         return 0;
106                 if (ch == delim)
107                         break;
108                 if (ch == '\n') {
109                         panic("incomplete line in intermediate file");
110                         /*NOTREACHED*/
111                 }
112                 buf[nread++] = (char)ch;
113         }
114         buf[nread++] = '\0';
115         if (ch != delim) {
116                 panic("line too long in intermediate file");
117                 /*NOTREACHED*/
118         }
119         return 1;
120 }
121
122 PRIVATE int
123 ReadInt(ip)
124         int *ip;
125 {
126 /* Reads a decimal integer until a character which is not
127  * a digit is encountered.
128  * Non-digits except minus-sign in front of the number are discarded.
129  * Doesn't check on overflow.
130  * Just a minus-sign is interpreted as 0. (To prevent a look-ahead.)
131  */
132         int ch;
133         int negative = 0;
134         int res = 0;
135
136         do {
137                 loadchar(ch);
138         } while (!isdigit(ch) && ch != '-');
139         if (ch == EOI)
140                 return 0;
141         if (ch == '-')
142                 negative = 1;
143         else
144                 res = ch - '0';
145         loadchar(ch);
146         while (isdigit(ch)) {
147                 res = 10*res + ch - '0';
148                 loadchar(ch);
149         }
150         pushback(ch);
151         *ip = (negative ? -res : res);
152         return 1;
153 }
154
155 PRIVATE int
156 ReadArgs(nrargs, buf)
157         char *buf;
158 {
159         /*      Reads a string into buf with format
160                         <type1>:<type2>: ... :<typeN>:\0
161                 Note: format must include the final colon.
162         */
163         int i;
164         int charcount = 1;
165
166         if (nrargs < 0) {
167                 /* variable # of args */
168                 nrargs = -nrargs - 1;
169         }
170         *buf = '\0';
171         for (i = 0; i < nrargs; i++) {
172                 int n;
173
174                 if (!ReadArg(buf, ARGTPSSIZE-charcount-1))
175                         return 0;
176                 n = strlen(buf) + 1;
177                 charcount += n;
178                 buf += n - 1;
179                 *buf++ = ':';
180         }
181         *buf = '\0';
182         return 1;
183 }
184
185 PRIVATE int
186 ReadArg(buf, size)
187         char *buf;
188         int size;
189 {
190         int ch;
191
192         loadchar(ch);
193         switch (ch) {
194         case '"':       /* formal format or actual string */
195                 *buf++ = ch;
196                 if (!ReadString(buf, ch, size-1))
197                         return 0;
198                 buf += strlen(buf);
199                 *buf++ = ch;
200                 *buf++ = '\0';
201                 SkipChar(':');
202                 return 1;
203         default:        /* normal type */
204                 pushback(ch);
205                 return ReadString(buf, ':', size);
206         case EOI:
207                 return 0;
208         }
209 }
210
211 PRIVATE SkipChar(ch)
212 {
213         int c;
214
215         loadchar(c);
216         if (c == ch)
217                 return;
218         panic("bad format in intermediate file, '%c' expected; '%c' read",
219                 ch, c
220         );
221         /*NOTREACHED*/
222 }
223