#include "sam.h" #define MINSIZE 16 /* minimum number of chars allocated */#define MAXSIZE 256 /* maximum number of chars for an empty string */ voidStrinit(String *p){ p->s = emalloc(MINSIZE*RUNESIZE); p->n = 0; p->size = MINSIZE;} voidStrinit0(String *p){ p->s = emalloc(MINSIZE*RUNESIZE); p->s[0] = 0; p->n = 1; p->size = MINSIZE;} voidStrclose(String *p){ free(p->s);} voidStrzero(String *p){ if(p->size > MAXSIZE){ p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */ p->size = MAXSIZE; } p->n = 0;} intStrlen(Rune *r){ Rune *s; for(s=r; *s; s++) ; return s-r;} voidStrdupl(String *p, Rune *s) /* copies the null */{ p->n = Strlen(s)+1; Strinsure(p, p->n); memmove(p->s, s, p->n*RUNESIZE);} voidStrduplstr(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);} voidStraddc(String *p, int c){ Strinsure(p, p->n+1); p->s[p->n++] = c;} voidStrinsure(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; }} voidStrinsert(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;} voidStrdelete(String *p, Posn p1, Posn p2){ memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE); p->n -= p2-p1;} intStrcmp(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;} 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;} voidfreetmpstr(String *s){ free(s->s); free(s);}
#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;
}
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);
}