mucgly 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +6 -0
- data/README.rdoc +63 -0
- data/doc/Mucgly.html +3 -3
- data/doc/_index.html +2 -2
- data/doc/file.CHANGELOG.html +8 -3
- data/doc/file.README.html +64 -2
- data/doc/index.html +64 -2
- data/doc/top-level-namespace.html +2 -2
- data/ext/mucgly/mucgly.c +313 -56
- data/lib/version.rb +1 -1
- data/test/golden/test_langmode.txt +17 -0
- data/test/result/test_langmode.txt +17 -0
- data/test/test_langmode.rx.c +25 -0
- data/test/test_mucgly.rb +3 -1
- metadata +54 -45
- checksums.yaml +0 -7
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= Version history
|
2
2
|
|
3
|
+
[0.2.1] Suspension feature for language mode compliance.
|
4
|
+
Character eater.
|
5
|
+
Mucgly.sethook method added.
|
6
|
+
Mucgly.seteater method added.
|
7
|
+
Checks for argument types in Mucgly methods.
|
8
|
+
|
3
9
|
[0.2.0] Multihook feature.
|
4
10
|
Remote escape feature.
|
5
11
|
Block output feature.
|
data/README.rdoc
CHANGED
@@ -63,6 +63,8 @@ For all command line options, see:
|
|
63
63
|
|
64
64
|
* Multiple, concurrent macro start and end limiters (multihook).
|
65
65
|
|
66
|
+
* Compatible with editor's language sensitive mode.
|
67
|
+
|
66
68
|
* Multiple sources for configuration: default config, environment
|
67
69
|
variable, command line.
|
68
70
|
|
@@ -165,6 +167,65 @@ happen multiple times. If a single hook set is performed (again),
|
|
165
167
|
singlehook mode is entered. This can also be used as method for
|
166
168
|
resetting the current set of multihooks.
|
167
169
|
|
170
|
+
=== Suspension
|
171
|
+
|
172
|
+
Suspension is a feature that helps in implementing macros that are
|
173
|
+
compliant with the text editor's language sensitive mode.
|
174
|
+
|
175
|
+
By default Mucgly macros do not look like part of the host language,
|
176
|
+
e.g. C language. However macros can be made to emulate the host
|
177
|
+
language.
|
178
|
+
|
179
|
+
For example the user might want to make the macro to look like a
|
180
|
+
function call in the host language.
|
181
|
+
|
182
|
+
The macro could be used like this:
|
183
|
+
|
184
|
+
c = rx( inline_mult( "c", "a1" ) );
|
185
|
+
|
186
|
+
Here hookbeg is "rx(" and hookend is ")". From the C language point of
|
187
|
+
view, this looks like two nested function calls. "rx" is called and
|
188
|
+
its argument is a return value from "inline_mult" function. From Ruby
|
189
|
+
point of view, we want "inline_mult" to be called as a Ruby
|
190
|
+
method. However, by default the macro would terminate to the first
|
191
|
+
closing parenthesis, which would cause a syntax error in the end.
|
192
|
+
|
193
|
+
The solution is to declare "(" as suspension character. Suspension
|
194
|
+
character means that for each occurence of the suspension character,
|
195
|
+
one hookend will be suspended, i.e. de-activated. Hence the first "("
|
196
|
+
after starting the macro with "rx(", will suspend the next ")",
|
197
|
+
i.e. hookend. Since there is only one "(", there will be only one
|
198
|
+
suspension performed, and the final ")" will terminate the macro. The
|
199
|
+
suspended hookend will be taken as part of the macro body.
|
200
|
+
|
201
|
+
In order to get suspension, a multihook is declared including a
|
202
|
+
suspension character/string.
|
203
|
+
|
204
|
+
/*-<+Mucgly.multihook( [ "rx(", ")", "(" ] )>-*/
|
205
|
+
|
206
|
+
Suspensions could be replaced with simple escape of the first ")"
|
207
|
+
within the macro call, but this is inconvenient, and might potentially
|
208
|
+
cause issues with language mode of the host language.
|
209
|
+
|
210
|
+
Suspension mechanism is not bullet proof, and thus does not always
|
211
|
+
guarantee language mode compatibility. Languages with C based syntax
|
212
|
+
work well since they use the same style of function argument lists and
|
213
|
+
string conventions as in Ruby. Other type of languages might not
|
214
|
+
benefit from this feature.
|
215
|
+
|
216
|
+
|
217
|
+
=== Eater
|
218
|
+
|
219
|
+
Eater is character/string which follows hookesc and designates that
|
220
|
+
the following char should be removed. This applies to both inside and
|
221
|
+
outside macros. The reason for adding "extra" characters to input
|
222
|
+
could be for example to trick the language mode of the host language
|
223
|
+
to change coloring.
|
224
|
+
|
225
|
+
Eater can be set with ":eater" or with "Mucgly.seteater". If
|
226
|
+
"Mucgly.seteater" is passed a nil, the Eater feature is disabled and
|
227
|
+
hookesc behaves as by default.
|
228
|
+
|
168
229
|
|
169
230
|
== Special commands
|
170
231
|
|
@@ -280,6 +341,8 @@ Complete list of Mucgly module methods:
|
|
280
341
|
|
281
342
|
[hookesc] Get hookesc value.
|
282
343
|
|
344
|
+
[sethook] Set hookbeg and hookend values.
|
345
|
+
|
283
346
|
[sethookbeg] Set hookbeg value.
|
284
347
|
|
285
348
|
[sethookend] Set hookend value.
|
data/doc/Mucgly.html
CHANGED
@@ -92,7 +92,7 @@
|
|
92
92
|
<dt id="VERSION-constant" class="">VERSION =
|
93
93
|
|
94
94
|
</dt>
|
95
|
-
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>0.2.
|
95
|
+
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>0.2.1</span><span class='tstring_end'>"</span></span></pre></dd>
|
96
96
|
|
97
97
|
</dl>
|
98
98
|
|
@@ -177,9 +177,9 @@
|
|
177
177
|
</div>
|
178
178
|
|
179
179
|
<div id="footer">
|
180
|
-
Generated on
|
180
|
+
Generated on Mon Oct 24 20:35:30 2016 by
|
181
181
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
182
|
-
0.8.7.6 (ruby-2.1
|
182
|
+
0.8.7.6 (ruby-2.3.1).
|
183
183
|
</div>
|
184
184
|
|
185
185
|
</body>
|
data/doc/_index.html
CHANGED
@@ -104,9 +104,9 @@
|
|
104
104
|
</div>
|
105
105
|
|
106
106
|
<div id="footer">
|
107
|
-
Generated on
|
107
|
+
Generated on Mon Oct 24 20:35:29 2016 by
|
108
108
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
109
|
-
0.8.7.6 (ruby-2.1
|
109
|
+
0.8.7.6 (ruby-2.3.1).
|
110
110
|
</div>
|
111
111
|
|
112
112
|
</body>
|
data/doc/file.CHANGELOG.html
CHANGED
@@ -63,7 +63,12 @@
|
|
63
63
|
|
64
64
|
<div id="content"><div id='filecontents'>
|
65
65
|
<h1 id="label-Version+history">Version history</h1>
|
66
|
-
<dl class="rdoc-list label-list"><dt>0.2.
|
66
|
+
<dl class="rdoc-list label-list"><dt>0.2.1
|
67
|
+
<dd>
|
68
|
+
<p>Suspension feature for language mode compliance. Character eater.
|
69
|
+
Mucgly.sethook method added. Mucgly.seteater method added. Checks for
|
70
|
+
argument types in Mucgly methods.</p>
|
71
|
+
</dd><dt>0.2.0
|
67
72
|
<dd>
|
68
73
|
<p>Multihook feature. Remote escape feature. Block output feature. Fix for
|
69
74
|
hook at EOF parsing.</p>
|
@@ -89,9 +94,9 @@ compatible with older versions.</p>
|
|
89
94
|
</div></div>
|
90
95
|
|
91
96
|
<div id="footer">
|
92
|
-
Generated on
|
97
|
+
Generated on Mon Oct 24 20:35:30 2016 by
|
93
98
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
94
|
-
0.8.7.6 (ruby-2.1
|
99
|
+
0.8.7.6 (ruby-2.3.1).
|
95
100
|
</div>
|
96
101
|
|
97
102
|
</body>
|
data/doc/file.README.html
CHANGED
@@ -130,6 +130,8 @@ line, configuration files, or from macro input file.</p>
|
|
130
130
|
</li><li>
|
131
131
|
<p>Multiple, concurrent macro start and end limiters (multihook).</p>
|
132
132
|
</li><li>
|
133
|
+
<p>Compatible with editor's language sensitive mode.</p>
|
134
|
+
</li><li>
|
133
135
|
<p>Multiple sources for configuration: default config, environment variable,
|
134
136
|
command line.</p>
|
135
137
|
</li><li>
|
@@ -229,6 +231,63 @@ happen multiple times. If a single hook set is performed (again),
|
|
229
231
|
singlehook mode is entered. This can also be used as method for resetting
|
230
232
|
the current set of multihooks.</p>
|
231
233
|
|
234
|
+
<h3 id="label-Suspension">Suspension</h3>
|
235
|
+
|
236
|
+
<p>Suspension is a feature that helps in implementing macros that are
|
237
|
+
compliant with the text editor's language sensitive mode.</p>
|
238
|
+
|
239
|
+
<p>By default Mucgly macros do not look like part of the host language, e.g. C
|
240
|
+
language. However macros can be made to emulate the host language.</p>
|
241
|
+
|
242
|
+
<p>For example the user might want to make the macro to look like a function
|
243
|
+
call in the host language.</p>
|
244
|
+
|
245
|
+
<p>The macro could be used like this:</p>
|
246
|
+
|
247
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_c'>c</span> <span class='op'>=</span> <span class='id identifier rubyid_rx'>rx</span><span class='lparen'>(</span> <span class='id identifier rubyid_inline_mult'>inline_mult</span><span class='lparen'>(</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>c</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>a1</span><span class='tstring_end'>"</span></span> <span class='rparen'>)</span> <span class='rparen'>)</span><span class='semicolon'>;</span>
|
248
|
+
</code></pre>
|
249
|
+
|
250
|
+
<p>Here hookbeg is “rx(” and hookend is “)”. From the C language point of
|
251
|
+
view, this looks like two nested function calls. “rx” is called and its
|
252
|
+
argument is a return value from “inline_mult” function. From Ruby point of
|
253
|
+
view, we want “inline_mult” to be called as a Ruby method. However, by
|
254
|
+
default the macro would terminate to the first closing parenthesis, which
|
255
|
+
would cause a syntax error in the end.</p>
|
256
|
+
|
257
|
+
<p>The solution is to declare “(” as suspension character. Suspension
|
258
|
+
character means that for each occurence of the suspension character, one
|
259
|
+
hookend will be suspended, i.e. de-activated. Hence the first “(” after
|
260
|
+
starting the macro with “rx(”, will suspend the next “)”, i.e. hookend.
|
261
|
+
Since there is only one “(”, there will be only one suspension performed,
|
262
|
+
and the final “)” will terminate the macro. The suspended hookend will be
|
263
|
+
taken as part of the macro body.</p>
|
264
|
+
|
265
|
+
<p>In order to get suspension, a multihook is declared including a suspension
|
266
|
+
character/string.</p>
|
267
|
+
|
268
|
+
<pre class="code ruby"><code class="ruby"><span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>*-<+Mucgly.multihook( [ "rx(", ")", "(" ] )>-*</span><span class='regexp_end'>/</span></span></code></pre>
|
269
|
+
|
270
|
+
<p>Suspensions could be replaced with simple escape of the first “)” within
|
271
|
+
the macro call, but this is inconvenient, and might potentially cause
|
272
|
+
issues with language mode of the host language.</p>
|
273
|
+
|
274
|
+
<p>Suspension mechanism is not bullet proof, and thus does not always
|
275
|
+
guarantee language mode compatibility. Languages with C based syntax work
|
276
|
+
well since they use the same style of function argument lists and string
|
277
|
+
conventions as in Ruby. Other type of languages might not benefit from this
|
278
|
+
feature.</p>
|
279
|
+
|
280
|
+
<h3 id="label-Eater">Eater</h3>
|
281
|
+
|
282
|
+
<p>Eater is character/string which follows hookesc and designates that the
|
283
|
+
following char should be removed. This applies to both inside and outside
|
284
|
+
macros. The reason for adding “extra” characters to input could be for
|
285
|
+
example to trick the language mode of the host language to change coloring.</p>
|
286
|
+
|
287
|
+
<p>Eater can be set with “:eater” or with “Mucgly.seteater”. If
|
288
|
+
“Mucgly.seteater” is passed a nil, the Eater feature is disabled and
|
289
|
+
hookesc behaves as by default.</p>
|
290
|
+
|
232
291
|
<h2 id="label-Special+commands">Special commands</h2>
|
233
292
|
|
234
293
|
<p>In addition to regular Ruby code the macros are allowed to include so
|
@@ -355,6 +414,9 @@ Hook-commands change the current hook values.</p>
|
|
355
414
|
</dd><dt>hookesc
|
356
415
|
<dd>
|
357
416
|
<p>Get hookesc value.</p>
|
417
|
+
</dd><dt>sethook
|
418
|
+
<dd>
|
419
|
+
<p>Set hookbeg and hookend values.</p>
|
358
420
|
</dd><dt>sethookbeg
|
359
421
|
<dd>
|
360
422
|
<p>Set hookbeg value.</p>
|
@@ -466,9 +528,9 @@ GEM executable (i.e. same command line options).</p>
|
|
466
528
|
</div></div>
|
467
529
|
|
468
530
|
<div id="footer">
|
469
|
-
Generated on
|
531
|
+
Generated on Mon Oct 24 20:35:30 2016 by
|
470
532
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
471
|
-
0.8.7.6 (ruby-2.1
|
533
|
+
0.8.7.6 (ruby-2.3.1).
|
472
534
|
</div>
|
473
535
|
|
474
536
|
</body>
|
data/doc/index.html
CHANGED
@@ -130,6 +130,8 @@ line, configuration files, or from macro input file.</p>
|
|
130
130
|
</li><li>
|
131
131
|
<p>Multiple, concurrent macro start and end limiters (multihook).</p>
|
132
132
|
</li><li>
|
133
|
+
<p>Compatible with editor's language sensitive mode.</p>
|
134
|
+
</li><li>
|
133
135
|
<p>Multiple sources for configuration: default config, environment variable,
|
134
136
|
command line.</p>
|
135
137
|
</li><li>
|
@@ -229,6 +231,63 @@ happen multiple times. If a single hook set is performed (again),
|
|
229
231
|
singlehook mode is entered. This can also be used as method for resetting
|
230
232
|
the current set of multihooks.</p>
|
231
233
|
|
234
|
+
<h3 id="label-Suspension">Suspension</h3>
|
235
|
+
|
236
|
+
<p>Suspension is a feature that helps in implementing macros that are
|
237
|
+
compliant with the text editor's language sensitive mode.</p>
|
238
|
+
|
239
|
+
<p>By default Mucgly macros do not look like part of the host language, e.g. C
|
240
|
+
language. However macros can be made to emulate the host language.</p>
|
241
|
+
|
242
|
+
<p>For example the user might want to make the macro to look like a function
|
243
|
+
call in the host language.</p>
|
244
|
+
|
245
|
+
<p>The macro could be used like this:</p>
|
246
|
+
|
247
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_c'>c</span> <span class='op'>=</span> <span class='id identifier rubyid_rx'>rx</span><span class='lparen'>(</span> <span class='id identifier rubyid_inline_mult'>inline_mult</span><span class='lparen'>(</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>c</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>a1</span><span class='tstring_end'>"</span></span> <span class='rparen'>)</span> <span class='rparen'>)</span><span class='semicolon'>;</span>
|
248
|
+
</code></pre>
|
249
|
+
|
250
|
+
<p>Here hookbeg is “rx(” and hookend is “)”. From the C language point of
|
251
|
+
view, this looks like two nested function calls. “rx” is called and its
|
252
|
+
argument is a return value from “inline_mult” function. From Ruby point of
|
253
|
+
view, we want “inline_mult” to be called as a Ruby method. However, by
|
254
|
+
default the macro would terminate to the first closing parenthesis, which
|
255
|
+
would cause a syntax error in the end.</p>
|
256
|
+
|
257
|
+
<p>The solution is to declare “(” as suspension character. Suspension
|
258
|
+
character means that for each occurence of the suspension character, one
|
259
|
+
hookend will be suspended, i.e. de-activated. Hence the first “(” after
|
260
|
+
starting the macro with “rx(”, will suspend the next “)”, i.e. hookend.
|
261
|
+
Since there is only one “(”, there will be only one suspension performed,
|
262
|
+
and the final “)” will terminate the macro. The suspended hookend will be
|
263
|
+
taken as part of the macro body.</p>
|
264
|
+
|
265
|
+
<p>In order to get suspension, a multihook is declared including a suspension
|
266
|
+
character/string.</p>
|
267
|
+
|
268
|
+
<pre class="code ruby"><code class="ruby"><span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>*-<+Mucgly.multihook( [ "rx(", ")", "(" ] )>-*</span><span class='regexp_end'>/</span></span></code></pre>
|
269
|
+
|
270
|
+
<p>Suspensions could be replaced with simple escape of the first “)” within
|
271
|
+
the macro call, but this is inconvenient, and might potentially cause
|
272
|
+
issues with language mode of the host language.</p>
|
273
|
+
|
274
|
+
<p>Suspension mechanism is not bullet proof, and thus does not always
|
275
|
+
guarantee language mode compatibility. Languages with C based syntax work
|
276
|
+
well since they use the same style of function argument lists and string
|
277
|
+
conventions as in Ruby. Other type of languages might not benefit from this
|
278
|
+
feature.</p>
|
279
|
+
|
280
|
+
<h3 id="label-Eater">Eater</h3>
|
281
|
+
|
282
|
+
<p>Eater is character/string which follows hookesc and designates that the
|
283
|
+
following char should be removed. This applies to both inside and outside
|
284
|
+
macros. The reason for adding “extra” characters to input could be for
|
285
|
+
example to trick the language mode of the host language to change coloring.</p>
|
286
|
+
|
287
|
+
<p>Eater can be set with “:eater” or with “Mucgly.seteater”. If
|
288
|
+
“Mucgly.seteater” is passed a nil, the Eater feature is disabled and
|
289
|
+
hookesc behaves as by default.</p>
|
290
|
+
|
232
291
|
<h2 id="label-Special+commands">Special commands</h2>
|
233
292
|
|
234
293
|
<p>In addition to regular Ruby code the macros are allowed to include so
|
@@ -355,6 +414,9 @@ Hook-commands change the current hook values.</p>
|
|
355
414
|
</dd><dt>hookesc
|
356
415
|
<dd>
|
357
416
|
<p>Get hookesc value.</p>
|
417
|
+
</dd><dt>sethook
|
418
|
+
<dd>
|
419
|
+
<p>Set hookbeg and hookend values.</p>
|
358
420
|
</dd><dt>sethookbeg
|
359
421
|
<dd>
|
360
422
|
<p>Set hookbeg value.</p>
|
@@ -466,9 +528,9 @@ GEM executable (i.e. same command line options).</p>
|
|
466
528
|
</div></div>
|
467
529
|
|
468
530
|
<div id="footer">
|
469
|
-
Generated on
|
531
|
+
Generated on Mon Oct 24 20:35:30 2016 by
|
470
532
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
471
|
-
0.8.7.6 (ruby-2.1
|
533
|
+
0.8.7.6 (ruby-2.3.1).
|
472
534
|
</div>
|
473
535
|
|
474
536
|
</body>
|
@@ -103,9 +103,9 @@
|
|
103
103
|
</div>
|
104
104
|
|
105
105
|
<div id="footer">
|
106
|
-
Generated on
|
106
|
+
Generated on Mon Oct 24 20:35:30 2016 by
|
107
107
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
108
|
-
0.8.7.6 (ruby-2.1
|
108
|
+
0.8.7.6 (ruby-2.3.1).
|
109
109
|
</div>
|
110
110
|
|
111
111
|
</body>
|
data/ext/mucgly/mucgly.c
CHANGED
@@ -81,11 +81,13 @@ void mucgly_debug( void ) {}
|
|
81
81
|
|
82
82
|
|
83
83
|
/**
|
84
|
-
* Pair of hooks for macro beginning and end.
|
84
|
+
* Pair of hooks for macro beginning and end. Plus optional suspension
|
85
|
+
* marker.
|
85
86
|
*/
|
86
87
|
typedef struct hookpair_s {
|
87
|
-
gchar* beg; /**< Hookbeg for
|
88
|
-
gchar* end; /**< Hookend for
|
88
|
+
gchar* beg; /**< Hookbeg for macro. */
|
89
|
+
gchar* end; /**< Hookend for macro. */
|
90
|
+
gchar* susp; /**< Suspender for macro. */
|
89
91
|
} hookpair_t;
|
90
92
|
|
91
93
|
|
@@ -110,6 +112,7 @@ typedef struct stackfile_s {
|
|
110
112
|
|
111
113
|
hookpair_t hook; /**< Pair of hooks for macro boundary. */
|
112
114
|
gchar* hookesc; /**< Hookesc for input file. */
|
115
|
+
gchar* eater; /**< Eater. */
|
113
116
|
|
114
117
|
hookpair_t* multi; /**< Pairs of hooks for multi-hooking. */
|
115
118
|
int multi_cnt; /**< Number of pairs in multi-hooking. */
|
@@ -117,10 +120,10 @@ typedef struct stackfile_s {
|
|
117
120
|
/** Current hook, as stack to support nesting macros. */
|
118
121
|
GList* curhook;
|
119
122
|
|
120
|
-
/** Hookesc is same as hookbeg.
|
123
|
+
/** Hookesc is same as hookbeg. Speed-up for input processing. */
|
121
124
|
gboolean hook_esc_eq_beg;
|
122
125
|
|
123
|
-
/** Hookesc is same as hookend.
|
126
|
+
/** Hookesc is same as hookend. Speed-up for input processing. */
|
124
127
|
gboolean hook_esc_eq_end;
|
125
128
|
|
126
129
|
/** Lookup-table for the first chars of hooks. Speeds up input processing. */
|
@@ -169,6 +172,7 @@ typedef struct pstate_s {
|
|
169
172
|
GString* match_buf; /**< Match str buffer. */
|
170
173
|
|
171
174
|
int in_macro; /**< Processing within macro. */
|
175
|
+
int suspension; /**< Suspension level. */
|
172
176
|
|
173
177
|
GList* output; /**< Stack of output streams. */
|
174
178
|
|
@@ -215,8 +219,9 @@ pstate_t* ruby_ps;
|
|
215
219
|
* ------------------------------------------------------------ */
|
216
220
|
|
217
221
|
void sf_update_hook_cache( stackfile_t* sf );
|
218
|
-
void sf_multi_hook( stackfile_t* sf, const char* beg, const char* end );
|
222
|
+
void sf_multi_hook( stackfile_t* sf, const char* beg, const char* end, const char* susp );
|
219
223
|
gchar* ps_current_hookend( pstate_t* ps );
|
224
|
+
gchar* ps_current_hooksusp( pstate_t* ps );
|
220
225
|
|
221
226
|
|
222
227
|
|
@@ -236,7 +241,7 @@ gchar* ps_current_hookend( pstate_t* ps );
|
|
236
241
|
int len_str_cmp( char* str1, char* str2 )
|
237
242
|
{
|
238
243
|
int len = strlen( str1 );
|
239
|
-
|
244
|
+
|
240
245
|
if ( !strncmp( str1, str2, len ) )
|
241
246
|
return len;
|
242
247
|
else
|
@@ -339,17 +344,18 @@ void mucgly_fatal( stackfile_t* sf, char* format, ... )
|
|
339
344
|
|
340
345
|
|
341
346
|
/**
|
342
|
-
*
|
347
|
+
* Copy hookpair content.
|
343
348
|
*
|
344
349
|
* @param from Source.
|
345
350
|
* @param to Destination.
|
346
351
|
*
|
347
352
|
* @return Destination.
|
348
353
|
*/
|
349
|
-
hookpair_t*
|
354
|
+
hookpair_t* hookpair_cpy( hookpair_t* from, hookpair_t* to )
|
350
355
|
{
|
351
356
|
to->beg = g_strdup( from->beg );
|
352
357
|
to->end = g_strdup( from->end );
|
358
|
+
to->susp = g_strdup( from->susp );
|
353
359
|
return to;
|
354
360
|
}
|
355
361
|
|
@@ -363,6 +369,7 @@ void hookpair_del( hookpair_t* pair )
|
|
363
369
|
{
|
364
370
|
g_free( pair->beg );
|
365
371
|
g_free( pair->end );
|
372
|
+
g_free( pair->susp );
|
366
373
|
}
|
367
374
|
|
368
375
|
|
@@ -424,7 +431,7 @@ stackfile_t* sf_new( gchar* filename, stackfile_t* inherit )
|
|
424
431
|
if ( inherit )
|
425
432
|
{
|
426
433
|
/* Inherited hook values. */
|
427
|
-
|
434
|
+
hookpair_cpy( &inherit->hook, &sf->hook );
|
428
435
|
sf->hookesc = g_strdup( inherit->hookesc );
|
429
436
|
|
430
437
|
/* Setup fast-lookup caches. */
|
@@ -434,7 +441,7 @@ stackfile_t* sf_new( gchar* filename, stackfile_t* inherit )
|
|
434
441
|
{
|
435
442
|
for ( int i = 0; i < inherit->multi_cnt; i++ )
|
436
443
|
{
|
437
|
-
sf_multi_hook( sf, inherit->multi[i].beg, inherit->multi[i].end );
|
444
|
+
sf_multi_hook( sf, inherit->multi[i].beg, inherit->multi[i].end, inherit->multi[i].susp );
|
438
445
|
}
|
439
446
|
}
|
440
447
|
}
|
@@ -495,7 +502,7 @@ void sf_rem( stackfile_t* sf )
|
|
495
502
|
|
496
503
|
hookpair_del( &sf->hook );
|
497
504
|
g_free( sf->hookesc );
|
498
|
-
|
505
|
+
|
499
506
|
if ( sf->multi )
|
500
507
|
{
|
501
508
|
for ( int i = 0; i < sf->multi_cnt; i++ )
|
@@ -517,7 +524,7 @@ void sf_rem( stackfile_t* sf )
|
|
517
524
|
int sf_get( stackfile_t* sf )
|
518
525
|
{
|
519
526
|
int ret;
|
520
|
-
|
527
|
+
|
521
528
|
re_read:
|
522
529
|
if ( sf->buf->len > 0 )
|
523
530
|
{
|
@@ -615,6 +622,8 @@ void sf_update_hook_cache( stackfile_t* sf )
|
|
615
622
|
/* Add the latest addition to 1st char lookup. */
|
616
623
|
sf->hook_1st_chars[ sf->multi[ sf->multi_cnt-1 ].beg[0] ] = 1;
|
617
624
|
sf->hook_1st_chars[ sf->multi[ sf->multi_cnt-1 ].end[0] ] = 1;
|
625
|
+
if ( sf->multi[ sf->multi_cnt-1 ].susp )
|
626
|
+
sf->hook_1st_chars[ sf->multi[ sf->multi_cnt-1 ].susp[0] ] = 1;
|
618
627
|
|
619
628
|
sf->hook_1st_chars[ sf->hookesc[0] ] = 1;
|
620
629
|
}
|
@@ -681,6 +690,24 @@ void sf_set_hook( stackfile_t* sf, hook_t hook, char* value )
|
|
681
690
|
}
|
682
691
|
|
683
692
|
|
693
|
+
/**
|
694
|
+
* Set eater value.
|
695
|
+
*
|
696
|
+
* @param sf Stackfile.
|
697
|
+
* @param value New eater value.
|
698
|
+
*/
|
699
|
+
void sf_set_eater( stackfile_t* sf, char* value )
|
700
|
+
{
|
701
|
+
if ( sf->eater )
|
702
|
+
g_free( sf->eater );
|
703
|
+
|
704
|
+
sf->eater = NULL;
|
705
|
+
if ( value )
|
706
|
+
sf->eater = g_strdup( value );
|
707
|
+
}
|
708
|
+
|
709
|
+
|
710
|
+
|
684
711
|
/**
|
685
712
|
* Add multi-hook pair.
|
686
713
|
*
|
@@ -688,7 +715,7 @@ void sf_set_hook( stackfile_t* sf, hook_t hook, char* value )
|
|
688
715
|
* @param beg Hookbeg of pair.
|
689
716
|
* @param end Hookend of pair.
|
690
717
|
*/
|
691
|
-
void sf_multi_hook( stackfile_t* sf, const char* beg, const char* end )
|
718
|
+
void sf_multi_hook( stackfile_t* sf, const char* beg, const char* end, const char* susp )
|
692
719
|
{
|
693
720
|
/* Check that hooks don't match escape. */
|
694
721
|
if ( !g_strcmp0( sf->hookesc, beg )
|
@@ -702,7 +729,7 @@ void sf_multi_hook( stackfile_t* sf, const char* beg, const char* end )
|
|
702
729
|
{
|
703
730
|
/* Allocate enough pairs. */
|
704
731
|
sf->multi = g_new0( hookpair_t, MULTI_LIMIT );
|
705
|
-
sf->multi[0] = (hookpair_t) {0,0};
|
732
|
+
sf->multi[0] = (hookpair_t) {0,0,0};
|
706
733
|
sf->multi_cnt = 0;
|
707
734
|
|
708
735
|
/* Clear non-multi-mode lookups. */
|
@@ -717,8 +744,10 @@ void sf_multi_hook( stackfile_t* sf, const char* beg, const char* end )
|
|
717
744
|
|
718
745
|
sf->multi[sf->multi_cnt].beg = g_strdup( beg );
|
719
746
|
sf->multi[sf->multi_cnt].end = g_strdup( end );
|
747
|
+
sf->multi[sf->multi_cnt].susp = g_strdup( susp );
|
748
|
+
|
720
749
|
sf->multi_cnt++;
|
721
|
-
sf->multi[sf->multi_cnt] = (hookpair_t) {0,0};
|
750
|
+
sf->multi[sf->multi_cnt] = (hookpair_t) {0,0,0};
|
722
751
|
|
723
752
|
sf_update_hook_cache( sf );
|
724
753
|
}
|
@@ -1040,10 +1069,11 @@ pstate_t* ps_new( gchar* outfile )
|
|
1040
1069
|
ps->fs = fs_new();
|
1041
1070
|
|
1042
1071
|
ps->in_macro = 0;
|
1072
|
+
ps->suspension = 0;
|
1043
1073
|
|
1044
1074
|
/* Preview input buffer. */
|
1045
1075
|
ps->check_buf = g_string_sized_new( 0 );
|
1046
|
-
|
1076
|
+
|
1047
1077
|
/* Top level input buffer. */
|
1048
1078
|
ps->macro_buf = g_string_sized_new( 0 );
|
1049
1079
|
|
@@ -1068,7 +1098,7 @@ pstate_t* ps_new( gchar* outfile )
|
|
1068
1098
|
void ps_rem( pstate_t* ps )
|
1069
1099
|
{
|
1070
1100
|
fs_rem( ps->fs );
|
1071
|
-
|
1101
|
+
|
1072
1102
|
g_string_free( ps->check_buf, TRUE );
|
1073
1103
|
g_string_free( ps->macro_buf, TRUE );
|
1074
1104
|
|
@@ -1121,10 +1151,10 @@ gboolean ps_check( pstate_t* ps, gchar* match, gboolean erase )
|
|
1121
1151
|
GString* input;
|
1122
1152
|
int len;
|
1123
1153
|
gboolean ret;
|
1124
|
-
|
1154
|
+
|
1125
1155
|
/* Dup match string since it might disappear if Filestack stack is
|
1126
1156
|
popped. */
|
1127
|
-
|
1157
|
+
|
1128
1158
|
g_string_assign( ps->match_buf, match );
|
1129
1159
|
|
1130
1160
|
len = strlen( match );
|
@@ -1178,7 +1208,7 @@ void ps_push_curhook( stackfile_t* sf, hookpair_t* pair )
|
|
1178
1208
|
{
|
1179
1209
|
sf->curhook = g_list_prepend(
|
1180
1210
|
sf->curhook,
|
1181
|
-
|
1211
|
+
hookpair_cpy( pair, g_new0( hookpair_t, 1 ) ) );
|
1182
1212
|
}
|
1183
1213
|
|
1184
1214
|
|
@@ -1252,12 +1282,51 @@ gboolean ps_check_hookend( pstate_t* ps )
|
|
1252
1282
|
}
|
1253
1283
|
|
1254
1284
|
|
1285
|
+
/**
|
1286
|
+
* Check input for hooksusp.
|
1287
|
+
*
|
1288
|
+
* @param ps Pstate.
|
1289
|
+
*
|
1290
|
+
* @return TRUE on match.
|
1291
|
+
*/
|
1292
|
+
gboolean ps_check_hooksusp( pstate_t* ps )
|
1293
|
+
{
|
1294
|
+
gchar* susp;
|
1295
|
+
|
1296
|
+
if ( !ps_has_file(ps) )
|
1297
|
+
return FALSE;
|
1298
|
+
else if ( susp = ps_current_hooksusp(ps) )
|
1299
|
+
return ps_check( ps, susp, TRUE );
|
1300
|
+
else
|
1301
|
+
return FALSE;
|
1302
|
+
}
|
1303
|
+
|
1304
|
+
|
1305
|
+
/**
|
1306
|
+
* Check input for eater.
|
1307
|
+
*
|
1308
|
+
* @param ps Pstate.
|
1309
|
+
*
|
1310
|
+
* @return TRUE on match.
|
1311
|
+
*/
|
1312
|
+
gboolean ps_check_eater( pstate_t* ps )
|
1313
|
+
{
|
1314
|
+
if ( !ps_has_file(ps) )
|
1315
|
+
return FALSE;
|
1316
|
+
|
1317
|
+
if ( ps_topfile(ps)->eater )
|
1318
|
+
return ps_check( ps, ps_topfile(ps)->eater, TRUE );
|
1319
|
+
else
|
1320
|
+
return FALSE;
|
1321
|
+
}
|
1322
|
+
|
1323
|
+
|
1255
1324
|
/**
|
1256
1325
|
* Return hookbeg string that opened the current macro.
|
1257
1326
|
*
|
1258
1327
|
* @param ps PState.
|
1259
1328
|
*
|
1260
|
-
* @return
|
1329
|
+
* @return
|
1261
1330
|
*/
|
1262
1331
|
gchar* ps_current_hookbeg( pstate_t* ps )
|
1263
1332
|
{
|
@@ -1268,11 +1337,11 @@ gchar* ps_current_hookbeg( pstate_t* ps )
|
|
1268
1337
|
|
1269
1338
|
|
1270
1339
|
/**
|
1271
|
-
* Return hookend string that
|
1340
|
+
* Return hookend string that closes the current macro.
|
1272
1341
|
*
|
1273
1342
|
* @param ps PState.
|
1274
1343
|
*
|
1275
|
-
* @return
|
1344
|
+
* @return
|
1276
1345
|
*/
|
1277
1346
|
gchar* ps_current_hookend( pstate_t* ps )
|
1278
1347
|
{
|
@@ -1282,6 +1351,20 @@ gchar* ps_current_hookend( pstate_t* ps )
|
|
1282
1351
|
}
|
1283
1352
|
|
1284
1353
|
|
1354
|
+
/**
|
1355
|
+
* Return hooksusp string that suspends the current hookend.
|
1356
|
+
*
|
1357
|
+
* @param ps PState.
|
1358
|
+
*
|
1359
|
+
* @return
|
1360
|
+
*/
|
1361
|
+
gchar* ps_current_hooksusp( pstate_t* ps )
|
1362
|
+
{
|
1363
|
+
hookpair_t* h;
|
1364
|
+
h = ps_topfile(ps)->curhook->data;
|
1365
|
+
return h->susp;
|
1366
|
+
}
|
1367
|
+
|
1285
1368
|
|
1286
1369
|
/**
|
1287
1370
|
* Get char (through Filestack).
|
@@ -1310,7 +1393,7 @@ void ps_out( pstate_t* ps, int c )
|
|
1310
1393
|
{
|
1311
1394
|
if ( c == '\n' )
|
1312
1395
|
of->lineno++;
|
1313
|
-
|
1396
|
+
|
1314
1397
|
fputc( c, of->fh );
|
1315
1398
|
if ( ps->flush )
|
1316
1399
|
fflush( of->fh );
|
@@ -1432,6 +1515,18 @@ void ps_collect( pstate_t* ps, int c )
|
|
1432
1515
|
}
|
1433
1516
|
|
1434
1517
|
|
1518
|
+
/**
|
1519
|
+
* Add str content to macro.
|
1520
|
+
*
|
1521
|
+
* @param ps Pstate.
|
1522
|
+
* @param str String to add.
|
1523
|
+
*/
|
1524
|
+
void ps_collect_str( pstate_t* ps, gchar* str )
|
1525
|
+
{
|
1526
|
+
g_string_append( ps->macro_buf, str );
|
1527
|
+
}
|
1528
|
+
|
1529
|
+
|
1435
1530
|
/**
|
1436
1531
|
* Enter first level macro and setup state accordingly.
|
1437
1532
|
*
|
@@ -1444,7 +1539,7 @@ void ps_enter_macro( pstate_t* ps )
|
|
1444
1539
|
|
1445
1540
|
/* Store macro start info. */
|
1446
1541
|
sf_mark_macro( ps_topfile( ps ) );
|
1447
|
-
|
1542
|
+
|
1448
1543
|
ps_start_collect( ps );
|
1449
1544
|
}
|
1450
1545
|
|
@@ -1553,7 +1648,7 @@ void ps_load_ruby_file( pstate_t* ps, gchar* filename )
|
|
1553
1648
|
gboolean ps_eval_cmd( pstate_t* ps )
|
1554
1649
|
{
|
1555
1650
|
char* cmd;
|
1556
|
-
|
1651
|
+
|
1557
1652
|
cmd = ps_get_macro( ps );
|
1558
1653
|
|
1559
1654
|
if ( cmd[0] == ':' )
|
@@ -1570,6 +1665,8 @@ gboolean ps_eval_cmd( pstate_t* ps )
|
|
1570
1665
|
sf_set_hook( ps_topfile(ps), hook_end, &cmd[ len+1 ] );
|
1571
1666
|
else if ( ( len = len_str_cmp( ":hookesc", cmd ) ) )
|
1572
1667
|
sf_set_hook( ps_topfile(ps), hook_esc, &cmd[ len+1 ] );
|
1668
|
+
else if ( ( len = len_str_cmp( ":eater", cmd ) ) )
|
1669
|
+
sf_set_eater( ps_topfile(ps), &cmd[ len+1 ] );
|
1573
1670
|
|
1574
1671
|
else if ( ( len = len_str_cmp( ":hookall", cmd ) ) )
|
1575
1672
|
{
|
@@ -1581,7 +1678,7 @@ gboolean ps_eval_cmd( pstate_t* ps )
|
|
1581
1678
|
else if ( ( len = len_str_cmp( ":hook", cmd ) ) )
|
1582
1679
|
{
|
1583
1680
|
gchar** pieces;
|
1584
|
-
|
1681
|
+
|
1585
1682
|
pieces = g_strsplit( &cmd[ len+1 ], " ", 2 );
|
1586
1683
|
if ( g_strv_length( pieces ) == 2 )
|
1587
1684
|
{
|
@@ -1629,13 +1726,13 @@ gboolean ps_eval_cmd( pstate_t* ps )
|
|
1629
1726
|
mucgly_error( ps_topfile(ps), "Unknown internal command: \"%s\"", &cmd[len+1] );
|
1630
1727
|
}
|
1631
1728
|
}
|
1632
|
-
|
1729
|
+
|
1633
1730
|
else if ( cmd[0] == '.' )
|
1634
1731
|
{
|
1635
1732
|
/* Mucgly variable output. */
|
1636
1733
|
ps_out_str( ps, ps_eval_ruby_str( ps, &cmd[1], TRUE, NULL ) );
|
1637
1734
|
}
|
1638
|
-
|
1735
|
+
|
1639
1736
|
else if ( cmd[0] == '/' )
|
1640
1737
|
{
|
1641
1738
|
/* Mucgly comment, do nothing. */
|
@@ -1652,7 +1749,7 @@ gboolean ps_eval_cmd( pstate_t* ps )
|
|
1652
1749
|
|
1653
1750
|
ps_out_str( ps, ps_current_hookend( ps ) );
|
1654
1751
|
}
|
1655
|
-
|
1752
|
+
|
1656
1753
|
else
|
1657
1754
|
{
|
1658
1755
|
/* Ruby code execution. */
|
@@ -1703,7 +1800,7 @@ void ps_process_hook_end_seq( pstate_t* ps, gboolean* do_break )
|
|
1703
1800
|
ps->post_pop = FALSE;
|
1704
1801
|
fs_pop_file( ps->fs );
|
1705
1802
|
}
|
1706
|
-
}
|
1803
|
+
}
|
1707
1804
|
}
|
1708
1805
|
|
1709
1806
|
|
@@ -1770,7 +1867,7 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1770
1867
|
|
1771
1868
|
for (;;)
|
1772
1869
|
{
|
1773
|
-
|
1870
|
+
|
1774
1871
|
/* For each input char, we must explicitly read it since
|
1775
1872
|
otherwise the Filestack does not operate correctly, i.e. we
|
1776
1873
|
are not allowed to put back to stream after EOF has been
|
@@ -1804,7 +1901,6 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1804
1901
|
}
|
1805
1902
|
else
|
1806
1903
|
{
|
1807
|
-
|
1808
1904
|
if ( ( c == ' ' || c == '\n' ) &&
|
1809
1905
|
ps_topfile(ps)->hook_esc_eq_end )
|
1810
1906
|
{
|
@@ -1813,6 +1909,15 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1813
1909
|
if ( do_break )
|
1814
1910
|
break;
|
1815
1911
|
}
|
1912
|
+
else if ( ps_topfile(ps)->eater
|
1913
|
+
&& ps_topfile(ps)->eater[0] == c )
|
1914
|
+
{
|
1915
|
+
fs_put( ps->fs, c );
|
1916
|
+
if ( ps_check_eater( ps ) )
|
1917
|
+
ps_in( ps );
|
1918
|
+
else
|
1919
|
+
ps_collect( ps, c );
|
1920
|
+
}
|
1816
1921
|
else
|
1817
1922
|
{
|
1818
1923
|
ps_collect( ps, c );
|
@@ -1832,6 +1937,15 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1832
1937
|
/* EOF */
|
1833
1938
|
break;
|
1834
1939
|
}
|
1940
|
+
else if ( ps_topfile(ps)->eater
|
1941
|
+
&& ps_topfile(ps)->eater[0] == c )
|
1942
|
+
{
|
1943
|
+
fs_put( ps->fs, c );
|
1944
|
+
if ( ps_check_eater( ps ) )
|
1945
|
+
ps_in( ps );
|
1946
|
+
else
|
1947
|
+
ps_out( ps, c );
|
1948
|
+
}
|
1835
1949
|
else
|
1836
1950
|
{
|
1837
1951
|
|
@@ -1862,7 +1976,7 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1862
1976
|
{
|
1863
1977
|
/* Escape is same as hookbeg and escape is
|
1864
1978
|
not used to eat out spaces. */
|
1865
|
-
|
1979
|
+
|
1866
1980
|
/* Put back the extra char (for safety/clarity). */
|
1867
1981
|
fs_put( ps->fs, c );
|
1868
1982
|
|
@@ -1871,7 +1985,7 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1871
1985
|
hook. */
|
1872
1986
|
ps_push_curhook( ps_topfile(ps), &ps_topfile(ps)->hook );
|
1873
1987
|
|
1874
|
-
/* Start collect the macro content. */
|
1988
|
+
/* Start to collect the macro content. */
|
1875
1989
|
ps_enter_macro( ps );
|
1876
1990
|
}
|
1877
1991
|
}
|
@@ -1882,16 +1996,29 @@ void ps_process_file( pstate_t* ps, gchar* infile, gchar* outfile )
|
|
1882
1996
|
}
|
1883
1997
|
}
|
1884
1998
|
}
|
1885
|
-
|
1999
|
+
|
1886
2000
|
}
|
1887
2001
|
}
|
2002
|
+
else if ( ps->in_macro && ps_check_hooksusp( ps ) )
|
2003
|
+
{
|
2004
|
+
ps->suspension++;
|
2005
|
+
ps_collect_str( ps, ps_current_hooksusp( ps ) );
|
2006
|
+
}
|
1888
2007
|
else if ( ps->in_macro && ps_check_hookend( ps ) )
|
1889
2008
|
{
|
1890
2009
|
/* Hookend has priority over hookbeg if we are in
|
1891
2010
|
macro. Also hookend is ignored when outside macro. */
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
2011
|
+
if ( ps->suspension == 0 )
|
2012
|
+
{
|
2013
|
+
ps_process_hook_end_seq( ps, &do_break );
|
2014
|
+
if ( do_break )
|
2015
|
+
break;
|
2016
|
+
}
|
2017
|
+
else
|
2018
|
+
{
|
2019
|
+
ps->suspension--;
|
2020
|
+
ps_collect_str( ps, ps_current_hookend( ps ) );
|
2021
|
+
}
|
1895
2022
|
}
|
1896
2023
|
else if ( ps_check_hookbeg( ps ) )
|
1897
2024
|
{
|
@@ -1958,7 +2085,7 @@ VALUE mucgly_write( VALUE obj, VALUE rstr )
|
|
1958
2085
|
else
|
1959
2086
|
/* Convert to Ruby String. */
|
1960
2087
|
tmp = rb_inspect( rstr );
|
1961
|
-
|
2088
|
+
|
1962
2089
|
str = RSTRING_PTR( tmp );
|
1963
2090
|
ps_out_str( ruby_ps, str );
|
1964
2091
|
return Qnil;
|
@@ -1983,7 +2110,7 @@ VALUE mucgly_puts( VALUE obj, VALUE rstr )
|
|
1983
2110
|
else
|
1984
2111
|
/* Convert to Ruby String. */
|
1985
2112
|
tmp = rb_inspect( rstr );
|
1986
|
-
|
2113
|
+
|
1987
2114
|
str = RSTRING_PTR( tmp );
|
1988
2115
|
|
1989
2116
|
ps_out_str( ruby_ps, str );
|
@@ -2031,6 +2158,31 @@ VALUE mucgly_hookesc( VALUE obj )
|
|
2031
2158
|
}
|
2032
2159
|
|
2033
2160
|
|
2161
|
+
/**
|
2162
|
+
* Mucgly.sethook method. Set both hookben and hookend.
|
2163
|
+
*
|
2164
|
+
* @param obj Not used.
|
2165
|
+
* @param ary Array of hookpairs.
|
2166
|
+
*
|
2167
|
+
* @return Qnil.
|
2168
|
+
*/
|
2169
|
+
VALUE mucgly_sethook( VALUE obj, VALUE hookbeg, VALUE hookend )
|
2170
|
+
{
|
2171
|
+
char* beg, *end;
|
2172
|
+
|
2173
|
+
Check_Type( hookbeg, T_STRING );
|
2174
|
+
Check_Type( hookend, T_STRING );
|
2175
|
+
|
2176
|
+
beg = RSTRING_PTR( hookbeg );
|
2177
|
+
sf_set_hook( ps_topfile( ruby_ps ), hook_beg, beg );
|
2178
|
+
|
2179
|
+
end = RSTRING_PTR( hookend );
|
2180
|
+
sf_set_hook( ps_topfile( ruby_ps ), hook_end, end );
|
2181
|
+
|
2182
|
+
return Qnil;
|
2183
|
+
}
|
2184
|
+
|
2185
|
+
|
2034
2186
|
/**
|
2035
2187
|
* Mucgly.sethookbeg method. Set hookbeg.
|
2036
2188
|
*
|
@@ -2042,6 +2194,7 @@ VALUE mucgly_hookesc( VALUE obj )
|
|
2042
2194
|
VALUE mucgly_sethookbeg( VALUE obj, VALUE rstr )
|
2043
2195
|
{
|
2044
2196
|
char* str;
|
2197
|
+
Check_Type( rstr, T_STRING );
|
2045
2198
|
str = RSTRING_PTR( rstr );
|
2046
2199
|
sf_set_hook( ps_topfile( ruby_ps ), hook_beg, str );
|
2047
2200
|
return Qnil;
|
@@ -2059,6 +2212,7 @@ VALUE mucgly_sethookbeg( VALUE obj, VALUE rstr )
|
|
2059
2212
|
VALUE mucgly_sethookend( VALUE obj, VALUE rstr )
|
2060
2213
|
{
|
2061
2214
|
char* str;
|
2215
|
+
Check_Type( rstr, T_STRING );
|
2062
2216
|
str = RSTRING_PTR( rstr );
|
2063
2217
|
sf_set_hook( ps_topfile( ruby_ps ), hook_end, str );
|
2064
2218
|
return Qnil;
|
@@ -2076,33 +2230,130 @@ VALUE mucgly_sethookend( VALUE obj, VALUE rstr )
|
|
2076
2230
|
VALUE mucgly_sethookesc( VALUE obj, VALUE rstr )
|
2077
2231
|
{
|
2078
2232
|
char* str;
|
2233
|
+
Check_Type( rstr, T_STRING );
|
2079
2234
|
str = RSTRING_PTR( rstr );
|
2080
2235
|
sf_set_hook( ps_topfile( ruby_ps ), hook_esc, str );
|
2081
2236
|
return Qnil;
|
2082
2237
|
}
|
2083
2238
|
|
2084
2239
|
|
2240
|
+
/**
|
2241
|
+
* Mucgly.seteater method. Set eater.
|
2242
|
+
*
|
2243
|
+
* @param obj Not used.
|
2244
|
+
* @param rstr Eater string (Ruby String).
|
2245
|
+
*
|
2246
|
+
* @return Qnil.
|
2247
|
+
*/
|
2248
|
+
VALUE mucgly_seteater( VALUE obj, VALUE rstr )
|
2249
|
+
{
|
2250
|
+
char* str;
|
2251
|
+
|
2252
|
+
if ( RB_TYPE_P( rstr, T_NIL ) )
|
2253
|
+
{
|
2254
|
+
sf_set_eater( ps_topfile( ruby_ps ), NULL );
|
2255
|
+
}
|
2256
|
+
else
|
2257
|
+
{
|
2258
|
+
Check_Type( rstr, T_STRING );
|
2259
|
+
str = RSTRING_PTR( rstr );
|
2260
|
+
sf_set_eater( ps_topfile( ruby_ps ), str );
|
2261
|
+
}
|
2262
|
+
|
2263
|
+
return Qnil;
|
2264
|
+
}
|
2265
|
+
|
2266
|
+
|
2085
2267
|
/**
|
2086
2268
|
* Mucgly.multihook method. Add multihook pairs.
|
2087
2269
|
*
|
2270
|
+
* Arg options:
|
2271
|
+
* [ hb1, he1, su1 ], [ hb2, he2, su2 ], [ hb3, he3 ], ...
|
2272
|
+
* [ hb1, he1, hb2, he2, hb3, he3 ]
|
2273
|
+
* hb1, he1, hb2, he2, hb3, he3, ...
|
2274
|
+
*
|
2088
2275
|
* @param obj Not used.
|
2089
2276
|
* @param ary Array of hookpairs.
|
2090
2277
|
*
|
2091
2278
|
* @return Qnil.
|
2092
2279
|
*/
|
2093
|
-
VALUE mucgly_multihook( VALUE
|
2280
|
+
VALUE mucgly_multihook( int argc, VALUE* argv, VALUE obj )
|
2094
2281
|
{
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
((int) RARRAY_LEN(ary)) );
|
2099
|
-
|
2100
|
-
char* beg, *end;
|
2101
|
-
for ( int i = 0; i < RARRAY_LEN(ary); i += 2 )
|
2282
|
+
char* beg, *end, *susp;
|
2283
|
+
|
2284
|
+
if ( RB_TYPE_P( argv[0], T_STRING ) )
|
2102
2285
|
{
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2286
|
+
if ( ( argc % 2 ) == 0 )
|
2287
|
+
{
|
2288
|
+
for ( int i = 0; i < argc; i += 2 )
|
2289
|
+
{
|
2290
|
+
beg = RSTRING_PTR( argv[i] );
|
2291
|
+
end = RSTRING_PTR( argv[i+1] );
|
2292
|
+
sf_multi_hook( ps_topfile( ruby_ps ), beg, end, NULL );
|
2293
|
+
}
|
2294
|
+
}
|
2295
|
+
else
|
2296
|
+
{
|
2297
|
+
rb_raise( rb_eRuntimeError,
|
2298
|
+
"mucgly: Argument count must be even!" );
|
2299
|
+
}
|
2300
|
+
}
|
2301
|
+
else if ( RB_TYPE_P( argv[0], T_ARRAY ) )
|
2302
|
+
{
|
2303
|
+
VALUE ary;
|
2304
|
+
|
2305
|
+
if ( argc > 1 )
|
2306
|
+
{
|
2307
|
+
/* Using suspensions. */
|
2308
|
+
|
2309
|
+
for ( int i = 0; i < argc; i++ )
|
2310
|
+
{
|
2311
|
+
ary = argv[i];
|
2312
|
+
if ( RARRAY_LEN(ary) == 3 )
|
2313
|
+
{
|
2314
|
+
beg = RSTRING_PTR( RARRAY_PTR(ary)[0] );
|
2315
|
+
end = RSTRING_PTR( RARRAY_PTR(ary)[1] );
|
2316
|
+
susp = RSTRING_PTR( RARRAY_PTR(ary)[2] );
|
2317
|
+
sf_multi_hook( ps_topfile( ruby_ps ), beg, end, susp );
|
2318
|
+
}
|
2319
|
+
else if ( RARRAY_LEN(ary) == 2 )
|
2320
|
+
{
|
2321
|
+
beg = RSTRING_PTR( RARRAY_PTR(ary)[0] );
|
2322
|
+
end = RSTRING_PTR( RARRAY_PTR(ary)[1] );
|
2323
|
+
sf_multi_hook( ps_topfile( ruby_ps ), beg, end, NULL );
|
2324
|
+
}
|
2325
|
+
else
|
2326
|
+
{
|
2327
|
+
rb_raise( rb_eRuntimeError,
|
2328
|
+
"mucgly: Array argument must either two or three long, i.e. beg, end, [susp]!" );
|
2329
|
+
}
|
2330
|
+
}
|
2331
|
+
}
|
2332
|
+
else
|
2333
|
+
{
|
2334
|
+
ary = argv[0];
|
2335
|
+
if ( RARRAY_LEN(ary) == 3 )
|
2336
|
+
{
|
2337
|
+
beg = RSTRING_PTR( RARRAY_PTR(ary)[0] );
|
2338
|
+
end = RSTRING_PTR( RARRAY_PTR(ary)[1] );
|
2339
|
+
susp = RSTRING_PTR( RARRAY_PTR(ary)[2] );
|
2340
|
+
sf_multi_hook( ps_topfile( ruby_ps ), beg, end, susp );
|
2341
|
+
}
|
2342
|
+
else if ( (RARRAY_LEN(ary) % 2) == 0 )
|
2343
|
+
{
|
2344
|
+
for ( int i = 0; i < RARRAY_LEN(ary); i += 2 )
|
2345
|
+
{
|
2346
|
+
beg = RSTRING_PTR( RARRAY_PTR(ary)[i] );
|
2347
|
+
end = RSTRING_PTR( RARRAY_PTR(ary)[i+1] );
|
2348
|
+
sf_multi_hook( ps_topfile( ruby_ps ), beg, end, NULL );
|
2349
|
+
}
|
2350
|
+
}
|
2351
|
+
else
|
2352
|
+
{
|
2353
|
+
rb_raise( rb_eRuntimeError,
|
2354
|
+
"mucgly: Array argument must have either three or even items!" );
|
2355
|
+
}
|
2356
|
+
}
|
2106
2357
|
}
|
2107
2358
|
|
2108
2359
|
return Qnil;
|
@@ -2177,6 +2428,7 @@ VALUE mucgly_pushinput( VALUE obj, VALUE rstr )
|
|
2177
2428
|
{
|
2178
2429
|
char* str;
|
2179
2430
|
|
2431
|
+
Check_Type( rstr, T_STRING );
|
2180
2432
|
str = RSTRING_PTR( rstr );
|
2181
2433
|
fs_push_file_delayed( ruby_ps->fs, str );
|
2182
2434
|
ruby_ps->post_push = TRUE;
|
@@ -2210,8 +2462,10 @@ VALUE mucgly_pushoutput( VALUE obj, VALUE rstr )
|
|
2210
2462
|
{
|
2211
2463
|
char* str;
|
2212
2464
|
|
2465
|
+
Check_Type( rstr, T_STRING );
|
2213
2466
|
str = RSTRING_PTR( rstr );
|
2214
2467
|
ps_push_file( ruby_ps, str );
|
2468
|
+
|
2215
2469
|
return Qnil;
|
2216
2470
|
}
|
2217
2471
|
|
@@ -2307,10 +2561,12 @@ void Init_mucgly( void )
|
|
2307
2561
|
rb_define_module_function( mMucgly, "hookbeg", mucgly_hookbeg, 0 );
|
2308
2562
|
rb_define_module_function( mMucgly, "hookend", mucgly_hookend, 0 );
|
2309
2563
|
rb_define_module_function( mMucgly, "hookesc", mucgly_hookesc, 0 );
|
2564
|
+
rb_define_module_function( mMucgly, "sethook", mucgly_sethook, -1 );
|
2310
2565
|
rb_define_module_function( mMucgly, "sethookbeg", mucgly_sethookbeg, 1 );
|
2311
2566
|
rb_define_module_function( mMucgly, "sethookend", mucgly_sethookend, 1 );
|
2312
2567
|
rb_define_module_function( mMucgly, "sethookesc", mucgly_sethookesc, 1 );
|
2313
|
-
rb_define_module_function( mMucgly, "
|
2568
|
+
rb_define_module_function( mMucgly, "seteater", mucgly_seteater, 1 );
|
2569
|
+
rb_define_module_function( mMucgly, "multihook", mucgly_multihook, -1 );
|
2314
2570
|
rb_define_module_function( mMucgly, "ifilename", mucgly_ifilename, 0 );
|
2315
2571
|
rb_define_module_function( mMucgly, "ilinenumber", mucgly_ilinenumber, 0 );
|
2316
2572
|
rb_define_module_function( mMucgly, "ofilename", mucgly_ofilename, 0 );
|
@@ -2369,7 +2625,7 @@ gchar* infile_to_outfile( gchar* infile, gchar* outfile_tag )
|
|
2369
2625
|
*/
|
2370
2626
|
void mucgly_main( int argc, char** argv )
|
2371
2627
|
{
|
2372
|
-
|
2628
|
+
|
2373
2629
|
/* Setup default hooks etc. */
|
2374
2630
|
stack_default = sf_new( NULL, NULL );
|
2375
2631
|
|
@@ -2535,7 +2791,8 @@ void mucgly_main( int argc, char** argv )
|
|
2535
2791
|
{
|
2536
2792
|
sf_multi_hook( stack_default,
|
2537
2793
|
opt_multi_sep[ cnt ],
|
2538
|
-
opt_multi_sep[ cnt+1 ]
|
2794
|
+
opt_multi_sep[ cnt+1 ],
|
2795
|
+
NULL );
|
2539
2796
|
cnt += 2;
|
2540
2797
|
}
|
2541
2798
|
}
|