Fossil SCM
Improved processing of nested macros in Pikchr.
Commit
f7259ea07c0ce42bc7ef0b6ff613af8f7f31ac179fcedbaca70f54a0b4e26089
Parent
01f6ed9c9a78d80…
1 file changed
+17
-4
+17
-4
| --- src/pikchr.c | ||
| +++ src/pikchr.c | ||
| @@ -7281,14 +7281,15 @@ | ||
| 7281 | 7281 | */ |
| 7282 | 7282 | static unsigned int pik_parse_macro_args( |
| 7283 | 7283 | Pik *p, |
| 7284 | 7284 | const char *z, /* Start of the argument list */ |
| 7285 | 7285 | int n, /* Available bytes */ |
| 7286 | - PToken *args | |
| 7286 | + PToken *args, /* Fill in with the arguments */ | |
| 7287 | + PToken *pOuter /* Arguments of the next outer context, or NULL */ | |
| 7287 | 7288 | ){ |
| 7288 | 7289 | int nArg = 0; |
| 7289 | - int i, sz; | |
| 7290 | + int i, j, sz; | |
| 7290 | 7291 | int iStart; |
| 7291 | 7292 | int depth = 0; |
| 7292 | 7293 | PToken x; |
| 7293 | 7294 | if( z[0]!='(' ) return 0; |
| 7294 | 7295 | args[0].z = z+1; |
| @@ -7315,10 +7316,22 @@ | ||
| 7315 | 7316 | depth--; |
| 7316 | 7317 | } |
| 7317 | 7318 | } |
| 7318 | 7319 | if( z[i]==')' ){ |
| 7319 | 7320 | args[nArg].n = i - iStart; |
| 7321 | + /* Remove leading and trailing whitespace from each argument. | |
| 7322 | + ** If what remains is one of $1, $2, ... $9 then transfer the | |
| 7323 | + ** corresponding argument from the outer context */ | |
| 7324 | + for(j=0; j<=nArg; j++){ | |
| 7325 | + PToken *t = &args[j]; | |
| 7326 | + while( t->n>0 && isspace(t->z[0]) ){ t->n--; t->z++; } | |
| 7327 | + while( t->n>0 && isspace(t->z[t->n-1]) ){ t->n--; } | |
| 7328 | + if( t->n==2 && t->z[0]=='$' && t->z[1]>='1' && t->z[1]<='9' ){ | |
| 7329 | + if( pOuter ) *t = pOuter[t->z[1]-'1']; | |
| 7330 | + else t->n = 0; | |
| 7331 | + } | |
| 7332 | + } | |
| 7320 | 7333 | return i+1; |
| 7321 | 7334 | } |
| 7322 | 7335 | x.z = z; |
| 7323 | 7336 | x.n = 1; |
| 7324 | 7337 | pik_error(p, &x, "unterminated macro argument list"); |
| @@ -7379,11 +7392,11 @@ | ||
| 7379 | 7392 | break; |
| 7380 | 7393 | } |
| 7381 | 7394 | pMac->inUse = 1; |
| 7382 | 7395 | memset(args, 0, sizeof(args)); |
| 7383 | 7396 | p->aCtx[p->nCtx++] = token; |
| 7384 | - sz += pik_parse_macro_args(p, pIn->z+j, pIn->n-j, args); | |
| 7397 | + sz += pik_parse_macro_args(p, pIn->z+j, pIn->n-j, args, aParam); | |
| 7385 | 7398 | pik_tokenize(p, &pMac->macroBody, pParser, args); |
| 7386 | 7399 | p->nCtx--; |
| 7387 | 7400 | pMac->inUse = 0; |
| 7388 | 7401 | }else{ |
| 7389 | 7402 | #if 0 |
| @@ -7622,6 +7635,6 @@ | ||
| 7622 | 7635 | } |
| 7623 | 7636 | return 0; |
| 7624 | 7637 | } |
| 7625 | 7638 | #endif /* PIKCHR_SHELL */ |
| 7626 | 7639 | |
| 7627 | -#line 7652 "pikchr.c" | |
| 7640 | +#line 7665 "pikchr.c" | |
| 7628 | 7641 |
| --- src/pikchr.c | |
| +++ src/pikchr.c | |
| @@ -7281,14 +7281,15 @@ | |
| 7281 | */ |
| 7282 | static unsigned int pik_parse_macro_args( |
| 7283 | Pik *p, |
| 7284 | const char *z, /* Start of the argument list */ |
| 7285 | int n, /* Available bytes */ |
| 7286 | PToken *args |
| 7287 | ){ |
| 7288 | int nArg = 0; |
| 7289 | int i, sz; |
| 7290 | int iStart; |
| 7291 | int depth = 0; |
| 7292 | PToken x; |
| 7293 | if( z[0]!='(' ) return 0; |
| 7294 | args[0].z = z+1; |
| @@ -7315,10 +7316,22 @@ | |
| 7315 | depth--; |
| 7316 | } |
| 7317 | } |
| 7318 | if( z[i]==')' ){ |
| 7319 | args[nArg].n = i - iStart; |
| 7320 | return i+1; |
| 7321 | } |
| 7322 | x.z = z; |
| 7323 | x.n = 1; |
| 7324 | pik_error(p, &x, "unterminated macro argument list"); |
| @@ -7379,11 +7392,11 @@ | |
| 7379 | break; |
| 7380 | } |
| 7381 | pMac->inUse = 1; |
| 7382 | memset(args, 0, sizeof(args)); |
| 7383 | p->aCtx[p->nCtx++] = token; |
| 7384 | sz += pik_parse_macro_args(p, pIn->z+j, pIn->n-j, args); |
| 7385 | pik_tokenize(p, &pMac->macroBody, pParser, args); |
| 7386 | p->nCtx--; |
| 7387 | pMac->inUse = 0; |
| 7388 | }else{ |
| 7389 | #if 0 |
| @@ -7622,6 +7635,6 @@ | |
| 7622 | } |
| 7623 | return 0; |
| 7624 | } |
| 7625 | #endif /* PIKCHR_SHELL */ |
| 7626 | |
| 7627 | #line 7652 "pikchr.c" |
| 7628 |
| --- src/pikchr.c | |
| +++ src/pikchr.c | |
| @@ -7281,14 +7281,15 @@ | |
| 7281 | */ |
| 7282 | static unsigned int pik_parse_macro_args( |
| 7283 | Pik *p, |
| 7284 | const char *z, /* Start of the argument list */ |
| 7285 | int n, /* Available bytes */ |
| 7286 | PToken *args, /* Fill in with the arguments */ |
| 7287 | PToken *pOuter /* Arguments of the next outer context, or NULL */ |
| 7288 | ){ |
| 7289 | int nArg = 0; |
| 7290 | int i, j, sz; |
| 7291 | int iStart; |
| 7292 | int depth = 0; |
| 7293 | PToken x; |
| 7294 | if( z[0]!='(' ) return 0; |
| 7295 | args[0].z = z+1; |
| @@ -7315,10 +7316,22 @@ | |
| 7316 | depth--; |
| 7317 | } |
| 7318 | } |
| 7319 | if( z[i]==')' ){ |
| 7320 | args[nArg].n = i - iStart; |
| 7321 | /* Remove leading and trailing whitespace from each argument. |
| 7322 | ** If what remains is one of $1, $2, ... $9 then transfer the |
| 7323 | ** corresponding argument from the outer context */ |
| 7324 | for(j=0; j<=nArg; j++){ |
| 7325 | PToken *t = &args[j]; |
| 7326 | while( t->n>0 && isspace(t->z[0]) ){ t->n--; t->z++; } |
| 7327 | while( t->n>0 && isspace(t->z[t->n-1]) ){ t->n--; } |
| 7328 | if( t->n==2 && t->z[0]=='$' && t->z[1]>='1' && t->z[1]<='9' ){ |
| 7329 | if( pOuter ) *t = pOuter[t->z[1]-'1']; |
| 7330 | else t->n = 0; |
| 7331 | } |
| 7332 | } |
| 7333 | return i+1; |
| 7334 | } |
| 7335 | x.z = z; |
| 7336 | x.n = 1; |
| 7337 | pik_error(p, &x, "unterminated macro argument list"); |
| @@ -7379,11 +7392,11 @@ | |
| 7392 | break; |
| 7393 | } |
| 7394 | pMac->inUse = 1; |
| 7395 | memset(args, 0, sizeof(args)); |
| 7396 | p->aCtx[p->nCtx++] = token; |
| 7397 | sz += pik_parse_macro_args(p, pIn->z+j, pIn->n-j, args, aParam); |
| 7398 | pik_tokenize(p, &pMac->macroBody, pParser, args); |
| 7399 | p->nCtx--; |
| 7400 | pMac->inUse = 0; |
| 7401 | }else{ |
| 7402 | #if 0 |
| @@ -7622,6 +7635,6 @@ | |
| 7635 | } |
| 7636 | return 0; |
| 7637 | } |
| 7638 | #endif /* PIKCHR_SHELL */ |
| 7639 | |
| 7640 | #line 7665 "pikchr.c" |
| 7641 |