string.c 2.7 KB

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