string.c 3.1 KB

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