string.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
string.c (2766B) | |
--- | |
1 #include "sam.h" | |
2 | |
3 #define MINSIZE 16 /* minimum number of cha… | |
4 #define MAXSIZE 256 /* maximum number of ch… | |
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 t… | |
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… | |
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 ru… | |
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 } |