Annotation of researchv10no/cmd/cfront/libstring/string.c, revision 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.