Annotation of researchv10no/cmd/cfront/libstring/string.c, revision 1.1.1.1

1.1       root        1: #include "String.h"
                      2: #include <ctype.h>
                      3: 
                      4: extern "C" {
                      5:        extern char     *memcpy(char *to, const char *from, int);
                      6: }
                      7: 
                      8: inline char*   // thanx to Jerry Schwarz
                      9: my_mcpy(char *to, const char *from, int n)
                     10: {
                     11:        if (n==1) {
                     12:                *to = *from;
                     13:                return to;
                     14:        } else return memcpy(to, from, n);
                     15: }
                     16: 
                     17: inline char*
                     18: my_Mcpy(char *to, const char *from, int n)
                     19: {
                     20:        if (n==1) {
                     21:                *to = *from;
                     22:                return to;
                     23:        } else return Memcpy(to, from, n);
                     24: }
                     25: 
                     26: String
                     27: String::operator+ (const String& oo) _const    /* catenate */
                     28: {
                     29:        register Rep    *sd = d;
                     30:        register Rep    *sood = oo.d;
                     31:        register        sdlen = sd->len;
                     32:        register        soodlen = sood->len;
                     33:        if (sdlen + soodlen > MAXSTRINGLENGTH)
                     34:                error( 1, "String.operator+: overflow" );
                     35:        if (sdlen == 0) return oo;
                     36:        else if (soodlen == 0) return *this;
                     37:        // try to make this a SubString of the result
                     38:        Rep     *temp;
                     39:        if ((temp = sd->canCat(soodlen)) == NULL) {
                     40:                temp = new Rep(sdlen + soodlen);
                     41:                my_mcpy(temp->start, sd->start, sdlen);
                     42:        }
                     43:        my_mcpy(temp->start+sdlen, sood->start, soodlen);
                     44:        return String(*temp);
                     45: }
                     46: 
                     47: String
                     48: String::operator+ (const char *p) _const       /* catenate */
                     49: {
                     50:        register Rep    *sd = d;
                     51:        register        sdlen = sd->len;
                     52:        register        len = strlen(p);
                     53:        if (sdlen + len > MAXSTRINGLENGTH)
                     54:                error(1, "String::operator+: overflow");
                     55:        if (sdlen == 0) return String(p);
                     56:        else if (len == 0) return *this;
                     57:        // try to make this a SubString of the result
                     58:        Rep     *temp;
                     59:        if ((temp = sd->canCat(len)) == NULL) {
                     60:                temp = new Rep(sdlen + len);
                     61:                my_mcpy(temp->start, sd->start, sdlen);
                     62:        }
                     63:        my_mcpy(temp->start+sdlen, p, len);
                     64:        return String(*temp);
                     65: }
                     66: 
                     67: String
                     68: String::operator+ (const char c) const /* catenate */
                     69: {
                     70:        register Rep    *sd = d;
                     71:        register        sdlen = sd->len;
                     72:        if (sdlen > MAXSTRINGLENGTH - 1)
                     73:                error( 1, "String.operator+: overflow" );
                     74:        if (sdlen == 0) return String(c);
                     75:        // try to make this a SubString of the result
                     76:        Rep     *temp;
                     77:        if ((temp = sd->canCat(1)) == NULL) {
                     78:                temp = new Rep(sdlen + 1);
                     79:                my_mcpy(temp->start, sd->start, sdlen);
                     80:        }
                     81:        temp->start[sdlen] = c;
                     82:        return String(*temp);
                     83: }
                     84: 
                     85: String
                     86: operator+ (const char *p, const String& s)     /* catenate */
                     87: {
                     88:        register Rep    *ssd = s.d;
                     89:        register        ssdlen = ssd->len;
                     90:        register        len = strlen(p);
                     91:        if (ssdlen + len > MAXSTRINGLENGTH)
                     92:                s.error( 1, "operator+(char*,String): overflow" );
                     93:        if (ssdlen == 0) return String(p);
                     94:        else if (len == 0) return s;
                     95:        Rep     *temp = new Rep(ssdlen + len);
                     96:        my_mcpy(temp->start, p, len);
                     97:        my_mcpy(temp->start+len, ssd->start, ssdlen);
                     98:        return String(*temp);
                     99: }
                    100: 
                    101: String
                    102: operator+ (const char c, const String& s)      /* catenate */
                    103: {
                    104:        register Rep    *ssd = s.d;
                    105:        register        ssdlen = ssd->len;
                    106:        if (ssdlen > MAXSTRINGLENGTH - 1)
                    107:                s.error( 1, "operator+(char,String): overflow" );
                    108:        if (ssdlen == 0) return String(c);
                    109:        Rep     *temp = new Rep(ssdlen + 1);
                    110:        my_mcpy(temp->start+1, ssd->start, ssdlen);
                    111:        temp->start[0] = c;
                    112:        return String(*temp);
                    113: }
                    114: 
                    115: Subchar&
                    116: String::operator[](const unsigned i)   /* character selection */
                    117: {
                    118:        if ( i >= length())
                    119:                error(1, "String.operator[]: out of bounds");
                    120:        return *new Subchar(*this,i);
                    121: }
                    122: 
                    123: SubString&
                    124: String::operator()(const unsigned offset, const unsigned len)  /* SubString */
                    125: {
                    126:        if ( offset > length() )
                    127:                error(1, "String.operator(): offset out of bounds");
                    128:        if ( len > MAXSUBSTRINGLENGTH || offset + len > d->len)
                    129:                error(1, "String.operator(): length out of bounds");
                    130:        return *new SubString(*this, offset, len);
                    131: }
                    132: 
                    133: Subchar::Subchar(const Subchar&)
                    134: {
                    135:        error(1, "Subchar.Subchar(Subchar&): shouldn't call this" );
                    136: }
                    137: 
                    138: SubString::SubString(const SubString&)
                    139: {
                    140:        error(1, "SubString.SubString(SubString&): shouldn't call this" );
                    141: }
                    142: 
                    143: String&
                    144: String::operator=(const String& oo)
                    145: {
                    146:        register Rep    *sd = d;
                    147:        register Rep    *sood = oo.d;
                    148:        if ( sd != sood ) {
                    149:                sd->refDecr();
                    150:                sd = d = sood;
                    151:                sd->refIncr();
                    152:        }
                    153:        return *this;
                    154: }
                    155: 
                    156: String&
                    157: String::operator=(const char *s)
                    158: {
                    159:        register Rep    *sd = d;
                    160:        sd->refDecr();
                    161:        d = new Rep(s);
                    162:        return *this;
                    163: }
                    164: 
                    165: String&
                    166: String::operator= (const char c)
                    167: {
                    168:        register Rep    *sd = d;
                    169:        sd->refDecr();
                    170:        d = &oneChar[c];
                    171:        return *this;
                    172: }
                    173: 
                    174: char
                    175: Subchar::operator=(const char cc)
                    176: {
                    177:        register Rep    *sd = ss->d;
                    178:        if (sd->len == 1) {     /* one character String */
                    179:                sd = &oneChar[cc];
                    180:        } else if (sd->refCount == 1 && !sd->is_constant()) {
                    181:                /* modify in place */
                    182:                sd->start[oo] = cc;
                    183:        } else {
                    184:                Rep     *rr = new Rep(*sd);
                    185:                /* copy middle */
                    186:                rr->start[oo] = cc;
                    187:                sd->refDecr();
                    188:                ss->d = rr;
                    189:        }
                    190:        /* delete this; it's used up */
                    191:        return cc;
                    192: }
                    193: 
                    194: void
                    195: SubString::operator=(const String& oss)
                    196: {
                    197:        register Rep    *sd = ss->d;
                    198:        register Rep    *osd = oss.d;
                    199:        int     itsOldLength = ss->length();
                    200:        int     newLength = itsOldLength + oss.length() - ll;
                    201:        if (newLength == 0) {
                    202:                sd->refDecr();
                    203:                sd = ss->d = nullRep;
                    204:        } else if (newLength == 1) {
                    205:                Rep     *rr;
                    206:                if (oss.length() == 1)
                    207:                        rr = osd;
                    208:                else if (oo == 1)       /* the head of this */
                    209:                        rr = &oneChar[*sd->start];
                    210:                else    /* the last character */
                    211:                        rr = &oneChar[*(sd->start+ss->length()-1)];
                    212:                sd->refDecr();
                    213:                ss->d = rr;
                    214:        } else if (sd->refCount == 1 && !sd->is_constant() &&
                    215:            (sd->extend(oss.length() - ll))) {
                    216:                /* modify in place */
                    217:                if (ll != oss.length())
                    218:                        /* copy tail */
                    219:                        my_Mcpy(sd->start + oo + oss.length(),
                    220:                            sd->start + oo + ll,
                    221:                            itsOldLength - (oo + ll));
                    222:                /* copy middle */
                    223:                my_mcpy(sd->start+oo, osd->start, oss.length());
                    224:        } else {
                    225:                Rep     *rr = new Rep(newLength);
                    226:                /* copy head */
                    227:                my_mcpy(rr->start, sd->start, oo);
                    228:                /* copy middle */
                    229:                my_mcpy(rr->start+oo, osd->start, oss.length());
                    230:                /* copy tail */
                    231:                my_mcpy(rr->start + oo + oss.length(),
                    232:                    sd->start + oo + ll,
                    233:                    ss->length() - (oo + ll));
                    234:                sd->refDecr();
                    235:                ss->d = rr;
                    236:        }
                    237:        /* delete this; it's used up */
                    238: }
                    239: 
                    240: bit
                    241: String::getX(char& c)  /*  or lop */
                    242: {
                    243:        register Rep    *sd = d;
                    244:        if ( length() < 1 )
                    245:                return FALSE;
                    246:        c = *sd->start;
                    247:        if ( length() == 1 )
                    248:                d = nullRep;
                    249:        else  if ( length() == 2 ) {
                    250:                d = &oneChar[(unsigned char)sd->start[1]];
                    251:                sd->refDecr();
                    252:        } else {
                    253:                Charfield       *myF = sd->myField();
                    254:                if (sd->refCount == 1 && !sd->is_constant()) {
                    255:                        sd->start++;
                    256:                        sd->len--;
                    257:                        myF->usedSpace -= 1;
                    258:                } else {
                    259:                        Rep     *rr = myF->getMt();
                    260:                        if (rr) {
                    261:                                sd->immutable();
                    262:                                rr->immutable();
                    263:                                rr->start = sd->start + 1;
                    264:                                myF->usedSpace += (rr->len = sd->len - 1);
                    265:                        } else
                    266:                                rr = new Rep (sd->start+1, sd->len - 1);
                    267:                        sd->refDecr();
                    268:                        d = rr;
                    269:                }
                    270:        }
                    271:        return TRUE;
                    272: }
                    273: 
                    274: bit
                    275: String::firstX(char &c) _const // don't change the String
                    276: {
                    277:        return  length() ? (c = *d->start, TRUE) : FALSE;
                    278: }
                    279: 
                    280: bit
                    281: String::lastX(char &c) _const  // don't change the String
                    282: {
                    283:        return  length() ? (c = d->start[length()-1], TRUE) : FALSE;
                    284: }
                    285: 
                    286: bit
                    287: String::unputX(char& c)                /* remove from back */
                    288: {
                    289:        register Rep    *sd = d;
                    290:        if (length() < 1)
                    291:                return FALSE;
                    292:        c = sd->start[length()-1];
                    293:        if (length() == 1)
                    294:                d = nullRep;
                    295:        else  if (length() == 2) {
                    296:                d = &oneChar[(unsigned char)*sd->start];
                    297:                sd->refDecr();
                    298:        } else {
                    299:                Charfield       *myF = sd->myField();
                    300:                if (!myF) abort();      // internal string error
                    301:                if (sd->refCount == 1 && !sd->is_constant()) {
                    302:                        sd->len--;
                    303:                        myF->usedSpace -= 1;
                    304:                } else {
                    305:                        Rep     *rr = myF->getMt();
                    306:                        if (rr) {
                    307:                                sd->immutable();
                    308:                                rr->immutable();
                    309:                                rr->start = sd->start;
                    310:                                myF->usedSpace += (rr->len = sd->len - 1);
                    311:                        } else
                    312:                                rr = new Rep (sd->start, sd->len - 1);
                    313:                        sd->refDecr();
                    314:                        d = rr;
                    315:                }
                    316:        }
                    317:        return TRUE;
                    318: }
                    319: 
                    320: String&
                    321: String::put(const char c)      /* append or put */
                    322: {
                    323:        register Rep    *sd = d;
                    324:        register        sdlen = sd->len;
                    325:        switch (sdlen) {
                    326:        case 0:
                    327:                d = &oneChar[(unsigned char) c];
                    328:                break;
                    329:        case 1:
                    330:                Rep     *rr = new Rep(2);
                    331:                *rr->start = *sd->start;
                    332:                rr->start[1] = c;
                    333:                d = rr;
                    334:                break;
                    335:        case MAXSTRINGLENGTH:
                    336:                error (1, "String::put: String overflow");
                    337:                break;
                    338:        default:
                    339:                if (sd->refCount == 1 && !sd->is_constant() && sd->extend(1))
                    340:                        sd->start[sdlen] = c;
                    341:                else {
                    342:                        Rep     *rr = sd->canCat(1);
                    343:                        if (rr)
                    344:                                rr->start[rr->len-1] = c;
                    345:                        else {
                    346:                                rr = new Rep (sdlen + 1);
                    347:                                my_mcpy(rr->start, sd->start, sdlen);
                    348:                                rr->start[sdlen] = c;
                    349:                        }
                    350:                        sd->refDecr();
                    351:                        d = rr;
                    352:                }
                    353:                break;
                    354:        }
                    355:        return *this;
                    356: }
                    357: 
                    358: String&
                    359: String::put(const char *p)     /* append */
                    360: {
                    361:        register Rep    *sd = d;
                    362:        register        sdlen = sd->len;
                    363:        register        soodlen = strlen(p);
                    364:        if (sdlen + soodlen > MAXSTRINGLENGTH)
                    365:                error(1, "String::put: overflow");
                    366:        if (sdlen == 0) return *this = p;
                    367:        if (soodlen == 0) return *this;
                    368:        if (sd->refCount == 1 && !sd->is_constant()) {
                    369:                char    *oldEnd = sd->start+sdlen;
                    370:                if (sd->extend(soodlen)) {
                    371:                        my_mcpy(oldEnd, p, soodlen);
                    372:                        return *this;
                    373:                }
                    374:        }
                    375:        Rep     *temp = new Rep(sdlen + soodlen);
                    376:        my_mcpy(temp->start, sd->start, sdlen);
                    377:        my_mcpy(temp->start+sdlen, p, soodlen);
                    378:        sd->refDecr();
                    379:        d = temp;
                    380:        return *this;
                    381: }
                    382: 
                    383: String&
                    384: String::put(const String& oo)  /* append */
                    385: {
                    386:        register Rep    *sd = d;
                    387:        register Rep    *sood = oo.d;
                    388:        register        sdlen = sd->len;
                    389:        register        soodlen = sood->len;
                    390:        if (sdlen + soodlen > MAXSTRINGLENGTH)
                    391:                error(1, "String::put: overflow");
                    392:        if (sdlen == 0) return *this = oo;
                    393:        if (soodlen == 0) return *this;
                    394:        if (sd->refCount == 1 && !sd->is_constant()) {
                    395:                char    *oldEnd = sd->start+sdlen;
                    396:                if (sd->extend(soodlen)) {
                    397:                        my_mcpy(oldEnd, sood->start, soodlen);
                    398:                        return *this;
                    399:                }
                    400:        }
                    401:        Rep     *temp = new Rep(sdlen + soodlen);
                    402:        my_mcpy(temp->start, sd->start, sdlen);
                    403:        my_mcpy(temp->start+sdlen, sood->start, soodlen);
                    404:        sd->refDecr();
                    405:        d = temp;
                    406:        return *this;
                    407: }
                    408: 
                    409: // unget(c) sticks c onto the front of the String
                    410: String&
                    411: String::unget (const char c)
                    412: {
                    413:        register Rep    *sd = d;
                    414:        register        sdlen = sd->len;
                    415:        switch (sdlen) {
                    416:        case 0:
                    417:                d = &oneChar[(unsigned char) c];
                    418:                break;
                    419:        case 1:
                    420:                Rep     *rr = new Rep (2);
                    421:                *rr->start = c;
                    422:                rr->start[1] = *sd->start;
                    423:                d = rr;
                    424:                break;
                    425:        case MAXSTRINGLENGTH:
                    426:                error(1, "String::unget: String overflow");
                    427:                break;
                    428:        default:
                    429:                if (sd->refCount == 1 && !sd->is_constant() && sd->extend(1)) {
                    430:                        my_Mcpy(sd->start+1, sd->start, sdlen);
                    431:                        *sd->start = c;
                    432:                } else {
                    433:                        Rep     *rr;
                    434:                        rr = new Rep (sdlen + 1);
                    435:                        my_mcpy (rr->start+1, sd->start, sdlen);
                    436:                        *rr->start = c;
                    437:                        sd->refDecr();
                    438:                        d = rr;
                    439:                }
                    440:        }
                    441:        return *this;
                    442: }
                    443: 
                    444: String&
                    445: String::unget (const String& oo)       /* prepend */
                    446: {
                    447:        register Rep    *sd = d;
                    448:        register Rep    *sood = oo.d;
                    449:        register        sdlen = sd->len;
                    450:        register        soodlen = sood->len;
                    451:        if (sdlen + soodlen > MAXSTRINGLENGTH)
                    452:                error(1, "String.operator-=: overflow");
                    453:        if (soodlen == 0) return *this;
                    454:        if (sdlen == 0) return *this = oo;
                    455:        if (sd->refCount == 1 && !sd->is_constant()) {
                    456:                if (sd->extend(soodlen)) {
                    457:                        my_Mcpy(sd->start+soodlen, sd->start, sdlen);
                    458:                        my_mcpy(sd->start, sood->start, soodlen);
                    459:                        return *this;
                    460:                }
                    461:        }
                    462:        Rep     *temp = new Rep(sdlen + soodlen);
                    463:        my_mcpy(temp->start, sood->start, soodlen);
                    464:        my_mcpy(temp->start+soodlen, sd->start, sdlen);
                    465:        sd->refDecr();
                    466:        d = temp;
                    467:        return *this;
                    468: }
                    469: 
                    470: istream&
                    471: operator>>(istream& ii, String& ss)
                    472: {
                    473:        ss = "";
                    474:        if (!(ii >> WS))
                    475:                return ii;
                    476:        char    c;
                    477:        while (ii.get(c)) {
                    478:                if (isspace(c)) {
                    479:                        ii.putback(c);
                    480:                        break;
                    481:                }
                    482:                ss.put(c);
                    483:        }
                    484:        return ii;
                    485: }
                    486: 
                    487: String
                    488: sgets(istream& ii)
                    489: {
                    490:        char    c;
                    491:        String  ans;
                    492:        while (ii.get(c) && c != '\n')
                    493:                ans.put(c);
                    494:        return ans;
                    495: }
                    496: 
                    497: void
                    498: String::dump(char *s) _const
                    499: {
                    500:        my_mcpy(s, d->start, d->len);
                    501:        s[d->len] = '\0';
                    502: }
                    503: 

unix.superglobalmegacorp.com

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