string.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3. Written by James Clark (jjc@jclark.com) */
  4. #include <stdio.h>
  5. #include "stringclass.h"
  6. #include "lib.h"
  7. #define INT_DIGITS 10
  8. static char *salloc(int len, int *sizep);
  9. static void sfree(char *ptr, int size);
  10. static char *sfree_alloc(char *ptr, int size, int len, int *sizep);
  11. static char *srealloc(char *ptr, int size, int oldlen, int newlen, int *sizep);
  12. static char *
  13. salloc(int len, int *sizep)
  14. {
  15. if (len == 0)
  16. {
  17. *sizep = 0;
  18. return 0;
  19. }
  20. else
  21. return new char[*sizep = len*2];
  22. }
  23. static void
  24. sfree(char *ptr, int)
  25. {
  26. a_delete ptr;
  27. }
  28. static char *
  29. sfree_alloc(char *ptr, int oldsz, int len, int *sizep)
  30. {
  31. if (oldsz >= len)
  32. {
  33. *sizep = oldsz;
  34. return ptr;
  35. }
  36. a_delete ptr;
  37. if (len == 0)
  38. {
  39. *sizep = 0;
  40. return 0;
  41. }
  42. else
  43. return new char[*sizep = len*2];
  44. }
  45. static char *
  46. srealloc(char *ptr, int oldsz, int oldlen, int newlen, int *sizep)
  47. {
  48. if (oldsz >= newlen)
  49. {
  50. *sizep = oldsz;
  51. return ptr;
  52. }
  53. if (newlen == 0)
  54. {
  55. a_delete ptr;
  56. *sizep = 0;
  57. return 0;
  58. }
  59. else
  60. {
  61. char *p = new char[*sizep = newlen*2];
  62. if (oldlen < newlen && oldlen != 0)
  63. memcpy(p, ptr, oldlen);
  64. a_delete ptr;
  65. return p;
  66. }
  67. }
  68. string::string() : ptr(0), len(0), sz(0)
  69. {
  70. }
  71. string::string(const char *p, int n) : len(n)
  72. {
  73. assert(n >= 0);
  74. ptr = salloc(n, &sz);
  75. if (n != 0)
  76. memcpy(ptr, p, n);
  77. }
  78. string::string(const char *p)
  79. {
  80. if (p == 0)
  81. {
  82. len = 0;
  83. ptr = 0;
  84. sz = 0;
  85. }
  86. else
  87. {
  88. len = strlen(p);
  89. ptr = salloc(len, &sz);
  90. memcpy(ptr, p, len);
  91. }
  92. }
  93. string::string(char c) : len(1)
  94. {
  95. ptr = salloc(1, &sz);
  96. *ptr = c;
  97. }
  98. string::string(const string &s) : len(s.len)
  99. {
  100. ptr = salloc(len, &sz);
  101. if (len != 0)
  102. memcpy(ptr, s.ptr, len);
  103. }
  104. string::~string()
  105. {
  106. sfree(ptr, sz);
  107. }
  108. string &
  109. string::operator=(const string &s)
  110. {
  111. ptr = sfree_alloc(ptr, sz, s.len, &sz);
  112. len = s.len;
  113. if (len != 0)
  114. memcpy(ptr, s.ptr, len);
  115. return *this;
  116. }
  117. string &
  118. string::operator=(const char *p)
  119. {
  120. if (p == 0)
  121. {
  122. sfree(ptr, len);
  123. len = 0;
  124. ptr = 0;
  125. sz = 0;
  126. }
  127. else
  128. {
  129. int slen = strlen(p);
  130. ptr = sfree_alloc(ptr, sz, slen, &sz);
  131. len = slen;
  132. memcpy(ptr, p, len);
  133. }
  134. return *this;
  135. }
  136. string &
  137. string::operator=(char c)
  138. {
  139. ptr = sfree_alloc(ptr, sz, 1, &sz);
  140. len = 1;
  141. *ptr = c;
  142. return *this;
  143. }
  144. void
  145. string::move(string &s)
  146. {
  147. sfree(ptr, sz);
  148. ptr = s.ptr;
  149. len = s.len;
  150. sz = s.sz;
  151. s.ptr = 0;
  152. s.len = 0;
  153. s.sz = 0;
  154. }
  155. void
  156. string::grow1()
  157. {
  158. ptr = srealloc(ptr, sz, len, len + 1, &sz);
  159. }
  160. string &
  161. string::operator+=(const char *p)
  162. {
  163. if (p != 0)
  164. {
  165. int n = strlen(p);
  166. int newlen = len + n;
  167. if (newlen > sz)
  168. ptr = srealloc(ptr, sz, len, newlen, &sz);
  169. memcpy(ptr + len, p, n);
  170. len = newlen;
  171. }
  172. return *this;
  173. }
  174. string &
  175. string::operator+=(const string &s)
  176. {
  177. if (s.len != 0) {
  178. int newlen = len + s.len;
  179. if (newlen > sz)
  180. ptr = srealloc(ptr, sz, len, newlen, &sz);
  181. memcpy(ptr + len, s.ptr, s.len);
  182. len = newlen;
  183. }
  184. return *this;
  185. }
  186. void
  187. string::append(const char *p, int n)
  188. {
  189. if (n > 0) {
  190. int newlen = len + n;
  191. if (newlen > sz)
  192. ptr = srealloc(ptr, sz, len, newlen, &sz);
  193. memcpy(ptr + len, p, n);
  194. len = newlen;
  195. }
  196. }
  197. string::string(const char *s1, int n1, const char *s2, int n2)
  198. {
  199. assert(n1 >= 0 && n2 >= 0);
  200. len = n1 + n2;
  201. if (len == 0)
  202. {
  203. sz = 0;
  204. ptr = 0;
  205. }
  206. else
  207. {
  208. ptr = salloc(len, &sz);
  209. if (n1 == 0)
  210. memcpy(ptr, s2, n2);
  211. else {
  212. memcpy(ptr, s1, n1);
  213. if (n2 != 0)
  214. memcpy(ptr + n1, s2, n2);
  215. }
  216. }
  217. }
  218. int
  219. operator<=(const string &s1, const string &s2)
  220. {
  221. return (s1.len <= s2.len
  222. ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
  223. : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
  224. }
  225. int
  226. operator<(const string &s1, const string &s2)
  227. {
  228. return (s1.len < s2.len
  229. ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
  230. : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
  231. }
  232. int
  233. operator>=(const string &s1, const string &s2)
  234. {
  235. return (s1.len >= s2.len
  236. ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
  237. : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
  238. }
  239. int
  240. operator>(const string &s1, const string &s2)
  241. {
  242. return (s1.len > s2.len
  243. ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
  244. : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
  245. }
  246. void
  247. string::set_length(int i)
  248. {
  249. assert(i >= 0);
  250. if (i > sz)
  251. ptr = srealloc(ptr, sz, len, i, &sz);
  252. len = i;
  253. }
  254. void
  255. string::clear()
  256. {
  257. len = 0;
  258. }
  259. int
  260. string::search(char c) const
  261. {
  262. char *p = (char *)memchr(ptr, c, len);
  263. return p ? p - ptr : -1;
  264. }
  265. // we silently strip nuls
  266. char *
  267. string::extract() const
  268. {
  269. char *p = ptr;
  270. int n = len;
  271. int nnuls = 0;
  272. int i;
  273. for (i = 0; i < n; i++)
  274. if (p[i] == '\0')
  275. nnuls++;
  276. char *q = new char[n + 1 - nnuls];
  277. char *r = q;
  278. for (i = 0; i < n; i++)
  279. if (p[i] != '\0')
  280. *r++ = p[i];
  281. q[n] = '\0';
  282. return q;
  283. }
  284. void
  285. put_string(const string &s, FILE *fp)
  286. {
  287. int len = s.length();
  288. const char *ptr = s.contents();
  289. for (int i = 0; i < len; i++)
  290. putc(ptr[i], fp);
  291. }
  292. string
  293. as_string(int i)
  294. {
  295. static char buf[INT_DIGITS + 2];
  296. sprintf(buf, "%d", i);
  297. return string(buf);
  298. }