annotate dmd/macro.c @ 650:aa6a0b7968f7

Added test case for bug #100 Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 05 Oct 2008 17:28:15 +0200
parents cbd6c8073a32
children b30fe7e1dbb9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
1
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
2 // Copyright (c) 1999-2006 by Digital Mars
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
3 // All Rights Reserved
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
4 // written by Walter Bright
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
5 // http://www.digitalmars.com
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
6 // License for redistribution is by either the Artistic License
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
8 // See the included readme.txt for details.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
9
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
10 /* Simple macro text processor.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
11 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
12
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
13 #include <stdio.h>
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
14 #include <string.h>
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
15 #include <time.h>
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
16 #include <ctype.h>
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
17 #include <assert.h>
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
18
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
19 #if IN_GCC || IN_LLVM
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
20 #include "mem.h"
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
21 #else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
22 #if _WIN32
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
23 #include "..\root\mem.h"
571
cbd6c8073a32 Changed all '#if linux || __APPLE__' to '#if POSIX' so we can support other platforms too, thanx for the suggestion anders.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 535
diff changeset
24 #elif POSIX
1
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
25 #include "../root/mem.h"
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
26 #else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
27 #error "fix this"
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
28 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
29 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
30
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
31 #include "root.h"
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
32 #include "macro.h"
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
33
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
34 #define isidstart(c) (isalpha(c) || (c) == '_')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
35 #define isidchar(c) (isalnum(c) || (c) == '_')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
36
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
37 unsigned char *memdup(unsigned char *p, size_t len)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
38 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
39 return (unsigned char *)memcpy(mem.malloc(len), p, len);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
40 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
41
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
42 Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
43 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
44 next = NULL;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
45
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
46 #if 1
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
47 this->name = name;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
48 this->namelen = namelen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
49
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
50 this->text = text;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
51 this->textlen = textlen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
52 #else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
53 this->name = name;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
54 this->namelen = namelen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
55
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
56 this->text = text;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
57 this->textlen = textlen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
58 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
59 inuse = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
60 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
61
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
62
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
63 Macro *Macro::search(unsigned char *name, size_t namelen)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
64 { Macro *table;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
65
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
66 //printf("Macro::search(%.*s)\n", namelen, name);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
67 for (table = this; table; table = table->next)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
68 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
69 if (table->namelen == namelen &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
70 memcmp(table->name, name, namelen) == 0)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
71 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
72 //printf("\tfound %d\n", table->textlen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
73 break;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
74 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
75 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
76 return table;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
77 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
78
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
79 Macro *Macro::define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
80 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
81 //printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
82
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
83 Macro *table;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
84
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
85 //assert(ptable);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
86 for (table = *ptable; table; table = table->next)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
87 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
88 if (table->namelen == namelen &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
89 memcmp(table->name, name, namelen) == 0)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
90 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
91 table->text = text;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
92 table->textlen = textlen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
93 return table;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
94 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
95 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
96 table = new Macro(name, namelen, text, textlen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
97 table->next = *ptable;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
98 *ptable = table;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
99 return table;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
100 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
101
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
102 /**********************************************************
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
103 * Given buffer p[0..end], extract argument marg[0..marglen].
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
104 * Params:
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
105 * n 0: get entire argument
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
106 * 1..9: get nth argument
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
107 * -1: get 2nd through end
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
108 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
109
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
110 unsigned extractArgN(unsigned char *p, unsigned end, unsigned char **pmarg, unsigned *pmarglen, int n)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
111 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
112 /* Scan forward for matching right parenthesis.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
113 * Nest parentheses.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
114 * Skip over $( and $)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
115 * Skip over "..." and '...' strings inside HTML tags.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
116 * Skip over <!-- ... --> comments.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
117 * Skip over previous macro insertions
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
118 * Set marglen.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
119 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
120 unsigned parens = 1;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
121 unsigned char instring = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
122 unsigned incomment = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
123 unsigned intag = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
124 unsigned inexp = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
125 unsigned argn = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
126
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
127 unsigned v = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
128
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
129 Largstart:
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
130 #if 1
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
131 // Skip first space, if any, to find the start of the macro argument
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
132 if (v < end && isspace(p[v]))
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
133 v++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
134 #else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
135 // Skip past spaces to find the start of the macro argument
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
136 for (; v < end && isspace(p[v]); v++)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
137 ;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
138 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
139 *pmarg = p + v;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
140
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
141 for (; v < end; v++)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
142 { unsigned char c = p[v];
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
143
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
144 switch (c)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
145 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
146 case ',':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
147 if (!inexp && !instring && !incomment && parens == 1)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
148 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
149 argn++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
150 if (argn == 1 && n == -1)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
151 { v++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
152 goto Largstart;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
153 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
154 if (argn == n)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
155 break;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
156 if (argn + 1 == n)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
157 { v++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
158 goto Largstart;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
159 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
160 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
161 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
162
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
163 case '(':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
164 if (!inexp && !instring && !incomment)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
165 parens++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
166 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
167
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
168 case ')':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
169 if (!inexp && !instring && !incomment && --parens == 0)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
170 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
171 break;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
172 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
173 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
174
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
175 case '"':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
176 case '\'':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
177 if (!inexp && !incomment && intag)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
178 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
179 if (c == instring)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
180 instring = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
181 else if (!instring)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
182 instring = c;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
183 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
184 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
185
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
186 case '<':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
187 if (!inexp && !instring && !incomment)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
188 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
189 if (v + 6 < end &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
190 p[v + 1] == '!' &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
191 p[v + 2] == '-' &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
192 p[v + 3] == '-')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
193 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
194 incomment = 1;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
195 v += 3;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
196 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
197 else if (v + 2 < end &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
198 isalpha(p[v + 1]))
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
199 intag = 1;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
200 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
201 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
202
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
203 case '>':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
204 if (!inexp)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
205 intag = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
206 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
207
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
208 case '-':
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
209 if (!inexp &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
210 !instring &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
211 incomment &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
212 v + 2 < end &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
213 p[v + 1] == '-' &&
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
214 p[v + 2] == '>')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
215 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
216 incomment = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
217 v += 2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
218 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
219 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
220
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
221 case 0xFF:
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
222 if (v + 1 < end)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
223 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
224 if (p[v + 1] == '{')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
225 inexp++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
226 else if (p[v + 1] == '}')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
227 inexp--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
228 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
229 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
230
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
231 default:
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
232 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
233 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
234 break;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
235 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
236 if (argn == 0 && n == -1)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
237 *pmarg = p + v;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
238 *pmarglen = p + v - *pmarg;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
239 //printf("extractArg%d('%.*s') = '%.*s'\n", n, end, p, *pmarglen, *pmarg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
240 return v;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
241 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
242
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
243
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
244 /*****************************************************
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
245 * Expand macro in place in buf.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
246 * Only look at the text in buf from start to end.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
247 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
248
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
249 void Macro::expand(OutBuffer *buf, unsigned start, unsigned *pend,
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
250 unsigned char *arg, unsigned arglen)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
251 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
252 #if 0
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
253 printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
254 printf("Buf is: '%.*s'\n", *pend - start, buf->data + start);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
255 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
256
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
257 static int nest;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
258 if (nest > 100) // limit recursive expansion
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
259 return;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
260 nest++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
261
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
262 unsigned end = *pend;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
263 assert(start <= end);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
264 assert(end <= buf->offset);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
265
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
266 /* First pass - replace $0
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
267 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
268 arg = memdup(arg, arglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
269 for (unsigned u = start; u + 1 < end; )
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
270 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
271 unsigned char *p = buf->data; // buf->data is not loop invariant
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
272
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
273 /* Look for $0, but not $$0, and replace it with arg.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
274 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
275 if (p[u] == '$' && (isdigit(p[u + 1]) || p[u + 1] == '+'))
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
276 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
277 if (u > start && p[u - 1] == '$')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
278 { // Don't expand $$0, but replace it with $0
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
279 buf->remove(u - 1, 1);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
280 end--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
281 u += 1; // now u is one past the closing '1'
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
282 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
283 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
284
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
285 unsigned char c = p[u + 1];
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
286 int n = (c == '+') ? -1 : c - '0';
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
287
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
288 unsigned char *marg;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
289 unsigned marglen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
290 extractArgN(arg, arglen, &marg, &marglen, n);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
291 if (marglen == 0)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
292 { // Just remove macro invocation
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
293 //printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
294 buf->remove(u, 2);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
295 end -= 2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
296 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
297 else if (c == '+')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
298 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
299 // Replace '$+' with 'arg'
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
300 //printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
301 buf->remove(u, 2);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
302 buf->insert(u, marg, marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
303 end += marglen - 2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
304
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
305 // Scan replaced text for further expansion
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
306 unsigned mend = u + marglen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
307 expand(buf, u, &mend, NULL, 0);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
308 end += mend - (u + marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
309 u = mend;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
310 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
311 else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
312 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
313 // Replace '$1' with '\xFF{arg\xFF}'
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
314 //printf("Replacing '$%c' with '\xFF{%.*s\xFF}'\n", p[u + 1], marglen, marg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
315 buf->data[u] = 0xFF;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
316 buf->data[u + 1] = '{';
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
317 buf->insert(u + 2, marg, marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
318 buf->insert(u + 2 + marglen, "\xFF}", 2);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
319 end += -2 + 2 + marglen + 2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
320
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
321 // Scan replaced text for further expansion
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
322 unsigned mend = u + 2 + marglen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
323 expand(buf, u + 2, &mend, NULL, 0);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
324 end += mend - (u + 2 + marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
325 u = mend;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
326 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
327 //printf("u = %d, end = %d\n", u, end);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
328 //printf("#%.*s#\n", end, &buf->data[0]);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
329 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
330 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
331
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
332 u++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
333 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
334
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
335 /* Second pass - replace other macros
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
336 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
337 for (unsigned u = start; u + 4 < end; )
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
338 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
339 unsigned char *p = buf->data; // buf->data is not loop invariant
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
340
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
341 /* A valid start of macro expansion is $(c, where c is
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
342 * an id start character, and not $$(c.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
343 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
344 if (p[u] == '$' && p[u + 1] == '(' && isidstart(p[u + 2]))
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
345 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
346 //printf("\tfound macro start '%c'\n", p[u + 2]);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
347 unsigned char *name = p + u + 2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
348 unsigned namelen = 0;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
349
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
350 unsigned char *marg;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
351 unsigned marglen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
352
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
353 unsigned v;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
354 /* Scan forward to find end of macro name and
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
355 * beginning of macro argument (marg).
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
356 */
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
357 for (v = u + 2; v < end; v++)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
358 { unsigned char c = p[v];
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
359
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
360 if (!isidchar(c))
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
361 { // We've gone past the end of the macro name.
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
362 namelen = v - (u + 2);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
363 break;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
364 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
365 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
366
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
367 v += extractArgN(p + v, end - v, &marg, &marglen, 0);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
368 assert(v <= end);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
369
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
370 if (v < end)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
371 { // v is on the closing ')'
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
372 if (u > start && p[u - 1] == '$')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
373 { // Don't expand $$(NAME), but replace it with $(NAME)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
374 buf->remove(u - 1, 1);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
375 end--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
376 u = v; // now u is one past the closing ')'
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
377 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
378 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
379
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
380 Macro *m = search(name, namelen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
381 if (m)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
382 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
383 #if 0
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
384 if (m->textlen && m->text[0] == ' ')
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
385 { m->text++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
386 m->textlen--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
387 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
388 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
389 if (m->inuse && marglen == 0)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
390 { // Remove macro invocation
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
391 buf->remove(u, v + 1 - u);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
392 end -= v + 1 - u;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
393 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
394 else if (m->inuse && arglen == marglen && memcmp(arg, marg, arglen) == 0)
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
395 { // Recursive expansion; just leave in place
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
396
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
397 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
398 else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
399 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
400 //printf("\tmacro '%.*s'(%.*s) = '%.*s'\n", m->namelen, m->name, marglen, marg, m->textlen, m->text);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
401 #if 1
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
402 marg = memdup(marg, marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
403 // Insert replacement text
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
404 buf->spread(v + 1, 2 + m->textlen + 2);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
405 buf->data[v + 1] = 0xFF;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
406 buf->data[v + 2] = '{';
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
407 memcpy(buf->data + v + 3, m->text, m->textlen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
408 buf->data[v + 3 + m->textlen] = 0xFF;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
409 buf->data[v + 3 + m->textlen + 1] = '}';
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
410
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
411 end += 2 + m->textlen + 2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
412
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
413 // Scan replaced text for further expansion
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
414 m->inuse++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
415 unsigned mend = v + 1 + 2+m->textlen+2;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
416 expand(buf, v + 1, &mend, marg, marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
417 end += mend - (v + 1 + 2+m->textlen+2);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
418 m->inuse--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
419
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
420 buf->remove(u, v + 1 - u);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
421 end -= v + 1 - u;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
422 u += mend - (v + 1);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
423 #else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
424 // Insert replacement text
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
425 buf->insert(v + 1, m->text, m->textlen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
426 end += m->textlen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
427
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
428 // Scan replaced text for further expansion
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
429 m->inuse++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
430 unsigned mend = v + 1 + m->textlen;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
431 expand(buf, v + 1, &mend, marg, marglen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
432 end += mend - (v + 1 + m->textlen);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
433 m->inuse--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
434
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
435 buf->remove(u, v + 1 - u);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
436 end -= v + 1 - u;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
437 u += mend - (v + 1);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
438 #endif
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
439 mem.free(marg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
440 //printf("u = %d, end = %d\n", u, end);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
441 //printf("#%.*s#\n", end - u, &buf->data[u]);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
442 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
443 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
444 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
445 else
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
446 {
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
447 // Replace $(NAME) with nothing
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
448 buf->remove(u, v + 1 - u);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
449 end -= (v + 1 - u);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
450 continue;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
451 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
452 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
453 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
454 u++;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
455 }
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
456 mem.free(arg);
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
457 *pend = end;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
458 nest--;
c53b6e3fe49a [svn r5] Initial commit. Most things are very rough.
lindquist
parents:
diff changeset
459 }