Blame


1 7f11104a 2003-12-11 devnull
2 7f11104a 2003-12-11 devnull #include <u.h>
3 7f11104a 2003-12-11 devnull #include <libc.h>
4 7f11104a 2003-12-11 devnull #include <bio.h>
5 7f11104a 2003-12-11 devnull #include "libString.h"
6 7f11104a 2003-12-11 devnull
7 7f11104a 2003-12-11 devnull struct Sinstack{
8 7f11104a 2003-12-11 devnull int depth;
9 7f11104a 2003-12-11 devnull Biobuf *fp[32]; /* hard limit to avoid infinite recursion */
10 7f11104a 2003-12-11 devnull };
11 7f11104a 2003-12-11 devnull
12 7f11104a 2003-12-11 devnull /* initialize */
13 7f11104a 2003-12-11 devnull extern Sinstack *
14 7f11104a 2003-12-11 devnull s_allocinstack(char *file)
15 7f11104a 2003-12-11 devnull {
16 7f11104a 2003-12-11 devnull Sinstack *sp;
17 7f11104a 2003-12-11 devnull Biobuf *fp;
18 7f11104a 2003-12-11 devnull
19 7f11104a 2003-12-11 devnull fp = Bopen(file, OREAD);
20 7f11104a 2003-12-11 devnull if(fp == nil)
21 7f11104a 2003-12-11 devnull return nil;
22 7f11104a 2003-12-11 devnull
23 7f11104a 2003-12-11 devnull sp = malloc(sizeof *sp);
24 7f11104a 2003-12-11 devnull sp->depth = 0;
25 7f11104a 2003-12-11 devnull sp->fp[0] = fp;
26 7f11104a 2003-12-11 devnull return sp;
27 7f11104a 2003-12-11 devnull }
28 7f11104a 2003-12-11 devnull
29 7f11104a 2003-12-11 devnull extern void
30 7f11104a 2003-12-11 devnull s_freeinstack(Sinstack *sp)
31 7f11104a 2003-12-11 devnull {
32 7f11104a 2003-12-11 devnull while(sp->depth >= 0)
33 7f11104a 2003-12-11 devnull Bterm(sp->fp[sp->depth--]);
34 7f11104a 2003-12-11 devnull free(sp);
35 7f11104a 2003-12-11 devnull }
36 7f11104a 2003-12-11 devnull
37 7f11104a 2003-12-11 devnull /* Append an input line to a String.
38 7f11104a 2003-12-11 devnull *
39 7f11104a 2003-12-11 devnull * Empty lines and leading whitespace are removed.
40 7f11104a 2003-12-11 devnull */
41 7f11104a 2003-12-11 devnull static char *
42 7f11104a 2003-12-11 devnull rdline(Biobuf *fp, String *to)
43 7f11104a 2003-12-11 devnull {
44 7f11104a 2003-12-11 devnull int c;
45 7f11104a 2003-12-11 devnull int len = 0;
46 7f11104a 2003-12-11 devnull
47 7f11104a 2003-12-11 devnull c = Bgetc(fp);
48 7f11104a 2003-12-11 devnull
49 7f11104a 2003-12-11 devnull /* eat leading white */
50 7f11104a 2003-12-11 devnull while(c==' ' || c=='\t' || c=='\n' || c=='\r')
51 7f11104a 2003-12-11 devnull c = Bgetc(fp);
52 7f11104a 2003-12-11 devnull
53 7f11104a 2003-12-11 devnull if(c < 0)
54 7f11104a 2003-12-11 devnull return 0;
55 7f11104a 2003-12-11 devnull
56 7f11104a 2003-12-11 devnull for(;;){
57 7f11104a 2003-12-11 devnull switch(c) {
58 7f11104a 2003-12-11 devnull case -1:
59 7f11104a 2003-12-11 devnull goto out;
60 7f11104a 2003-12-11 devnull case '\\':
61 7f11104a 2003-12-11 devnull c = Bgetc(fp);
62 7f11104a 2003-12-11 devnull if (c != '\n') {
63 7f11104a 2003-12-11 devnull s_putc(to, '\\');
64 7f11104a 2003-12-11 devnull s_putc(to, c);
65 7f11104a 2003-12-11 devnull len += 2;
66 7f11104a 2003-12-11 devnull }
67 7f11104a 2003-12-11 devnull break;
68 7f11104a 2003-12-11 devnull case '\r':
69 7f11104a 2003-12-11 devnull break;
70 7f11104a 2003-12-11 devnull case '\n':
71 7f11104a 2003-12-11 devnull if(len != 0)
72 7f11104a 2003-12-11 devnull goto out;
73 7f11104a 2003-12-11 devnull break;
74 7f11104a 2003-12-11 devnull default:
75 7f11104a 2003-12-11 devnull s_putc(to, c);
76 7f11104a 2003-12-11 devnull len++;
77 7f11104a 2003-12-11 devnull break;
78 7f11104a 2003-12-11 devnull }
79 7f11104a 2003-12-11 devnull c = Bgetc(fp);
80 7f11104a 2003-12-11 devnull }
81 7f11104a 2003-12-11 devnull out:
82 7f11104a 2003-12-11 devnull s_terminate(to);
83 7f11104a 2003-12-11 devnull return to->ptr - len;
84 7f11104a 2003-12-11 devnull }
85 7f11104a 2003-12-11 devnull
86 7f11104a 2003-12-11 devnull /* Append an input line to a String.
87 7f11104a 2003-12-11 devnull *
88 7f11104a 2003-12-11 devnull * Returns a pointer to the character string (or 0).
89 7f11104a 2003-12-11 devnull * Leading whitespace and newlines are removed.
90 7f11104a 2003-12-11 devnull * Lines starting with #include cause us to descend into the new file.
91 7f11104a 2003-12-11 devnull * Empty lines and other lines starting with '#' are ignored.
92 fa325e9b 2020-01-10 cross */
93 7f11104a 2003-12-11 devnull extern char *
94 7f11104a 2003-12-11 devnull s_rdinstack(Sinstack *sp, String *to)
95 7f11104a 2003-12-11 devnull {
96 7f11104a 2003-12-11 devnull char *p;
97 7f11104a 2003-12-11 devnull Biobuf *fp, *nfp;
98 7f11104a 2003-12-11 devnull
99 7f11104a 2003-12-11 devnull s_terminate(to);
100 7f11104a 2003-12-11 devnull fp = sp->fp[sp->depth];
101 7f11104a 2003-12-11 devnull
102 7f11104a 2003-12-11 devnull for(;;){
103 7f11104a 2003-12-11 devnull p = rdline(fp, to);
104 7f11104a 2003-12-11 devnull if(p == nil){
105 7f11104a 2003-12-11 devnull if(sp->depth == 0)
106 7f11104a 2003-12-11 devnull break;
107 7f11104a 2003-12-11 devnull Bterm(fp);
108 7f11104a 2003-12-11 devnull sp->depth--;
109 7f11104a 2003-12-11 devnull return s_rdinstack(sp, to);
110 7f11104a 2003-12-11 devnull }
111 7f11104a 2003-12-11 devnull
112 7f11104a 2003-12-11 devnull if(strncmp(p, "#include", 8) == 0 && (p[8] == ' ' || p[8] == '\t')){
113 7f11104a 2003-12-11 devnull to->ptr = p;
114 7f11104a 2003-12-11 devnull p += 8;
115 7f11104a 2003-12-11 devnull
116 7f11104a 2003-12-11 devnull /* sanity (and looping) */
117 7f11104a 2003-12-11 devnull if(sp->depth >= nelem(sp->fp))
118 834469a3 2005-01-04 devnull sysfatal("s_rdinstack: includes too deep");
119 7f11104a 2003-12-11 devnull
120 7f11104a 2003-12-11 devnull /* skip white */
121 7f11104a 2003-12-11 devnull while(*p == ' ' || *p == '\t')
122 7f11104a 2003-12-11 devnull p++;
123 7f11104a 2003-12-11 devnull
124 7f11104a 2003-12-11 devnull nfp = Bopen(p, OREAD);
125 7f11104a 2003-12-11 devnull if(nfp == nil)
126 7f11104a 2003-12-11 devnull continue;
127 7f11104a 2003-12-11 devnull sp->depth++;
128 7f11104a 2003-12-11 devnull sp->fp[sp->depth] = nfp;
129 7f11104a 2003-12-11 devnull return s_rdinstack(sp, to);
130 7f11104a 2003-12-11 devnull }
131 7f11104a 2003-12-11 devnull
132 7f11104a 2003-12-11 devnull /* got milk? */
133 7f11104a 2003-12-11 devnull if(*p != '#')
134 7f11104a 2003-12-11 devnull break;
135 7f11104a 2003-12-11 devnull
136 7f11104a 2003-12-11 devnull /* take care of comments */
137 7f11104a 2003-12-11 devnull to->ptr = p;
138 7f11104a 2003-12-11 devnull s_terminate(to);
139 7f11104a 2003-12-11 devnull }
140 7f11104a 2003-12-11 devnull return p;
141 7f11104a 2003-12-11 devnull }