Annotation of researchv10dc/cmd/icon/src/iconx/fstranl.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * File: fstranl.c
                      3:  *  Contents: any, bal, find, many, match, move, pos, tab, upto
                      4:  */
                      5: 
                      6: #include "../h/rt.h"
                      7: 
                      8: /*
                      9:  * any(c,s,i,j) - test if first character of s[i:j] is in c.
                     10:  */
                     11: 
                     12: FncDcl(any,4)
                     13:    {
                     14:    register word i, j;
                     15:    long l1, l2;
                     16:    int *cs, csbuf[CsetSize];
                     17:    char sbuf[MaxCvtLen];
                     18: 
                     19:    /*
                     20:     * c must be a cset.  s defaults to &subject; i defaults to &pos if s
                     21:     *  defaulted, 1 otherwise.  j defaults to 0.
                     22:     */
                     23:    if (cvcset(&Arg1, &cs, csbuf) == NULL)
                     24:       runerr(104, &Arg1);
                     25:    if (defstr(&Arg2, sbuf, &k_subject))
                     26:       defint(&Arg3, &l1, k_pos);
                     27:    else
                     28:       defint(&Arg3, &l1, (word)1);
                     29:    defint(&Arg4, &l2, (word)0);
                     30: 
                     31:    /*
                     32:     * Convert i and j to positions in s. If i == j then the specified
                     33:     *  substring of s is empty and any fails. Otherwise make i the smaller of
                     34:     *  the two.  (j is of no further use.)
                     35:     */
                     36:    i = cvpos(l1, StrLen(Arg2));
                     37:    if (i == 0)
                     38:       Fail;
                     39:    j = cvpos(l2, StrLen(Arg2));
                     40:    if (j == 0)
                     41:       Fail;
                     42:    if (i == j)
                     43:       Fail;
                     44:    if (i > j)
                     45:       i = j;
                     46: 
                     47:    /*
                     48:     * If s[i] is not in the cset c, fail.
                     49:     */
                     50:    if (!Testb(StrLoc(Arg2)[i-1], cs))
                     51:       Fail;
                     52: 
                     53:    /*
                     54:     * Return pos(s[i+1]).
                     55:     */
                     56:    Arg0.dword = D_Integer;
                     57:    IntVal(Arg0) = i + 1;
                     58:    Return;
                     59:    }
                     60: 
                     61: 
                     62: /*
                     63:  * bal(c1,c2,c3,s,i,j) - find end of a balanced substring of s[i:j].
                     64:  *  Generates successive positions.
                     65:  */
                     66: 
                     67: FncDcl(bal,6)
                     68:    {
                     69:    register word i, j;
                     70:    register cnt, c;
                     71:    word t;
                     72:    long l1, l2;
                     73:    int *cs1, *cs2, *cs3;
                     74:    int csbuf1[CsetSize], csbuf2[CsetSize], csbuf3[CsetSize];
                     75:    char sbuf[MaxCvtLen];
                     76:    static int lpar[CsetSize] = /* '(' */
                     77:       cset_display(0, 0, 0400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
                     78:    static int rpar[CsetSize] = /* ')' */
                     79:       cset_display(0, 0, 01000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
                     80: 
                     81:    /*
                     82:     *  c1 defaults to &cset; c2 defaults to '(' (lpar); c3 defaults to
                     83:     *   ')' (rpar); s to &subject; i to &pos if s defaulted, 1 otherwise;
                     84:     *   j defaults to 0.
                     85:     */
                     86:    defcset(&Arg1, &cs1, csbuf1, k_cset.bits);
                     87:    defcset(&Arg2, &cs2, csbuf2, lpar);
                     88:    defcset(&Arg3, &cs3, csbuf3, rpar);
                     89:    if (defstr(&Arg4, sbuf, &k_subject))
                     90:       defint(&Arg5, &l1, k_pos);
                     91:    else
                     92:       defint(&Arg5, &l1, (word)1);
                     93:    defint(&Arg6, &l2, (word)0);
                     94: 
                     95:    /*
                     96:     * Convert i and j to positions in s and order them.
                     97:     */
                     98:    i = cvpos(l1, StrLen(Arg4));
                     99:    if (i == 0)
                    100:       Fail;
                    101:    j = cvpos(l2, StrLen(Arg4));
                    102:    if (j == 0)
                    103:       Fail;
                    104:    if (i > j) {
                    105:       t = i;
                    106:       i = j;
                    107:       j = t;
                    108:       }
                    109: 
                    110:    /*
                    111:     * Loop through characters in s[i:j].  When a character in cs2 is
                    112:     *  found, increment cnt; when a chracter in cs3 is found, decrement
                    113:     *  cnt.  When cnt is 0 there have been an equal number of occurrences
                    114:     *  of characters in cs2 and cs3, i.e., the string to the left of
                    115:     *  i is balanced.  If the string is balanced and the current character
                    116:     *  (s[i]) is in c1, suspend i.  Note that if cnt drops below zero,
                    117:     *  bal fails.
                    118:     */
                    119:    cnt = 0;
                    120:    Arg0.dword = D_Integer;
                    121:    while (i < j) {
                    122:       c = StrLoc(Arg4)[i-1];
                    123:       if (cnt == 0 && Testb(c, cs1)) {
                    124:          IntVal(Arg0) = i;
                    125:          Suspend;
                    126:          }
                    127:       if (Testb(c, cs2))
                    128:          cnt++;
                    129:       else if (Testb(c, cs3))
                    130:          cnt--;
                    131:       if (cnt < 0)
                    132:          Fail;
                    133:       i++;
                    134:       }
                    135:    /*
                    136:     * Eventually fail.
                    137:     */
                    138:    Fail;
                    139:    }
                    140: 
                    141: 
                    142: /*
                    143:  * find(s1,s2,i,j) - find string s1 in s2[i:j] and return position in
                    144:  *  s2 of beginning of s1.
                    145:  * Generates successive positions.
                    146:  */
                    147: 
                    148: /* >find */
                    149: FncDcl(find,4)
                    150:    {
                    151:    register word l;
                    152:    register char *s1, *s2;
                    153:    word i, j, t;
                    154:    long l1, l2;
                    155:    char sbuf1[MaxCvtLen], sbuf2[MaxCvtLen];
                    156: 
                    157:    /*
                    158:     * Arg1 must be a string.  Arg2 defaults to &subject; Arg3 defaults
                    159:     *  to &pos if Arg2 is defaulted, or to 1 otherwise; Arg4 defaults
                    160:     *  to 0.
                    161: 
                    162:     */
                    163:    if (cvstr(&Arg1, sbuf1) == NULL)
                    164:       runerr(103, &Arg1);
                    165:    if (defstr(&Arg2, sbuf2, &k_subject))
                    166:       defint(&Arg3, &l1, k_pos);
                    167:    else
                    168:       defint(&Arg3, &l1, (word)1);
                    169:    defint(&Arg4, &l2, (word)0);
                    170: 
                    171:    /*
                    172:     * Convert i and j to absolute positions in s2 and order them
                    173:     * so that i <= j.
                    174:     */
                    175:    i = cvpos(l1, StrLen(Arg2));
                    176:    if (i == 0)
                    177:       Fail;
                    178:    j = cvpos(l2, StrLen(Arg2));
                    179:    if (j == 0)
                    180:       Fail;
                    181:    if (i > j) {
                    182:       t = i;
                    183:       i = j;
                    184:       j = t;
                    185:       }
                    186: 
                    187:    /*
                    188:     * Loop through s2[i:j] trying to find s1 at each point, stopping
                    189:     *  when the remaining portion s2[i:j] is too short to contain s1.
                    190:     */
                    191:    Arg0.dword = D_Integer;
                    192:    while (i <= j - StrLen(Arg1)) {
                    193:       s1 = StrLoc(Arg1);
                    194:       s2 = StrLoc(Arg2) + i - 1;
                    195:       l = StrLen(Arg1);
                    196: 
                    197:       /*
                    198:        * Compare strings on a byte-wise basis; if end is reached
                    199:        *  before inequality is found, suspend the position of the string.
                    200:        */
                    201:       do {
                    202:          if (l-- <= 0) {
                    203:             IntVal(Arg0) = i;
                    204:             Suspend;
                    205:             break;
                    206:             }
                    207:          } while (*s1++ == *s2++);
                    208:       i++;
                    209:       }
                    210: 
                    211:    Fail;
                    212:    }
                    213: /* <find */
                    214: 
                    215: /*
                    216:  * many(c,s,i,j) - find longest prefix of s[i:j] of characters in c.
                    217:  */
                    218: 
                    219: FncDcl(many,4)
                    220:    {
                    221:    register word i, j, t;
                    222:    int *cs, csbuf[CsetSize];
                    223:    long l1, l2;
                    224:    char sbuf[MaxCvtLen];
                    225: 
                    226:    /*
                    227:     * c must be a cset.  s defaults to &subject;  i defaults to &pos if s
                    228:     *  defaulted, 1 otherwise;  j defaults to 0.
                    229:     */
                    230:    if (cvcset(&Arg1, &cs, csbuf) == NULL)
                    231:       runerr(104, &Arg1);
                    232:    if (defstr(&Arg2, sbuf, &k_subject))
                    233:       defint(&Arg3, &l1, k_pos);
                    234:    else
                    235:       defint(&Arg3, &l1, (word)1);
                    236:    defint(&Arg4, &l2, (word)0);
                    237: 
                    238:    /*
                    239:     * Convert i and j to absolute positions and order them.  If i == j,
                    240:     *  then the specified substring of s is the empty string and many
                    241:     *  fails.
                    242:     */
                    243:    i = cvpos(l1, StrLen(Arg2));
                    244:    if (i == 0)
                    245:       Fail;
                    246:    j = cvpos(l2, StrLen(Arg2));
                    247:    if (j == 0)
                    248:       Fail;
                    249:    if (i == j)
                    250:       Fail;
                    251:    if (i > j) {
                    252:       t = i;
                    253:       i = j;
                    254:       j = t;
                    255:       }
                    256: 
                    257:    /*
                    258:     * Fail if first character of s[i:j] isn't in c.
                    259:     */
                    260:    if (!Testb(StrLoc(Arg2)[i-1], cs))
                    261:       Fail;
                    262: 
                    263:    /*
                    264:     * Move i along s[i:j] until a character that is not in c is found or
                    265:     *  the end of the string is reached.
                    266:     */
                    267:    i++;
                    268:    while (i < j && Testb(StrLoc(Arg2)[i-1], cs))
                    269:       i++;
                    270: 
                    271:    /*
                    272:     * Return the position of the first character not in c.
                    273:     */
                    274:    Arg0.dword = D_Integer;
                    275:    IntVal(Arg0) = i;
                    276:    Return;
                    277:    }
                    278: 
                    279: 
                    280: /*
                    281:  * match(s1,s2,i,j) - test if s1 is prefix of s2[i:j].
                    282:  */
                    283: FncDcl(match,4)
                    284:    {
                    285:    register word i;
                    286:    register char *s1, *s2;
                    287:    word j, t;
                    288:    long l1, l2;
                    289:    char sbuf1[MaxCvtLen], sbuf2[MaxCvtLen];
                    290: 
                    291:    /*
                    292:     * s1 must be a string.  s2 defaults to &subject;  i defaults to &pos
                    293:     *  if s defaulted, 1 otherwise; j defaults to 0.
                    294:     */
                    295:    if (cvstr(&Arg1, sbuf1) == NULL)
                    296:       runerr(103, &Arg1);
                    297:    if (defstr(&Arg2, sbuf2, &k_subject))
                    298:       defint(&Arg3, &l1, k_pos);
                    299:    else
                    300:       defint(&Arg3, &l1, (word)1);
                    301:    defint(&Arg4, &l2, (word)0);
                    302: 
                    303:    /*
                    304:     * Convert i and j to absolute positions and then make i the smaller
                    305:     *  of the two positions and make j the length of the substring.
                    306:     */
                    307:    i = cvpos(l1, StrLen(Arg2));
                    308:    if (i == 0)
                    309:       Fail;
                    310:    j = cvpos(l2, StrLen(Arg2));
                    311:    if (j == 0)
                    312:       Fail;
                    313:    if (i > j) {
                    314:       t = i;
                    315:       i = j;
                    316:       j = t - j;
                    317:       }
                    318:    else
                    319:       j = j - i;
                    320: 
                    321:    /*
                    322:     * Can't match unless s1 is as long as s2[i:j].
                    323:     */
                    324:    if (j < StrLen(Arg1))
                    325:       Fail;
                    326: 
                    327:    /*
                    328:     * Compare s1 with s2[i:j] for *s1 characters; fail if an inequality
                    329:     *  if found.
                    330:     */
                    331:    s1 = StrLoc(Arg1);
                    332:    s2 = StrLoc(Arg2) + i - 1;
                    333:    for (j = StrLen(Arg1); j > 0; j--)
                    334:       if (*s1++ != *s2++)
                    335:          Fail;
                    336: 
                    337:    /*
                    338:     * Return position of end of matched string in s2.
                    339:     */
                    340:    Arg0.dword = D_Integer;
                    341:    IntVal(Arg0) = i + StrLen(Arg1);
                    342:    Return;
                    343:    }
                    344: 
                    345: 
                    346: /*
                    347:  * move(i) - move &pos by i, return substring of &subject spanned.
                    348:  *  Reverses effects if resumed.
                    349:  */
                    350: FncDcl(move,1)
                    351:    {
                    352:    register word i, j;
                    353:    long l;
                    354:    word oldpos;
                    355: 
                    356:    /*
                    357:     * i must be a (non-long) integer.
                    358:     */
                    359:    switch (cvint(&Arg1, &l)) {
                    360: 
                    361:       case T_Integer:
                    362:          j = (word)l;
                    363:          break;
                    364: 
                    365:       case T_Longint:
                    366:          Fail;
                    367: 
                    368:       default:
                    369:          runerr(101, &Arg1);
                    370:       }
                    371: 
                    372:    /*
                    373:     * Save old &pos.  Local variable i holds &pos before the move.
                    374:     */
                    375:    oldpos = i = k_pos;
                    376: 
                    377:    /*
                    378:     * If attempted move is past either end of the string, fail.
                    379:     */
                    380:    if (i + j <= 0 || i + j > StrLen(k_subject) + 1)
                    381:       Fail;
                    382: 
                    383:    /*
                    384:     * Set new &pos.
                    385:     */
                    386:    k_pos += j;
                    387: 
                    388:    /*
                    389:     * Make sure j >= 0.
                    390:     */
                    391:    if (j < 0) {
                    392:       i += j;
                    393:       j = -j;
                    394:       }
                    395: 
                    396:    /*
                    397:     * Suspend substring of &subject that was moved over.
                    398:     */
                    399:    StrLen(Arg0) = j;
                    400:    StrLoc(Arg0) = StrLoc(k_subject) + i - 1;
                    401:    Suspend;
                    402: 
                    403:    /*
                    404:     * If move is resumed, restore the old position and fail.
                    405:     */
                    406:    k_pos = oldpos;
                    407:    if (k_pos > StrLen(k_subject) + 1)
                    408:       runerr(205, &tvky_pos.kyval);
                    409:    Fail;
                    410:    }
                    411: 
                    412: 
                    413: /*
                    414:  * pos(i) - test if &pos is at position i in &subject.
                    415:  */
                    416: FncDcl(pos,1)
                    417:    {
                    418:    register word i;
                    419:    long l;
                    420: 
                    421:    /*
                    422:     * i must be an integer.
                    423:     */
                    424:    if (cvint(&Arg1, &l) == NULL)
                    425:       runerr(101, &Arg1);
                    426: 
                    427:    /*
                    428:     * Fail if &pos isn't equivalent to i, return i otherwise.
                    429:     */
                    430:    if ((i = cvpos(l, StrLen(k_subject))) != k_pos)
                    431:       Fail;
                    432:    Arg0.dword = D_Integer;
                    433:    IntVal(Arg0) = i;
                    434:    Return;
                    435:    }
                    436: 
                    437: 
                    438: /*
                    439:  * tab(i) - set &pos to i, return substring of &subject spanned.
                    440:  *  Reverses effects if resumed..
                    441:  */
                    442: 
                    443: /* >tab */
                    444: FncDcl(tab,1)
                    445:    {
                    446:    register word i, j;
                    447:    word t, oldpos;
                    448:    long l1;
                    449: 
                    450:    /*
                    451:     * Arg1 must be an integer.
                    452:     */
                    453:    if (cvint(&Arg1, &l1) == NULL)
                    454:       runerr(101, &Arg1);
                    455: /* <tab */
                    456: 
                    457:    /*
                    458:     * Convert j to an absolute position.
                    459:     */
                    460:    j = cvpos(l1, StrLen(k_subject));
                    461:    if (j == 0)
                    462:       Fail;
                    463: 
                    464:    /*
                    465:     * Save old &pos.  Local variable i holds &pos before the tab.
                    466:     */
                    467:    oldpos = i = k_pos;
                    468: 
                    469:    /*
                    470:     * Set new &pos.
                    471:     */
                    472:    k_pos = j;
                    473: 
                    474:    /*
                    475:     *  Make j the length of the substring &subject[i:j]
                    476:     */
                    477:    if (i > j) {
                    478:       t = i;
                    479:       i = j;
                    480:       j = t - j;
                    481:       }
                    482:    else
                    483:       j = j - i;
                    484: 
                    485:    /*
                    486:     * Suspend the portion of &subject that was tabbed over.
                    487:     */
                    488:    StrLoc(Arg0) = StrLoc(k_subject) + i - 1;
                    489:    StrLen(Arg0) = j;
                    490:    Suspend;
                    491: 
                    492:    /*
                    493:     * If tab is resumed, restore the old position and fail.
                    494:     */
                    495:    k_pos = oldpos;
                    496:    if (k_pos > StrLen(k_subject) + 1)
                    497:       runerr(205, &tvky_pos.kyval);
                    498:    Fail;
                    499:    }
                    500: 
                    501: 
                    502: /*
                    503:  * upto(c,s,i,j) - find each occurrence in s[i:j] of a character in c.
                    504:  * Generates successive positions.
                    505:  */
                    506: 
                    507: FncDcl(upto,4)
                    508:    {
                    509:    register word i, j;
                    510:    word t;
                    511:    long l1, l2;
                    512:    int *cs, csbuf[CsetSize];
                    513:    char sbuf[MaxCvtLen];
                    514: 
                    515:    /*
                    516:     * c must be a cset.  s defaults to &subject; i defaults to &pos if
                    517:     *  s defaulted, 1 otherwise; j defaults to 0.
                    518:     */
                    519:    if (cvcset(&Arg1, &cs, csbuf) == NULL)
                    520:       runerr(104, &Arg1);
                    521:    if (defstr(&Arg2, sbuf, &k_subject))
                    522:       defint(&Arg3, &l1, k_pos);
                    523:    else
                    524:       defint(&Arg3, &l1, (word)1);
                    525:    defint(&Arg4, &l2, (word)0);
                    526: 
                    527:    /*
                    528:     * Convert i and j to positions in s and order them.
                    529:     */
                    530:    i = cvpos(l1, StrLen(Arg2));
                    531:    if (i == 0)
                    532:       Fail;
                    533:    j = cvpos(l2, StrLen(Arg2));
                    534:    if (j == 0)
                    535:       Fail;
                    536:    if (i > j) {
                    537:       t = i;
                    538:       i = j;
                    539:       j = t;
                    540:       }
                    541: 
                    542:    /*
                    543:     * Look through s[i:j] and suspend position of each occurrence of
                    544:     *  of a character in c.
                    545:     */
                    546:    while (i < j) {
                    547:       if (Testb(StrLoc(Arg2)[i-1], cs)) {
                    548:          Arg0.dword = D_Integer;
                    549:          IntVal(Arg0) = i;
                    550:          Suspend;
                    551:          }
                    552:       i++;
                    553:       }
                    554:    /*
                    555:     * Eventually fail.
                    556:     */
                    557:    Fail;
                    558:    }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.