Subversion Repositories planix.SVN

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "sam.h"

#define MINSIZE 16              /* minimum number of chars allocated */
#define MAXSIZE 256             /* maximum number of chars for an empty string */


void
Strinit(String *p)
{
        p->s = emalloc(MINSIZE*RUNESIZE);
        p->n = 0;
        p->size = MINSIZE;
}

void
Strinit0(String *p)
{
        p->s = emalloc(MINSIZE*RUNESIZE);
        p->s[0] = 0;
        p->n = 1;
        p->size = MINSIZE;
}

void
Strclose(String *p)
{
        free(p->s);
}

void
Strzero(String *p)
{
        if(p->size > MAXSIZE){
                p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */
                p->size = MAXSIZE;
        }
        p->n = 0;
}

int
Strlen(Rune *r)
{
        Rune *s;

        for(s=r; *s; s++)
                ;
        return s-r;
}

void
Strdupl(String *p, Rune *s)     /* copies the null */
{
        p->n = Strlen(s)+1;
        Strinsure(p, p->n);
        memmove(p->s, s, p->n*RUNESIZE);
}

void
Strduplstr(String *p, String *q)        /* will copy the null if there's one there */
{
        Strinsure(p, q->n);
        p->n = q->n;
        memmove(p->s, q->s, q->n*RUNESIZE);
}

void
Straddc(String *p, int c)
{
        Strinsure(p, p->n+1);
        p->s[p->n++] = c;
}

void
Strinsure(String *p, ulong n)
{
        if(n > STRSIZE)
                error(Etoolong);
        if(p->size < n){        /* p needs to grow */
                n += 100;
                p->s = erealloc(p->s, n*RUNESIZE);
                p->size = n;
        }
}

void
Strinsert(String *p, String *q, Posn p0)
{
        Strinsure(p, p->n+q->n);
        memmove(p->s+p0+q->n, p->s+p0, (p->n-p0)*RUNESIZE);
        memmove(p->s+p0, q->s, q->n*RUNESIZE);
        p->n += q->n;
}

void
Strdelete(String *p, Posn p1, Posn p2)
{
        memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE);
        p->n -= p2-p1;
}

int
Strcmp(String *a, String *b)
{
        int i, c;

        for(i=0; i<a->n && i<b->n; i++)
                if(c = (a->s[i] - b->s[i]))     /* assign = */
                        return c;
        /* damn NULs confuse everything */
        i = a->n - b->n;
        if(i == 1){
                if(a->s[a->n-1] == 0)
                        return 0;
        }else if(i == -1){
                if(b->s[b->n-1] == 0)
                        return 0;
        }
        return i;
}

int
Strispre(String *a, String *b)
{
        int i;

        for(i=0; i<a->n && i<b->n; i++){
                if(a->s[i] - b->s[i]){  /* assign = */
                        if(a->s[i] == 0)
                                return 1;
                        return 0;
                }
        }
        return i == a->n;
}

char*
Strtoc(String *s)
{
        int i;
        char *c, *d;
        Rune *r;
        c = emalloc(s->n*UTFmax + 1);  /* worst case UTFmax bytes per rune, plus NUL */
        d = c;
        r = s->s;
        for(i=0; i<s->n; i++)
                d += runetochar(d, r++);
        if(d==c || d[-1]!=0)
                *d = 0;
        return c;

}

/*
 * Build very temporary String from Rune*
 */
String*
tmprstr(Rune *r, int n)
{
        static String p;

        p.s = r;
        p.n = n;
        p.size = n;
        return &p;
}

/*
 * Convert null-terminated char* into String
 */
String*
tmpcstr(char *s)
{
        String *p;
        Rune *r;
        int i, n;

        n = utflen(s);  /* don't include NUL */
        p = emalloc(sizeof(String));
        r = emalloc(n*RUNESIZE);
        p->s = r;
        for(i=0; i<n; i++,r++)
                s += chartorune(r, s);
        p->n = n;
        p->size = n;
        return p;
}

void
freetmpstr(String *s)
{
        free(s->s);
        free(s);
}