string.c (2766B)
1 #include "sam.h" 2 3 #define MINSIZE 16 /* minimum number of chars allocated */ 4 #define MAXSIZE 256 /* maximum number of chars for an empty string */ 5 6 7 void 8 Strinit(String *p) 9 { 10 p->s = emalloc(MINSIZE*RUNESIZE); 11 p->n = 0; 12 p->size = MINSIZE; 13 } 14 15 void 16 Strinit0(String *p) 17 { 18 p->s = emalloc(MINSIZE*RUNESIZE); 19 p->s[0] = 0; 20 p->n = 1; 21 p->size = MINSIZE; 22 } 23 24 void 25 Strclose(String *p) 26 { 27 free(p->s); 28 } 29 30 void 31 Strzero(String *p) 32 { 33 if(p->size > MAXSIZE){ 34 p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */ 35 p->size = MAXSIZE; 36 } 37 p->n = 0; 38 } 39 40 int 41 Strlen(Rune *r) 42 { 43 Rune *s; 44 45 for(s=r; *s; s++) 46 ; 47 return s-r; 48 } 49 50 void 51 Strdupl(String *p, Rune *s) /* copies the null */ 52 { 53 p->n = Strlen(s)+1; 54 Strinsure(p, p->n); 55 memmove(p->s, s, p->n*RUNESIZE); 56 } 57 58 void 59 Strduplstr(String *p, String *q) /* will copy the null if there's one there */ 60 { 61 Strinsure(p, q->n); 62 p->n = q->n; 63 memmove(p->s, q->s, q->n*RUNESIZE); 64 } 65 66 void 67 Straddc(String *p, int c) 68 { 69 Strinsure(p, p->n+1); 70 p->s[p->n++] = c; 71 } 72 73 void 74 Strinsure(String *p, ulong n) 75 { 76 if(n > STRSIZE) 77 error(Etoolong); 78 if(p->size < n){ /* p needs to grow */ 79 n += 100; 80 p->s = erealloc(p->s, n*RUNESIZE); 81 p->size = n; 82 } 83 } 84 85 void 86 Strinsert(String *p, String *q, Posn p0) 87 { 88 Strinsure(p, p->n+q->n); 89 memmove(p->s+p0+q->n, p->s+p0, (p->n-p0)*RUNESIZE); 90 memmove(p->s+p0, q->s, q->n*RUNESIZE); 91 p->n += q->n; 92 } 93 94 void 95 Strdelete(String *p, Posn p1, Posn p2) 96 { 97 memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE); 98 p->n -= p2-p1; 99 } 100 101 int 102 Strcmp(String *a, String *b) 103 { 104 int i, c; 105 106 for(i=0; i<a->n && i<b->n; i++) 107 if(c = (a->s[i] - b->s[i])) /* assign = */ 108 return c; 109 /* damn NULs confuse everything */ 110 i = a->n - b->n; 111 if(i == 1){ 112 if(a->s[a->n-1] == 0) 113 return 0; 114 }else if(i == -1){ 115 if(b->s[b->n-1] == 0) 116 return 0; 117 } 118 return i; 119 } 120 121 int 122 Strispre(String *a, String *b) 123 { 124 int i; 125 126 for(i=0; i<a->n && i<b->n; i++){ 127 if(a->s[i] - b->s[i]){ /* assign = */ 128 if(a->s[i] == 0) 129 return 1; 130 return 0; 131 } 132 } 133 return i == a->n; 134 } 135 136 char* 137 Strtoc(String *s) 138 { 139 int i; 140 char *c, *d; 141 Rune *r; 142 c = emalloc(s->n*UTFmax + 1); /* worst case UTFmax bytes per rune, plus NUL */ 143 d = c; 144 r = s->s; 145 for(i=0; i<s->n; i++) 146 d += runetochar(d, r++); 147 if(d==c || d[-1]!=0) 148 *d = 0; 149 return c; 150 151 } 152 153 /* 154 * Build very temporary String from Rune* 155 */ 156 String* 157 tmprstr(Rune *r, int n) 158 { 159 static String p; 160 161 p.s = r; 162 p.n = n; 163 p.size = n; 164 return &p; 165 } 166 167 /* 168 * Convert null-terminated char* into String 169 */ 170 String* 171 tmpcstr(char *s) 172 { 173 String *p; 174 Rune *r; 175 int i, n; 176 177 n = utflen(s); /* don't include NUL */ 178 p = emalloc(sizeof(String)); 179 r = emalloc(n*RUNESIZE); 180 p->s = r; 181 for(i=0; i<n; i++,r++) 182 s += chartorune(r, s); 183 p->n = n; 184 p->size = n; 185 return p; 186 } 187 188 void 189 freetmpstr(String *s) 190 { 191 free(s->s); 192 free(s); 193 }