aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Kistruck2007-08-13 16:54:40 +0100
committerRichard Kistruck2007-08-13 16:54:40 +0100
commitd9d4f267df0a1cf0db5c995ff6d799f1faa5f2b7 (patch)
treed3527c5ba068931122f6803302e44990014a620d /mps/code
parentc6663dcbff1c7a33cf26d9729188f04b5941585b (diff)
downloademacs-d9d4f267df0a1cf0db5c995ff6d799f1faa5f2b7.tar.gz
emacs-d9d4f267df0a1cf0db5c995ff6d799f1faa5f2b7.zip
Mps br/diagtag: give helpful message if diag_end tag does not match.
(tidyup) Move RulesGlobal to head of file; write instructions. (tidyup) Move StringEqual into mpm.c (with StringLength); add AVER. (cosmetic) Correct case of names: module-interface names begin uppercase; local names begin lowercase. Tags should be C identifiers. Copied from Perforce Change: 163112 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/diag.c301
-rw-r--r--mps/code/mpm.c40
-rw-r--r--mps/code/mpm.h5
3 files changed, 197 insertions, 149 deletions
diff --git a/mps/code/diag.c b/mps/code/diag.c
index ae028712366..f75d7770293 100644
--- a/mps/code/diag.c
+++ b/mps/code/diag.c
@@ -14,30 +14,88 @@
14#include "mpslib.h" /* for mps_lib_stdout */ 14#include "mpslib.h" /* for mps_lib_stdout */
15 15
16 16
17static mps_lib_FILE *FilterStream(void); 17typedef struct RuleStruct {
18static int FilterStream_fputc(int c, mps_lib_FILE *stream); 18 const char *action;
19static int FilterStream_fputs(const char *s, mps_lib_FILE *stream); 19 const char *tag;
20 const char *para;
21 const char *line;
22 int tpMatch; /* .tpmatch */
23 /* @@ needs sig; Note: at end, to make initializer expression easy */
24} *Rule;
25
26
27/* RulesGlobal -- throw away some diags (see instructions below) */
28
29struct RuleStruct RulesGlobal[] = {
30 { "+", "*", "*", "*" },
31 { "-", "DIAGTEST_", "*", "*" },
32 { NULL, "", "", "" }
33};
34
35struct RuleStruct RulesGlobalExample[] = {
36 { "+", "*", "*", "*" },
37 { "-", "DIAGTEST_", "*", "*" },
38 { "+", "ChainCondemnAuto", "gens [0..0]", "*" },
39 { "+", "TraceStart", "*", "*" },
40 { "+", "TraceStart", "because code 1:", "*" },
41 { "-", "TraceStart", "*", "controlPool" },
42 { "-", "TraceStart", "*", "ommit" },
43 { "-", "TraceStart", "*", "zoneShift" },
44 { "-", "TraceStart", "*", "alignment" },
45 { "-", "amcScanNailed-loop", "*", "*" },
46 { NULL, "", "", "" }
47};
48
49/* RulesGlobal:
50 *
51 * In your local copy of diag.c, you can modify RulesGlobal as you
52 * wish, to control what diags you see.
53 *
54 * Each rule consists of: action, tag, para, and line. A rule that
55 * matches on TAG, PARA and LINE determines what ACTION is taken
56 * for that line of that diag. Later rules override earlier rules,
57 * ie. the lowest matching rule wins.
58 *
59 * ACTION = "+" (output this line of diag), or "-" (skip this line).
60 *
61 * TAG: does pattern (text or *) appear in diag's tag?
62 *
63 * PARA: does pattern (text or *) appear anywhere in diag's text output
64 * (does not match the tag)?
65 *
66 * LINE: does pattern (text or *) appear on this line of the diag
67 * text?
68 *
69 * Note: a diag that deliberately has no output, eg.
70 * DIAG_SINGLEF(( "MyTag", NULL )),
71 * is treated as having a single empty 'line'. See .empty-diag.
72 */
73
74
75static mps_lib_FILE *filterStream(void);
76static int filterStream_fputc(int c, mps_lib_FILE *stream);
77static int filterStream_fputs(const char *s, mps_lib_FILE *stream);
20static void diag_test(void); 78static void diag_test(void);
21 79
22 80
23/* Stream -- output to FilterStream or to a real mps_lib_FILE stream 81/* Stream -- output to filterStream or to a real mps_lib_FILE stream
24 * 82 *
25 * There are only two functions and two destinations; a full class 83 * There are only two functions and two destinations; a full class
26 * hierarchy would be overkill! RHSK 2007-08-08. 84 * hierarchy would be overkill! RHSK 2007-08-08.
27 */ 85 */
28 86
29int stream_fputc(int c, mps_lib_FILE *stream) 87int Stream_fputc(int c, mps_lib_FILE *stream)
30{ 88{
31 if(stream == FilterStream()) 89 if(stream == filterStream())
32 return FilterStream_fputc(c, stream); 90 return filterStream_fputc(c, stream);
33 else 91 else
34 return mps_lib_fputc(c, stream); 92 return mps_lib_fputc(c, stream);
35} 93}
36 94
37int stream_fputs(const char *s, mps_lib_FILE *stream) 95int Stream_fputs(const char *s, mps_lib_FILE *stream)
38{ 96{
39 if(stream == FilterStream()) 97 if(stream == filterStream())
40 return FilterStream_fputs(s, stream); 98 return filterStream_fputs(s, stream);
41 else 99 else
42 return mps_lib_fputs(s, stream); 100 return mps_lib_fputs(s, stream);
43} 101}
@@ -57,7 +115,7 @@ typedef struct DiagStruct {
57} *Diag; 115} *Diag;
58 116
59 117
60/* FilterStream -- capable of filtering diagnostics 118/* filterStream -- capable of filtering diagnostics
61 * 119 *
62 * This is not really an mps_lib_FILE*; it is a single global instance 120 * This is not really an mps_lib_FILE*; it is a single global instance
63 * of a DiagStruct. 121 * of a DiagStruct.
@@ -66,59 +124,33 @@ typedef struct DiagStruct {
66 * (or not) when complete. 124 * (or not) when complete.
67 */ 125 */
68 126
69struct DiagStruct FilterDiagGlobal; 127struct DiagStruct filterDiagGlobal;
70 128
71static mps_lib_FILE *FilterStream(void) 129static mps_lib_FILE *filterStream(void)
72{ 130{
73 return (mps_lib_FILE*)&FilterDiagGlobal; 131 return (mps_lib_FILE*)&filterDiagGlobal;
74} 132}
75 133
76static mps_lib_FILE *FilterUnderlyingStream(void) 134/* filterStream_under: the underlying stream used to output diags */
135/* that pass the filter. */
136static mps_lib_FILE *filterStream_under(void)
77{ 137{
78 return mps_lib_stdout; 138 return mps_lib_stdout;
79} 139}
80 140
141/* .tpmatch: does this rule match current diag's tag and para? */
81enum { 142enum {
82 TPMatch_Unknown = 0, /* initial value = 0 */ 143 TPMatch_Unknown = 0, /* initial value = 0 */
83 TPMatch_Yes, 144 TPMatch_Yes,
84 TPMatch_No 145 TPMatch_No
85}; 146};
86 147
87typedef struct RuleStruct { 148static void rules_diag(Rule rules)
88 const char *action;
89 const char *tag;
90 const char *para;
91 const char *line;
92 int tpMatch; /* does this rule match diag on tag and para? */
93} *Rule;
94
95struct RuleStruct RulesGlobalX[] = {
96 { "+", "*", "*", "*" },
97 { "+", "TraceStart", "*", "*" },
98 { "+", "TraceStart", "*", "freeSet" },
99 { NULL, "", "", "" }
100};
101
102struct RuleStruct RulesGlobal[] = {
103 { "+", "*", "*", "*" },
104 { "-", "DIAGTEST-", "*", "*" },
105 { "+", "ChainCondemnAuto", "gens [0..0]", "*" },
106 { "+", "TraceStart", "*", "*" },
107 { "+", "TraceStart", "because code 1:", "*" },
108 { "-", "TraceStart", "*", "controlPool" },
109 { "-", "TraceStart", "*", "ommit" },
110 { "-", "TraceStart", "*", "zoneShift" },
111 { "-", "TraceStart", "*", "alignment" },
112 { "-", "amcScanNailed-loop", "*", "*" },
113 { NULL, "", "", "" }
114};
115
116static void Rules_diag(Rule rules)
117{ 149{
118 Index ir; 150 Index ir;
119 151
120 AVER(rules); 152 AVER(rules);
121 DIAG_FIRSTF(( "Rules_diag", 153 DIAG_FIRSTF(( "DiagFilter_Rules",
122 "Only showing diags permitted by these tag/paragraph/line" 154 "Only showing diags permitted by these tag/paragraph/line"
123 " rules:\n", NULL )); 155 " rules:\n", NULL ));
124 for(ir = 0; rules[ir].action != NULL; ir++) { 156 for(ir = 0; rules[ir].action != NULL; ir++) {
@@ -127,31 +159,16 @@ static void Rules_diag(Rule rules)
127 rule->para, rule->line, 159 rule->para, rule->line,
128 NULL )); 160 NULL ));
129 } 161 }
130 DIAG_END("Rules_diag"); 162 DIAG_END("DiagFilter_Rules");
131} 163}
132 164
133static Bool StringEqual(const char *s1, const char *s2)
134{
135 Index i;
136
137 AVER(s1);
138 AVER(s2);
139
140 for(i = 0; ; i++) {
141 if(s1[i] != s2[i])
142 return FALSE;
143 if(s1[i] == '\0')
144 break;
145 }
146 return TRUE;
147}
148 165
149/* PatternOccurs -- does patt occur in buf[i..j)? 166/* patternOccurs -- does patt occur in buf[i..j)?
150 * 167 *
151 * Returns true iff patt[0..pattLen) literally occurs in buf[i..j). 168 * Returns true iff patt[0..pattLen) literally occurs in buf[i..j).
152 */ 169 */
153 170
154static Bool PatternOccurs(const char *patt, Count pattLen, 171static Bool patternOccurs(const char *patt, Count pattLen,
155 const char *buf, Index i, Index j) 172 const char *buf, Index i, Index j)
156{ 173{
157 Index im; /* start of tentative match */ 174 Index im; /* start of tentative match */
@@ -176,7 +193,7 @@ static Bool PatternOccurs(const char *patt, Count pattLen,
176 return FALSE; 193 return FALSE;
177} 194}
178 195
179static Bool MatchLine(Rule rule, Diag diag, Index i, Index j) 196static Bool matchLine(Rule rule, Diag diag, Index i, Index j)
180{ 197{
181 AVER(rule); 198 AVER(rule);
182 AVER(diag); 199 AVER(diag);
@@ -186,11 +203,11 @@ static Bool MatchLine(Rule rule, Diag diag, Index i, Index j)
186 if(rule->line[0] == '*') 203 if(rule->line[0] == '*')
187 return TRUE; 204 return TRUE;
188 205
189 return PatternOccurs(rule->line, StringLength(rule->line), 206 return patternOccurs(rule->line, StringLength(rule->line),
190 diag->buf, i, j); 207 diag->buf, i, j);
191} 208}
192 209
193static Bool MatchPara(Rule rule, Diag diag) 210static Bool matchPara(Rule rule, Diag diag)
194{ 211{
195 AVER(rule); 212 AVER(rule);
196 AVER(diag); 213 AVER(diag);
@@ -198,11 +215,11 @@ static Bool MatchPara(Rule rule, Diag diag)
198 if(rule->para[0] == '*') 215 if(rule->para[0] == '*')
199 return TRUE; 216 return TRUE;
200 217
201 return PatternOccurs(rule->para, StringLength(rule->para), 218 return patternOccurs(rule->para, StringLength(rule->para),
202 diag->buf, 0, diag->n); 219 diag->buf, 0, diag->n);
203} 220}
204 221
205static Bool MatchTag(Rule rule, const char *tag) 222static Bool matchTag(Rule rule, const char *tag)
206{ 223{
207 AVER(rule); 224 AVER(rule);
208 AVER(rule->tag); 225 AVER(rule->tag);
@@ -211,11 +228,11 @@ static Bool MatchTag(Rule rule, const char *tag)
211 if(rule->tag[0] == '*') 228 if(rule->tag[0] == '*')
212 return TRUE; 229 return TRUE;
213 230
214 return PatternOccurs(rule->tag, StringLength(rule->tag), 231 return patternOccurs(rule->tag, StringLength(rule->tag),
215 tag, 0, StringLength(tag)); 232 tag, 0, StringLength(tag));
216} 233}
217 234
218static void LineOutput(Diag diag, Index i, Index j) 235static void filterStream_LineOut(Diag diag, Index i, Index j)
219{ 236{
220 int r; 237 int r;
221 238
@@ -223,23 +240,23 @@ static void LineOutput(Diag diag, Index i, Index j)
223 AVER(i <= j); 240 AVER(i <= j);
224 AVER(j <= diag->n); 241 AVER(j <= diag->n);
225 242
226 r = stream_fputc(' ', FilterUnderlyingStream()); 243 r = Stream_fputc(' ', filterStream_under());
227 AVER(r != mps_lib_EOF); 244 AVER(r != mps_lib_EOF);
228 245
229 for(; i < j; i++) { 246 for(; i < j; i++) {
230 char c; 247 char c;
231 c = diag->buf[i]; 248 c = diag->buf[i];
232 r = stream_fputc(c, FilterUnderlyingStream()); 249 r = Stream_fputc(c, filterStream_under());
233 AVER(r != mps_lib_EOF); 250 AVER(r != mps_lib_EOF);
234 } 251 }
235} 252}
236 253
237 254
238/* FilterStream_Output -- output this diag, if the rules select it 255/* filterStream_Output -- output this diag, if the rules select it
239 * 256 *
240 */ 257 */
241 258
242static void FilterStream_Output(Diag diag, Rule rules) 259static void filterStream_Output(Diag diag, Rule rules)
243{ 260{
244 static Bool inside = FALSE; 261 static Bool inside = FALSE;
245 Res res; 262 Res res;
@@ -285,14 +302,14 @@ static void FilterStream_Output(Diag diag, Rule rules)
285 for(;;) { 302 for(;;) {
286 Rule rule = &rules[ir]; 303 Rule rule = &rules[ir];
287 if(rule->tpMatch == TPMatch_Unknown) { 304 if(rule->tpMatch == TPMatch_Unknown) {
288 /* memoize tpMatch */ 305 /* memoize .tpMatch */
289 if(MatchTag(rule, diag->tag) && MatchPara(rule, diag)) { 306 if(matchTag(rule, diag->tag) && matchPara(rule, diag)) {
290 rule->tpMatch = TPMatch_Yes; 307 rule->tpMatch = TPMatch_Yes;
291 } else { 308 } else {
292 rule->tpMatch = TPMatch_No; 309 rule->tpMatch = TPMatch_No;
293 } 310 }
294 } 311 }
295 if(rule->tpMatch == TPMatch_Yes && MatchLine(rule, diag, i, j)) 312 if(rule->tpMatch == TPMatch_Yes && matchLine(rule, diag, i, j))
296 break; 313 break;
297 AVER(ir != 0); /* there must ALWAYS be a matching rule */ 314 AVER(ir != 0); /* there must ALWAYS be a matching rule */
298 ir--; 315 ir--;
@@ -300,28 +317,28 @@ static void FilterStream_Output(Diag diag, Rule rules)
300 317
301 /* Do the rule's action. */ 318 /* Do the rule's action. */
302 if(0) 319 if(0)
303 (void) WriteF(FilterUnderlyingStream(), 320 (void) WriteF(filterStream_under(),
304 "[RULE: $U (of $U);", ir, nr, 321 "[RULE: $U (of $U);", ir, nr,
305 " ACTION: $C]\n", rules[ir].action[0], 322 " ACTION: $C]\n", rules[ir].action[0],
306 NULL); 323 NULL);
307 if(rules[ir].action[0] == '+') { 324 if(rules[ir].action[0] == '+') {
308 if(nolinesyet) { 325 if(nolinesyet) {
309 res = WriteF(FilterUnderlyingStream(), "MPS.$S {", diag->tag, NULL); 326 res = WriteF(filterStream_under(), "MPS.$S {", diag->tag, NULL);
310 AVER(res == ResOK); 327 AVER(res == ResOK);
311 nolinesyet = FALSE; 328 nolinesyet = FALSE;
312 } 329 }
313 LineOutput(diag, i, j); 330 filterStream_LineOut(diag, i, j);
314 } 331 }
315 } 332 }
316 333
317 if(!nolinesyet) { 334 if(!nolinesyet) {
318 res = WriteF(FilterUnderlyingStream(), "}\n", NULL); 335 res = WriteF(filterStream_under(), "}\n", NULL);
319 AVER(res == ResOK); 336 AVER(res == ResOK);
320 } 337 }
321 inside = FALSE; 338 inside = FALSE;
322} 339}
323 340
324static void FilterStream_TagBegin(mps_lib_FILE *stream, const char *tag) 341static void filterStream_TagBegin(mps_lib_FILE *stream, const char *tag)
325{ 342{
326 static Bool first = TRUE; 343 static Bool first = TRUE;
327 Diag diag; 344 Diag diag;
@@ -334,13 +351,13 @@ static void FilterStream_TagBegin(mps_lib_FILE *stream, const char *tag)
334 351
335 if(first) { 352 if(first) {
336 first = FALSE; 353 first = FALSE;
337 Rules_diag(&RulesGlobal[0]); 354 rules_diag(&RulesGlobal[0]);
338 diag_test(); 355 diag_test();
339 } 356 }
340 357
341 if(diag->tag != NULL) { 358 if(diag->tag != NULL) {
342 /* Be helpful to the poor programmer! */ 359 /* Be helpful to the poor programmer! */
343 (void) WriteF(FilterUnderlyingStream(), 360 (void) WriteF(filterStream_under(),
344 "\nWARNING: diag tag \"$S\" is still current" 361 "\nWARNING: diag tag \"$S\" is still current"
345 " (missing DIAG_END()).", 362 " (missing DIAG_END()).",
346 diag->tag, NULL); 363 diag->tag, NULL);
@@ -350,7 +367,7 @@ static void FilterStream_TagBegin(mps_lib_FILE *stream, const char *tag)
350 /* @@ when all diags are tagged, the buffer must be empty */ 367 /* @@ when all diags are tagged, the buffer must be empty */
351 /* @@ but for now, as a courtesy... */ 368 /* @@ but for now, as a courtesy... */
352 if(diag->n > 0) { 369 if(diag->n > 0) {
353 FilterStream_Output(diag, &RulesGlobal[0]); 370 filterStream_Output(diag, &RulesGlobal[0]);
354 diag->n = 0; 371 diag->n = 0;
355 } 372 }
356 373
@@ -358,28 +375,36 @@ static void FilterStream_TagBegin(mps_lib_FILE *stream, const char *tag)
358 diag->tag = tag; 375 diag->tag = tag;
359} 376}
360 377
361static void FilterStream_TagEnd(mps_lib_FILE *stream, const char *tag) 378static void filterStream_TagEnd(mps_lib_FILE *stream, const char *tag)
362{ 379{
363 Diag diag; 380 Diag diag;
364 diag = (Diag)stream; 381 diag = (Diag)stream;
365 /* AVERT(Diag, diag) */ 382 /* AVERT(Diag, diag) */
366 383
367 AVER(diag->tag != NULL); 384 AVER(diag->tag != NULL);
385
386 if(!StringEqual(diag->tag, tag)) {
387 /* Be helpful to the poor programmer! */
388 (void) WriteF(filterStream_under(),
389 "\nWARNING: diag tag \"$S\" is current, "
390 "but got DIAG_END(\"$S\"). (They must match).",
391 diag->tag, tag, NULL);
392 }
368 AVER(StringEqual(diag->tag, tag)); 393 AVER(StringEqual(diag->tag, tag));
369 394
370 /* Output the diag */ 395 /* Output the diag */
371 FilterStream_Output(diag, &RulesGlobal[0]); 396 filterStream_Output(diag, &RulesGlobal[0]);
372 397
373 diag->tag = NULL; 398 diag->tag = NULL;
374 diag->n = 0; 399 diag->n = 0;
375} 400}
376 401
377static int FilterStream_fputc(int c, mps_lib_FILE *stream) 402static int filterStream_fputc(int c, mps_lib_FILE *stream)
378{ 403{
379 Diag diag; 404 Diag diag;
380 405
381 AVER(c != mps_lib_EOF); 406 AVER(c != mps_lib_EOF);
382 AVER(stream == FilterStream()); 407 AVER(stream == filterStream());
383 408
384 diag = (Diag)stream; 409 diag = (Diag)stream;
385 /* AVERT(Diag, diag) */ 410 /* AVERT(Diag, diag) */
@@ -394,14 +419,14 @@ static int FilterStream_fputc(int c, mps_lib_FILE *stream)
394 return c; 419 return c;
395} 420}
396 421
397static int FilterStream_fputs(const char *s, mps_lib_FILE *stream) 422static int filterStream_fputs(const char *s, mps_lib_FILE *stream)
398{ 423{
399 Diag diag; 424 Diag diag;
400 Count l; 425 Count l;
401 Index i; 426 Index i;
402 427
403 AVER(s); 428 AVER(s);
404 AVER(stream == FilterStream()); 429 AVER(stream == filterStream());
405 430
406 diag = (Diag)stream; 431 diag = (Diag)stream;
407 /* AVERT(Diag, diag) */ 432 /* AVERT(Diag, diag) */
@@ -436,19 +461,19 @@ Bool DiagIsOn(void)
436mps_lib_FILE *DiagStream(void) 461mps_lib_FILE *DiagStream(void)
437{ 462{
438 if(1) { 463 if(1) {
439 return FilterStream(); 464 return filterStream();
440 } else { 465 } else {
441 return mps_lib_stdout; 466 return mps_lib_stdout;
442 } 467 }
443} 468}
444 469
445static void DiagTagBegin(mps_lib_FILE *stream, const char *tag) 470static void diagTagBegin(mps_lib_FILE *stream, const char *tag)
446{ 471{
447 AVER(stream); 472 AVER(stream);
448 AVER(tag); 473 AVER(tag);
449 474
450 if(stream == FilterStream()) { 475 if(stream == filterStream()) {
451 FilterStream_TagBegin(stream, tag); 476 filterStream_TagBegin(stream, tag);
452 } else { 477 } else {
453 Res res; 478 Res res;
454 res = WriteF(stream, "MPS.$S {\n", tag, NULL); 479 res = WriteF(stream, "MPS.$S {\n", tag, NULL);
@@ -456,13 +481,13 @@ static void DiagTagBegin(mps_lib_FILE *stream, const char *tag)
456 } 481 }
457} 482}
458 483
459static void DiagTagEnd(mps_lib_FILE *stream, const char *tag) 484static void diagTagEnd(mps_lib_FILE *stream, const char *tag)
460{ 485{
461 AVER(stream); 486 AVER(stream);
462 AVER(tag); 487 AVER(tag);
463 488
464 if(stream == FilterStream()) { 489 if(stream == filterStream()) {
465 FilterStream_TagEnd(stream, tag); 490 filterStream_TagEnd(stream, tag);
466 } else { 491 } else {
467 Res res; 492 Res res;
468 res = WriteF(stream, "} MPS.$S\n", tag, NULL); 493 res = WriteF(stream, "} MPS.$S\n", tag, NULL);
@@ -485,14 +510,14 @@ void DiagSingleF(const char *tag, ...)
485 va_list args; 510 va_list args;
486 Res res; 511 Res res;
487 512
488 DiagTagBegin(DiagStream(), tag); 513 diagTagBegin(DiagStream(), tag);
489 514
490 va_start(args, tag); 515 va_start(args, tag);
491 res = WriteF_v(DiagStream(), args); 516 res = WriteF_v(DiagStream(), args);
492 AVER(res == ResOK); 517 AVER(res == ResOK);
493 va_end(args); 518 va_end(args);
494 519
495 DiagTagEnd(DiagStream(), tag); 520 diagTagEnd(DiagStream(), tag);
496} 521}
497 522
498void DiagFirstF(const char *tag, ...) 523void DiagFirstF(const char *tag, ...)
@@ -500,7 +525,7 @@ void DiagFirstF(const char *tag, ...)
500 va_list args; 525 va_list args;
501 Res res; 526 Res res;
502 527
503 DiagTagBegin(DiagStream(), tag); 528 diagTagBegin(DiagStream(), tag);
504 529
505 va_start(args, tag); 530 va_start(args, tag);
506 res = WriteF_v(DiagStream(), args); 531 res = WriteF_v(DiagStream(), args);
@@ -526,7 +551,7 @@ void DiagMoreF(const char *firstformat, ...)
526 551
527void DiagEnd(const char *tag) 552void DiagEnd(const char *tag)
528{ 553{
529 DiagTagEnd(DiagStream(), tag); 554 diagTagEnd(DiagStream(), tag);
530} 555}
531 556
532 557
@@ -536,7 +561,7 @@ void DiagEnd(const char *tag)
536 * There's no point running them otherwise. RHSK. 561 * There's no point running them otherwise. RHSK.
537 */ 562 */
538 563
539static void PatternOccurs_test(Bool expect, const char *patt, 564static void patternOccurs_test(Bool expect, const char *patt,
540 const char *text) 565 const char *text)
541{ 566{
542 Count pattLen = StringLength(patt); 567 Count pattLen = StringLength(patt);
@@ -547,9 +572,9 @@ static void PatternOccurs_test(Bool expect, const char *patt,
547 Count padLen; 572 Count padLen;
548 Bool occurs; 573 Bool occurs;
549 574
550 /* Call PatternOccurs with this patt and text 3 times: each time */ 575 /* Call patternOccurs with this patt and text 3 times: each time */
551 /* putting the text in the buffer at a different offset, to */ 576 /* putting the text in the buffer at a different offset, to */
552 /* verify that PatternOccurs is not accepting matches outside the */ 577 /* verify that patternOccurs is not accepting matches outside the */
553 /* [i..j) portion of the buffer. */ 578 /* [i..j) portion of the buffer. */
554 579
555 for(start = 0; start < 21; start += 7) { 580 for(start = 0; start < 21; start += 7) {
@@ -565,19 +590,19 @@ static void PatternOccurs_test(Bool expect, const char *patt,
565 for(i = 0; i < padLen; i++) { 590 for(i = 0; i < padLen; i++) {
566 (buf+start+textLen)[i] = 'X'; 591 (buf+start+textLen)[i] = 'X';
567 } 592 }
568 occurs = PatternOccurs(patt, pattLen, buf, start, start+textLen); 593 occurs = patternOccurs(patt, pattLen, buf, start, start+textLen);
569 AVER(occurs == expect); 594 AVER(occurs == expect);
570 } 595 }
571} 596}
572 597
573static void diag_test(void) 598static void diag_test(void)
574{ 599{
575 DIAG_SINGLEF(( "DIAGTEST-Tag1", "text $U.\n", 42, NULL )); 600 DIAG_SINGLEF(( "DIAGTEST_Tag1", "text $U.\n", 42, NULL ));
576 601
577 DIAG_SINGLEF(( "DIAGTEST-EmptyDiag", NULL )); 602 DIAG_SINGLEF(( "DIAGTEST_EmptyDiag", NULL ));
578 603
579 DIAG_FIRSTF(( 604 DIAG_FIRSTF((
580 "DIAGTEST-StringEqual", 605 "DIAGTEST_StringEqual",
581 "Fred = Fred: $U.\n", 606 "Fred = Fred: $U.\n",
582 StringEqual("Fred", "Fred"), 607 StringEqual("Fred", "Fred"),
583 NULL 608 NULL
@@ -588,34 +613,34 @@ static void diag_test(void)
588 DIAG_MOREF(("Fred = 0: $U.\n", StringEqual("Fred", ""), NULL)); 613 DIAG_MOREF(("Fred = 0: $U.\n", StringEqual("Fred", ""), NULL));
589 DIAG_MOREF(("0 = 0: $U.\n", StringEqual("", ""), NULL)); 614 DIAG_MOREF(("0 = 0: $U.\n", StringEqual("", ""), NULL));
590 DIAG_MOREF(("0 = 000: $U.\n", StringEqual("", "\0\0"), NULL)); 615 DIAG_MOREF(("0 = 000: $U.\n", StringEqual("", "\0\0"), NULL));
591 DIAG_END("DIAGTEST-StringEqual"); 616 DIAG_END("DIAGTEST_StringEqual");
592 617
593 DIAG_FIRSTF(( "DIAGTEST-PatternOccurs", NULL )); 618 DIAG_FIRSTF(( "DIAGTEST_patternOccurs", NULL ));
594 PatternOccurs_test(TRUE, "Fred", "Fred"); 619 patternOccurs_test(TRUE, "Fred", "Fred");
595 PatternOccurs_test(TRUE, "Fred", "XFredX"); 620 patternOccurs_test(TRUE, "Fred", "XFredX");
596 PatternOccurs_test(TRUE, "Fred", "FFred"); 621 patternOccurs_test(TRUE, "Fred", "FFred");
597 PatternOccurs_test(TRUE, "Fred", "FrFred"); 622 patternOccurs_test(TRUE, "Fred", "FrFred");
598 PatternOccurs_test(TRUE, "Fred", "FreFred"); 623 patternOccurs_test(TRUE, "Fred", "FreFred");
599 PatternOccurs_test(TRUE, "Fred", "FreFreFFred"); 624 patternOccurs_test(TRUE, "Fred", "FreFreFFred");
600 PatternOccurs_test(TRUE, "Fred", "FredFred"); 625 patternOccurs_test(TRUE, "Fred", "FredFred");
601 PatternOccurs_test(TRUE, "Fred", "FFredFre"); 626 patternOccurs_test(TRUE, "Fred", "FFredFre");
602 PatternOccurs_test(TRUE, "Fred", "FrFredFr"); 627 patternOccurs_test(TRUE, "Fred", "FrFredFr");
603 PatternOccurs_test(TRUE, "Fred", "FreFredF"); 628 patternOccurs_test(TRUE, "Fred", "FreFredF");
604 PatternOccurs_test(TRUE, "Fred", "FreFreFFredFre"); 629 patternOccurs_test(TRUE, "Fred", "FreFreFFredFre");
605 PatternOccurs_test(TRUE, "Fred", "FredFredF"); 630 patternOccurs_test(TRUE, "Fred", "FredFredF");
606 PatternOccurs_test(TRUE, "X", "X"); 631 patternOccurs_test(TRUE, "X", "X");
607 PatternOccurs_test(TRUE, "", "X"); 632 patternOccurs_test(TRUE, "", "X");
608 PatternOccurs_test(TRUE, "", "Whatever"); 633 patternOccurs_test(TRUE, "", "Whatever");
609 PatternOccurs_test(FALSE, "Fred", "Tom"); 634 patternOccurs_test(FALSE, "Fred", "Tom");
610 PatternOccurs_test(FALSE, "X", "Tom"); 635 patternOccurs_test(FALSE, "X", "Tom");
611 PatternOccurs_test(FALSE, "X", "x"); 636 patternOccurs_test(FALSE, "X", "x");
612 PatternOccurs_test(FALSE, "X", ""); 637 patternOccurs_test(FALSE, "X", "");
613 PatternOccurs_test(FALSE, "Whatever", ""); 638 patternOccurs_test(FALSE, "Whatever", "");
614 PatternOccurs_test(FALSE, "Fred", "Fre"); 639 patternOccurs_test(FALSE, "Fred", "Fre");
615 PatternOccurs_test(FALSE, "Fred", "red"); 640 patternOccurs_test(FALSE, "Fred", "red");
616 PatternOccurs_test(FALSE, "Fred", "Fxred"); 641 patternOccurs_test(FALSE, "Fred", "Fxred");
617 PatternOccurs_test(FALSE, "Fred", "Frexd"); 642 patternOccurs_test(FALSE, "Fred", "Frexd");
618 DIAG_END("DIAGTEST-PatternOccurs"); 643 DIAG_END("DIAGTEST_patternOccurs");
619 644
620#if 0 645#if 0
621 DIAG_FIRSTF(( "TestTag2", "text $U.\n", 42, NULL )); 646 DIAG_FIRSTF(( "TestTag2", "text $U.\n", 42, NULL ));
diff --git a/mps/code/mpm.c b/mps/code/mpm.c
index 9f2e0802037..84c9fdc870b 100644
--- a/mps/code/mpm.c
+++ b/mps/code/mpm.c
@@ -258,7 +258,7 @@ static Res WriteWord(mps_lib_FILE *stream, Word w, unsigned base,
258 buf[i] = pad; 258 buf[i] = pad;
259 } 259 }
260 260
261 r = stream_fputs(&buf[i], stream); 261 r = Stream_fputs(&buf[i], stream);
262 if (r == mps_lib_EOF) 262 if (r == mps_lib_EOF)
263 return ResIO; 263 return ResIO;
264 264
@@ -299,7 +299,7 @@ static Res WriteDouble(mps_lib_FILE *stream, double d)
299 int j = 0; 299 int j = 0;
300 300
301 if (F == 0.0) { 301 if (F == 0.0) {
302 if (stream_fputs("0", stream) == mps_lib_EOF) 302 if (Stream_fputs("0", stream) == mps_lib_EOF)
303 return ResIO; 303 return ResIO;
304 return ResOK; 304 return ResOK;
305 } 305 }
@@ -314,7 +314,7 @@ static Res WriteDouble(mps_lib_FILE *stream, double d)
314 for ( ; F >= 1.0 ; F /= 10.0) { 314 for ( ; F >= 1.0 ; F /= 10.0) {
315 E++; 315 E++;
316 if (E > DBL_MAX_10_EXP) { 316 if (E > DBL_MAX_10_EXP) {
317 if (stream_fputs("Infinity", stream) == mps_lib_EOF) 317 if (Stream_fputs("Infinity", stream) == mps_lib_EOF)
318 return ResIO; 318 return ResIO;
319 return ResOK; 319 return ResOK;
320 } 320 }
@@ -401,7 +401,7 @@ static Res WriteDouble(mps_lib_FILE *stream, double d)
401 } 401 }
402 buf[j] = '\0'; /* arnold */ 402 buf[j] = '\0'; /* arnold */
403 403
404 if (stream_fputs(buf, stream) == mps_lib_EOF) 404 if (Stream_fputs(buf, stream) == mps_lib_EOF)
405 return ResIO; 405 return ResIO;
406 return ResOK; 406 return ResOK;
407} 407}
@@ -460,7 +460,7 @@ Res WriteF_firstformat_v(mps_lib_FILE *stream,
460 460
461 while(*format != '\0') { 461 while(*format != '\0') {
462 if (*format != '$') { 462 if (*format != '$') {
463 r = stream_fputc(*format, stream); /* Could be more efficient */ 463 r = Stream_fputc(*format, stream); /* Could be more efficient */
464 if (r == mps_lib_EOF) return ResIO; 464 if (r == mps_lib_EOF) return ResIO;
465 } else { 465 } else {
466 ++format; 466 ++format;
@@ -494,13 +494,13 @@ Res WriteF_firstformat_v(mps_lib_FILE *stream,
494 494
495 case 'S': { /* string */ 495 case 'S': { /* string */
496 WriteFS s = va_arg(args, WriteFS); 496 WriteFS s = va_arg(args, WriteFS);
497 r = stream_fputs((const char *)s, stream); 497 r = Stream_fputs((const char *)s, stream);
498 if (r == mps_lib_EOF) return ResIO; 498 if (r == mps_lib_EOF) return ResIO;
499 } break; 499 } break;
500 500
501 case 'C': { /* character */ 501 case 'C': { /* character */
502 WriteFC c = va_arg(args, WriteFC); /* promoted */ 502 WriteFC c = va_arg(args, WriteFC); /* promoted */
503 r = stream_fputc((int)c, stream); 503 r = Stream_fputc((int)c, stream);
504 if (r == mps_lib_EOF) return ResIO; 504 if (r == mps_lib_EOF) return ResIO;
505 } break; 505 } break;
506 506
@@ -524,7 +524,7 @@ Res WriteF_firstformat_v(mps_lib_FILE *stream,
524 } break; 524 } break;
525 525
526 case '$': { /* dollar char */ 526 case '$': { /* dollar char */
527 r = stream_fputc('$', stream); 527 r = Stream_fputc('$', stream);
528 if (r == mps_lib_EOF) return ResIO; 528 if (r == mps_lib_EOF) return ResIO;
529 } break; 529 } break;
530 530
@@ -549,7 +549,7 @@ Res WriteF_firstformat_v(mps_lib_FILE *stream,
549} 549}
550 550
551 551
552/* StringLength -- Slow substitute for strlen */ 552/* StringLength -- slow substitute for strlen */
553 553
554size_t StringLength(const char *s) 554size_t StringLength(const char *s)
555{ 555{
@@ -563,6 +563,28 @@ size_t StringLength(const char *s)
563} 563}
564 564
565 565
566/* StringEqual -- slow substitute for (strcmp == 0) */
567
568Bool StringEqual(const char *s1, const char *s2)
569{
570 Index i;
571
572 AVER(s1);
573 AVER(s2);
574
575 for(i = 0; ; i++) {
576 if(s1[i] != s2[i])
577 return FALSE;
578 if(s1[i] == '\0') {
579 AVER(s2[i] == '\0');
580 break;
581 }
582 }
583 return TRUE;
584}
585
586
587
566/* C. COPYRIGHT AND LICENSE 588/* C. COPYRIGHT AND LICENSE
567 * 589 *
568 * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>. 590 * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index 8638aa998b4..fc56e1e5062 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -147,14 +147,15 @@ extern Res WriteF_v(mps_lib_FILE *stream, va_list args);
147extern Res WriteF_firstformat_v(mps_lib_FILE *stream, 147extern Res WriteF_firstformat_v(mps_lib_FILE *stream,
148 const char *firstformat, va_list args); 148 const char *firstformat, va_list args);
149 149
150extern int stream_fputc(int c, mps_lib_FILE *stream); 150extern int Stream_fputc(int c, mps_lib_FILE *stream);
151extern int stream_fputs(const char *s, mps_lib_FILE *stream); 151extern int Stream_fputs(const char *s, mps_lib_FILE *stream);
152 152
153 153
154 154
155/* Miscellaneous support -- see <code/mpm.c> */ 155/* Miscellaneous support -- see <code/mpm.c> */
156 156
157extern size_t StringLength(const char *s); 157extern size_t StringLength(const char *s);
158extern Bool StringEqual(const char *s1, const char *s2);
158 159
159 160
160/* Version Determination 161/* Version Determination