Annotation of researchv10dc/cmd/icon/src/iconx/fstranl.c, revision 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.