@@ -81,6 +81,12 @@ function Define (name, value) {
81
81
this . value = value || ''
82
82
}
83
83
84
+ function FuncDefine ( name , args , func ) {
85
+ this . name = name
86
+ this . args = args
87
+ this . func = func
88
+ }
89
+
84
90
var defines = [ ]
85
91
var expectEndifCount = 0
86
92
var skipCount = 0
@@ -125,19 +131,149 @@ function createDefineFromLine (line, rl, linenum) {
125
131
if ( debug ) {
126
132
console . log ( ` afterdef: ${ afterdef } ` )
127
133
}
128
- var hasValue = afterdef . indexOf ( ' ' ) !== - 1
129
- var name = afterdef . substring ( 0 , hasValue ? afterdef . indexOf ( ' ' )
130
- : afterdef . length )
134
+ let spaceIx = afterdef . indexOf ( ' ' )
135
+ let brIx = afterdef . indexOf ( '(' )
136
+ let clBrIx = afterdef . indexOf ( ')' )
137
+ let isFunc = false
138
+ if ( brIx !== - 1 && brIx < spaceIx ) {
139
+ isFunc = true
140
+ if ( clBrIx === - 1 ) {
141
+ console . error ( `Error: Unterminated function definition on line ${ linenum } ` )
142
+ console . error ( ` Missing ')'.` )
143
+ console . error ( ` ${ line } ` )
144
+ rc = 2
145
+ rl . close ( )
146
+ return
147
+ }
148
+ if ( afterdef . charAt ( clBrIx + 1 ) == ' ' ) {
149
+ spaceIx = clBrIx + 1
150
+ } else {
151
+ spaceIx = - 1
152
+ }
153
+ }
154
+ var hasValue = spaceIx !== - 1
155
+ var name = afterdef . substring ( 0 , hasValue ? spaceIx : afterdef . length )
131
156
if ( ! name ) {
132
157
console . error ( `Error: No name specified for define, line ${ linenum } ` )
133
158
console . error ( ` ${ line } ` )
134
159
rc = 2
135
160
rl . close ( )
136
161
return
137
162
}
138
- var value = hasValue ? afterdef . substring ( afterdef . indexOf ( ' ' ) + 1 ,
139
- afterdef . length ) : ''
140
- return new Define ( name , value )
163
+ var value = hasValue ? afterdef . substring ( spaceIx + 1 , afterdef . length )
164
+ : ''
165
+ let args , func , funcName
166
+ if ( isFunc ) {
167
+ funcName = name . substring ( 0 , name . indexOf ( '(' ) ) . trim ( )
168
+ args = [ ]
169
+ let argsStr = name . substring ( name . indexOf ( '(' ) + 1 , name . indexOf ( ')' ) )
170
+ argsStr . split ( ',' ) . forEach ( ( s ) => {
171
+ let str = s . trim ( )
172
+ args . push ( str )
173
+ } )
174
+ func = value
175
+ }
176
+ return isFunc ? new FuncDefine ( funcName , args , func ) : new Define ( name , value )
177
+ }
178
+
179
+ function resolveLine ( lineToResolve , linenum ) {
180
+ let resolvedLine = lineToResolve
181
+ defines . forEach ( ( e ) => {
182
+ if ( e . value !== undefined ) {
183
+ let regex = new RegExp ( "(\\W|^)" + e . name + "(\\W|$)" , "g" )
184
+ if ( resolvedLine . match ( regex ) ) {
185
+ if ( debug ) {
186
+ console . log ( ` Current line has define ${ e . name } ` )
187
+ }
188
+ let matches = regex . exec ( resolvedLine )
189
+ let newmatches = [ ]
190
+ let i = 0
191
+ matches . forEach ( ( match ) => {
192
+ if ( match . length >= e . name . length ) {
193
+ if ( debug ) {
194
+ console . log ( ` Match ${ match } ` )
195
+ }
196
+ newmatches . push ( [ match . replace ( e . name , e . value ) , i ] )
197
+ }
198
+ i ++
199
+ } )
200
+ i = 0
201
+ newmatches . forEach ( ( match ) => {
202
+ resolvedLine =
203
+ resolvedLine . replace ( matches [ newmatches [ i ] [ 1 ] ] , newmatches [ i ] [ 0 ] )
204
+ i ++
205
+ } )
206
+ }
207
+ } else if ( e . func !== undefined ) {
208
+ // Example: \b[()\[\]{},; ]*prnt( *)[(][^,]*[)]
209
+ let regexStr = "\\b[()\\[\\]{},; ]*?"
210
+ let replRegexStr = e . name + "( *?)[(]"
211
+ var i
212
+ for ( i = 0 ; i < e . args . length ; i ++ ) {
213
+ replRegexStr += "[^,]+?,"
214
+ }
215
+ replRegexStr = replRegexStr . substring ( 0 , replRegexStr . length - 1 )
216
+ replRegexStr += "[)]"
217
+ regexStr += replRegexStr
218
+ let finalReplRegex = new RegExp ( replRegexStr )
219
+ if ( debug ) {
220
+ console . log ( ` regexStr: ${ regexStr } ` )
221
+ }
222
+ let regex = new RegExp ( regexStr )
223
+ while ( resolvedLine . match ( regex ) ) {
224
+ if ( debug ) {
225
+ console . log ( ` ${ linenum } uses a function define!` )
226
+ }
227
+ let funcBody = e . func . valueOf ( )
228
+ if ( debug ) {
229
+ console . log ( ` Defined function body: ${ funcBody } ` )
230
+ }
231
+ let matches = regex . exec ( resolvedLine )
232
+ if ( debug ) {
233
+ console . log ( ` All matches: \n${ JSON . stringify ( matches ) } ` )
234
+ }
235
+ let match = matches [ 0 ]
236
+ if ( match === undefined || match === null ||
237
+ match . trim ( ) . length === 0 ) return
238
+ if ( debug ) {
239
+ console . log ( ` Processing match ${ match } ` )
240
+ }
241
+ let lineArgsStr = match . substring (
242
+ match . indexOf ( '(' ) + 1 , match . lastIndexOf ( ')' ) )
243
+ let lineArgs = [ ]
244
+ if ( lineArgsStr . indexOf ( ',' ) !== - 1 ) {
245
+ lineArgsStr . split ( ',' ) . forEach ( ( lineArg ) => {
246
+ lineArgs . push ( lineArg . trim ( ) )
247
+ } )
248
+ } else {
249
+ lineArgs . push ( lineArgsStr . trim ( ) )
250
+ }
251
+ if ( debug ) {
252
+ console . log ( ` Line args: ${ lineArgs } ` )
253
+ }
254
+ i = 0
255
+ e . args . forEach ( ( arg ) => {
256
+ if ( debug ) {
257
+ console . log ( ` Function body before replace: ${ funcBody } ` )
258
+ }
259
+ let replRegex = new RegExp ( "\\b" + arg + "\\b" , "g" )
260
+ if ( debug ) {
261
+ let replRegexMatches = replRegex . exec ( funcBody )
262
+ console . log ( ` Repl regex matches: ` +
263
+ `${ JSON . stringify ( replRegexMatches ) } ` )
264
+ }
265
+ funcBody = funcBody . replace ( replRegex , lineArgs [ i ] )
266
+ if ( debug ) {
267
+ console . log ( ` Replaced ${ arg } with ${ lineArgs [ i ] } ` )
268
+ console . log ( ` New function body: ${ funcBody } \n` )
269
+ }
270
+ i ++
271
+ } )
272
+ resolvedLine = resolvedLine . replace ( finalReplRegex , funcBody )
273
+ }
274
+ }
275
+ } )
276
+ return resolvedLine
141
277
}
142
278
143
279
function processLine ( rawline , inputfile , outputfile , rl , linenum , afterPause ) {
@@ -265,33 +401,12 @@ function processLine (rawline, inputfile, outputfile, rl, linenum, afterPause) {
265
401
}
266
402
} } ) ( ) === true ) return true
267
403
if ( skipCount == 0 && printLine ) {
268
- let resolvedLine = rawline . valueOf ( )
269
- defines . forEach ( ( e ) => {
270
- let regex = new RegExp ( "(\\W|^)" + e . name + "(\\W|$)" , "g" )
271
- if ( rawline . match ( regex ) ) {
272
- if ( debug ) {
273
- console . log ( ` Current line has define ${ e . name } ` )
274
- }
275
- let matches = regex . exec ( resolvedLine )
276
- let newmatches = [ ]
277
- let i = 0
278
- matches . forEach ( ( match ) => {
279
- if ( match . length >= e . name . length ) {
280
- if ( debug ) {
281
- console . log ( ` Match ${ match } ` )
282
- }
283
- newmatches . push ( [ match . replace ( e . name , e . value ) , i ] )
284
- }
285
- i ++
286
- } )
287
- i = 0
288
- newmatches . forEach ( ( match ) => {
289
- resolvedLine =
290
- resolvedLine . replace ( matches [ newmatches [ i ] [ 1 ] ] , newmatches [ i ] [ 0 ] )
291
- i ++
292
- } )
293
- }
294
- } )
404
+ let resolvedLine = resolveLine ( rawline . valueOf ( ) )
405
+ let prevResolvedLine
406
+ while ( resolvedLine !== prevResolvedLine ) {
407
+ prevResolvedLine = resolvedLine . valueOf ( )
408
+ resolvedLine = resolveLine ( prevResolvedLine )
409
+ }
295
410
fs . appendFileSync ( outputfile , `${ resolvedLine } \n` )
296
411
}
297
412
}
0 commit comments