diff options
| author | Richard Kistruck | 2007-08-13 16:54:40 +0100 |
|---|---|---|
| committer | Richard Kistruck | 2007-08-13 16:54:40 +0100 |
| commit | d9d4f267df0a1cf0db5c995ff6d799f1faa5f2b7 (patch) | |
| tree | d3527c5ba068931122f6803302e44990014a620d /mps/code | |
| parent | c6663dcbff1c7a33cf26d9729188f04b5941585b (diff) | |
| download | emacs-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.c | 301 | ||||
| -rw-r--r-- | mps/code/mpm.c | 40 | ||||
| -rw-r--r-- | mps/code/mpm.h | 5 |
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 | ||
| 17 | static mps_lib_FILE *FilterStream(void); | 17 | typedef struct RuleStruct { |
| 18 | static int FilterStream_fputc(int c, mps_lib_FILE *stream); | 18 | const char *action; |
| 19 | static 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 | |||
| 29 | struct RuleStruct RulesGlobal[] = { | ||
| 30 | { "+", "*", "*", "*" }, | ||
| 31 | { "-", "DIAGTEST_", "*", "*" }, | ||
| 32 | { NULL, "", "", "" } | ||
| 33 | }; | ||
| 34 | |||
| 35 | struct 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 | |||
| 75 | static mps_lib_FILE *filterStream(void); | ||
| 76 | static int filterStream_fputc(int c, mps_lib_FILE *stream); | ||
| 77 | static int filterStream_fputs(const char *s, mps_lib_FILE *stream); | ||
| 20 | static void diag_test(void); | 78 | static 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 | ||
| 29 | int stream_fputc(int c, mps_lib_FILE *stream) | 87 | int 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 | ||
| 37 | int stream_fputs(const char *s, mps_lib_FILE *stream) | 95 | int 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 | ||
| 69 | struct DiagStruct FilterDiagGlobal; | 127 | struct DiagStruct filterDiagGlobal; |
| 70 | 128 | ||
| 71 | static mps_lib_FILE *FilterStream(void) | 129 | static mps_lib_FILE *filterStream(void) |
| 72 | { | 130 | { |
| 73 | return (mps_lib_FILE*)&FilterDiagGlobal; | 131 | return (mps_lib_FILE*)&filterDiagGlobal; |
| 74 | } | 132 | } |
| 75 | 133 | ||
| 76 | static mps_lib_FILE *FilterUnderlyingStream(void) | 134 | /* filterStream_under: the underlying stream used to output diags */ |
| 135 | /* that pass the filter. */ | ||
| 136 | static 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? */ | ||
| 81 | enum { | 142 | enum { |
| 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 | ||
| 87 | typedef struct RuleStruct { | 148 | static 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 | |||
| 95 | struct RuleStruct RulesGlobalX[] = { | ||
| 96 | { "+", "*", "*", "*" }, | ||
| 97 | { "+", "TraceStart", "*", "*" }, | ||
| 98 | { "+", "TraceStart", "*", "freeSet" }, | ||
| 99 | { NULL, "", "", "" } | ||
| 100 | }; | ||
| 101 | |||
| 102 | struct 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 | |||
| 116 | static 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 | ||
| 133 | static 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 | ||
| 154 | static Bool PatternOccurs(const char *patt, Count pattLen, | 171 | static 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 | ||
| 179 | static Bool MatchLine(Rule rule, Diag diag, Index i, Index j) | 196 | static 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 | ||
| 193 | static Bool MatchPara(Rule rule, Diag diag) | 210 | static 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 | ||
| 205 | static Bool MatchTag(Rule rule, const char *tag) | 222 | static 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 | ||
| 218 | static void LineOutput(Diag diag, Index i, Index j) | 235 | static 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 | ||
| 242 | static void FilterStream_Output(Diag diag, Rule rules) | 259 | static 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 | ||
| 324 | static void FilterStream_TagBegin(mps_lib_FILE *stream, const char *tag) | 341 | static 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 | ||
| 361 | static void FilterStream_TagEnd(mps_lib_FILE *stream, const char *tag) | 378 | static 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 | ||
| 377 | static int FilterStream_fputc(int c, mps_lib_FILE *stream) | 402 | static 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 | ||
| 397 | static int FilterStream_fputs(const char *s, mps_lib_FILE *stream) | 422 | static 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) | |||
| 436 | mps_lib_FILE *DiagStream(void) | 461 | mps_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 | ||
| 445 | static void DiagTagBegin(mps_lib_FILE *stream, const char *tag) | 470 | static 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 | ||
| 459 | static void DiagTagEnd(mps_lib_FILE *stream, const char *tag) | 484 | static 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 | ||
| 498 | void DiagFirstF(const char *tag, ...) | 523 | void 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 | ||
| 527 | void DiagEnd(const char *tag) | 552 | void 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 | ||
| 539 | static void PatternOccurs_test(Bool expect, const char *patt, | 564 | static 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 | ||
| 573 | static void diag_test(void) | 598 | static 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 | ||
| 554 | size_t StringLength(const char *s) | 554 | size_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 | |||
| 568 | Bool 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); | |||
| 147 | extern Res WriteF_firstformat_v(mps_lib_FILE *stream, | 147 | extern Res WriteF_firstformat_v(mps_lib_FILE *stream, |
| 148 | const char *firstformat, va_list args); | 148 | const char *firstformat, va_list args); |
| 149 | 149 | ||
| 150 | extern int stream_fputc(int c, mps_lib_FILE *stream); | 150 | extern int Stream_fputc(int c, mps_lib_FILE *stream); |
| 151 | extern int stream_fputs(const char *s, mps_lib_FILE *stream); | 151 | extern 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 | ||
| 157 | extern size_t StringLength(const char *s); | 157 | extern size_t StringLength(const char *s); |
| 158 | extern Bool StringEqual(const char *s1, const char *s2); | ||
| 158 | 159 | ||
| 159 | 160 | ||
| 160 | /* Version Determination | 161 | /* Version Determination |