text.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:10k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/text.doc,v 1.10 1996/06/26 23:02:01 drh Exp $";
  2. #include <string.h>
  3. #include <limits.h>
  4. #include "assert.h"
  5. #include "fmt.h"
  6. #include "text.h"
  7. #include "mem.h"
  8. #define T Text_T
  9. #define idx(i, len) ((i) <= 0 ? (i) + (len) : (i) - 1)
  10. #define isatend(s, n) ((s).str+(s).len == current->avail
  11. && current->avail + (n) <= current->limit)
  12. #define equal(s, i, t) 
  13. (memcmp(&(s).str[i], (t).str, (t).len) == 0)
  14. struct Text_save_T {
  15. struct chunk *current;
  16. char *avail;
  17. };
  18. static char cset[] =
  19. "00010203040506071011121314151617"
  20. "20212223242526273031323334353637"
  21. "40414243444546475051525354555657"
  22. "60616263646566677071727374757677"
  23. "100101102103104105106107110111112113114115116117"
  24. "120121122123124125126127130131132133134135136137"
  25. "140141142143144145146147150151152153154155156157"
  26. "160161162163164165166167170171172173174175176177"
  27. "200201202203204205206207210211212213214215216217"
  28. "220221222223224225226227230231232233234235236237"
  29. "240241242243244245246247250251252253254255256257"
  30. "260261262263264265266267270271272273274275276277"
  31. "300301302303304305306307310311312313314315316317"
  32. "320321322323324325326327330331332333334335336337"
  33. "340341342343344345346347350351352353354355356357"
  34. "360361362363364365366367370371372373374375376377"
  35. ;
  36. const T Text_cset   = { 256, cset };
  37. const T Text_ascii  = { 127, cset };
  38. const T Text_ucase  = {  26, cset + 'A' };
  39. const T Text_lcase  = {  26, cset + 'a' };
  40. const T Text_digits = {  10, cset + '0' };
  41. const T Text_null   = {   0, cset };
  42. static struct chunk {
  43. struct chunk *link;
  44. char *avail;
  45. char *limit;
  46. } head = { NULL, NULL, NULL }, *current = &head;
  47. static char *alloc(int len) {
  48. assert(len >= 0);
  49. if (current->avail + len > current->limit) {
  50. current = current->link = 
  51. ALLOC(sizeof (*current) + 10*1024 + len);
  52. current->avail = (char *)(current + 1);
  53. current->limit = current->avail + 10*1024 + len;
  54. current->link = NULL;
  55. }
  56. current->avail += len;
  57. return current->avail - len;
  58. }
  59. int Text_pos(T s, int i) {
  60. assert(s.len >= 0 && s.str);
  61. i = idx(i, s.len);
  62. assert(i >= 0 && i <= s.len);
  63. return i + 1;
  64. }
  65. T Text_box(const char *str, int len) {
  66. T text;
  67. assert(str);
  68. assert(len >= 0);
  69. text.str = str;
  70. text.len = len;
  71. return text;
  72. }
  73. T Text_sub(T s, int i, int j) {
  74. T text;
  75. assert(s.len >= 0 && s.str);
  76. i = idx(i, s.len);
  77. j = idx(j, s.len);
  78. if (i > j) { int t = i; i = j; j = t; }
  79. assert(i >= 0 && j <= s.len);
  80. text.len = j - i;
  81. text.str = s.str + i;
  82. return text;
  83. }
  84. T Text_put(const char *str) {
  85. T text;
  86. assert(str);
  87. text.len = strlen(str);
  88. text.str = memcpy(alloc(text.len), str, text.len);
  89. return text;
  90. }
  91. char *Text_get(char *str, int size, T s) {
  92. assert(s.len >= 0 && s.str);
  93. if (str == NULL)
  94. str = ALLOC(s.len + 1);
  95. else
  96. assert(size >= s.len + 1);
  97. memcpy(str, s.str, s.len);
  98. str[s.len] = '';
  99. return str;
  100. }
  101. T Text_dup(T s, int n) {
  102. assert(s.len >= 0 && s.str);
  103. assert(n >= 0);
  104. if (n == 0 || s.len == 0)
  105. return Text_null;
  106. if (n == 1)
  107. return s;
  108. {
  109. T text;
  110. char *p;
  111. text.len = n*s.len;
  112. if (isatend(s, text.len - s.len)) {
  113. text.str = s.str;
  114. p = alloc(text.len - s.len);
  115. n--;
  116. } else
  117. text.str = p = alloc(text.len);
  118. for ( ; n-- > 0; p += s.len)
  119. memcpy(p, s.str, s.len);
  120. return text;
  121. }
  122. }
  123. T Text_cat(T s1, T s2) {
  124. assert(s1.len >= 0 && s1.str);
  125. assert(s2.len >= 0 && s2.str);
  126. if (s1.len == 0)
  127. return s2;
  128. if (s2.len == 0)
  129. return s1;
  130. if (s1.str + s1.len == s2.str) {
  131. s1.len += s2.len;
  132. return s1;
  133. }
  134. {
  135. T text;
  136. text.len = s1.len + s2.len;
  137. if (isatend(s1, s2.len)) {
  138. text.str = s1.str;
  139. memcpy(alloc(s2.len), s2.str, s2.len);
  140. } else {
  141. char *p;
  142. text.str = p = alloc(s1.len + s2.len);
  143. memcpy(p,          s1.str, s1.len);
  144. memcpy(p + s1.len, s2.str, s2.len);
  145. }
  146. return text;
  147. }
  148. T Text_reverse(T s) {
  149. assert(s.len >= 0 && s.str);
  150. if (s.len == 0)
  151. return Text_null;
  152. else if (s.len == 1)
  153. return s;
  154. else {
  155. T text;
  156. char *p;
  157. int i = s.len;
  158. text.len = s.len;
  159. text.str = p = alloc(s.len);
  160. while (--i >= 0)
  161. *p++ = s.str[i];
  162. return text;
  163. }
  164. }
  165. T Text_map(T s, const T *from, const T *to) {
  166. static char map[256];
  167. static int inited = 0;
  168. assert(s.len >= 0 && s.str);
  169. if (from && to) {
  170. int k;
  171. for (k = 0; k < (int)sizeof map; k++)
  172. map[k] = k;
  173. assert(from->len == to->len);
  174. for (k = 0; k < from->len; k++)
  175. map[from->str[k]] = to->str[k];
  176. inited = 1;
  177. } else {
  178. assert(from == NULL && to == NULL);
  179. assert(inited);
  180. }
  181. if (s.len == 0)
  182. return Text_null;
  183. else {
  184. T text;
  185. int i;
  186. char *p;
  187. text.len = s.len;
  188. text.str = p = alloc(s.len);
  189. for (i = 0; i < s.len; i++)
  190. *p++ = map[s.str[i]];
  191. return text;
  192. }
  193. }
  194. int Text_cmp(T s1, T s2) {
  195. assert(s1.len >= 0 && s1.str);
  196. assert(s2.len >= 0 && s2.str);
  197. if (s1.str == s2.str)
  198. return s1.len - s2.len;
  199. else if (s1.len < s2.len) {
  200. int cond = memcmp(s1.str, s2.str, s1.len);
  201. return cond == 0 ? -1 : cond;
  202. } else if (s1.len > s2.len) {
  203. int cond = memcmp(s1.str, s2.str, s2.len);
  204. return cond == 0 ? +1 : cond;
  205. } else
  206. return memcmp(s1.str, s2.str, s1.len);
  207. }
  208. Text_save_T Text_save(void) {
  209. Text_save_T save;
  210. NEW(save);
  211. save->current = current;
  212. save->avail = current->avail;
  213. alloc(1);
  214. return save;
  215. }
  216. void Text_restore(Text_save_T *save) {
  217. struct chunk *p, *q;
  218. assert(save && *save);
  219. current = (*save)->current;
  220. current->avail = (*save)->avail;
  221. FREE(*save);
  222. for (p = current->link; p; p = q) {
  223. q = p->link;
  224. FREE(p);
  225. }
  226. current->link = NULL;
  227. }
  228. int Text_chr(T s, int i, int j, int c) {
  229. assert(s.len >= 0 && s.str);
  230. i = idx(i, s.len);
  231. j = idx(j, s.len);
  232. if (i > j) { int t = i; i = j; j = t; }
  233. assert(i >= 0 && j <= s.len);
  234. for ( ; i < j; i++)
  235. if (s.str[i] == c)
  236. return i + 1;
  237. return 0;
  238. }
  239. int Text_rchr(T s, int i, int j, int c) {
  240. assert(s.len >= 0 && s.str);
  241. i = idx(i, s.len);
  242. j = idx(j, s.len);
  243. if (i > j) { int t = i; i = j; j = t; }
  244. assert(i >= 0 && j <= s.len);
  245. while (j > i)
  246. if (s.str[--j] == c)
  247. return j + 1;
  248. return 0;
  249. }
  250. int Text_upto(T s, int i, int j, T set) {
  251. assert(set.len >= 0 && set.str);
  252. assert(s.len >= 0 && s.str);
  253. i = idx(i, s.len);
  254. j = idx(j, s.len);
  255. if (i > j) { int t = i; i = j; j = t; }
  256. assert(i >= 0 && j <= s.len);
  257. for ( ; i < j; i++)
  258. if (memchr(set.str, s.str[i], set.len))
  259. return i + 1;
  260. return 0;
  261. }
  262. int Text_rupto(T s, int i, int j, T set) {
  263. assert(set.len >= 0 && set.str);
  264. assert(s.len >= 0 && s.str);
  265. i = idx(i, s.len);
  266. j = idx(j, s.len);
  267. if (i > j) { int t = i; i = j; j = t; }
  268. assert(i >= 0 && j <= s.len);
  269. while (j > i)
  270. if (memchr(set.str, s.str[--j], set.len))
  271. return j + 1;
  272. return 0;
  273. }
  274. int Text_find(T s, int i, int j, T str) {
  275. assert(str.len >= 0 && str.str);
  276. assert(s.len >= 0 && s.str);
  277. i = idx(i, s.len);
  278. j = idx(j, s.len);
  279. if (i > j) { int t = i; i = j; j = t; }
  280. assert(i >= 0 && j <= s.len);
  281. if (str.len == 0)
  282. return i + 1;
  283. else if (str.len == 1) {
  284. for ( ; i < j; i++)
  285. if (s.str[i] == *str.str)
  286. return i + 1;
  287. } else
  288. for ( ; i + str.len <= j; i++)
  289. if (equal(s, i, str))
  290. return i + 1;
  291. return 0;
  292. }
  293. int Text_rfind(T s, int i, int j, T str) {
  294. assert(str.len >= 0 && str.str);
  295. assert(s.len >= 0 && s.str);
  296. i = idx(i, s.len);
  297. j = idx(j, s.len);
  298. if (i > j) { int t = i; i = j; j = t; }
  299. assert(i >= 0 && j <= s.len);
  300. if (str.len == 0)
  301. return j + 1;
  302. else if (str.len == 1) {
  303. while (j > i)
  304. if (s.str[--j] == *str.str)
  305. return j + 1;
  306. } else
  307. for ( ; j - str.len >= i; j--)
  308. if (equal(s, j - str.len, str))
  309. return j - str.len + 1;
  310. return 0;
  311. }
  312. int Text_any(T s, int i, T set) {
  313. assert(s.len >= 0 && s.str);
  314. assert(set.len >= 0 && set.str);
  315. i = idx(i, s.len);
  316. assert(i >= 0 && i <= s.len);
  317. if (i < s.len && memchr(set.str, s.str[i], set.len))
  318. return i + 2;
  319. return 0;
  320. }
  321. int Text_many(T s, int i, int j, T set) {
  322. assert(set.len >= 0 && set.str);
  323. assert(s.len >= 0 && s.str);
  324. i = idx(i, s.len);
  325. j = idx(j, s.len);
  326. if (i > j) { int t = i; i = j; j = t; }
  327. assert(i >= 0 && j <= s.len);
  328. if (i < j && memchr(set.str, s.str[i], set.len)) {
  329. do
  330. i++;
  331. while (i < j
  332. && memchr(set.str, s.str[i], set.len));
  333. return i + 1;
  334. }
  335. return 0;
  336. }
  337. int Text_rmany(T s, int i, int j, T set) {
  338. assert(set.len >= 0 && set.str);
  339. assert(s.len >= 0 && s.str);
  340. i = idx(i, s.len);
  341. j = idx(j, s.len);
  342. if (i > j) { int t = i; i = j; j = t; }
  343. assert(i >= 0 && j <= s.len);
  344. if (j > i && memchr(set.str, s.str[j-1], set.len)) {
  345. do
  346. --j;
  347. while (j >= i
  348. && memchr(set.str, s.str[j], set.len));
  349. return j + 2;
  350. }
  351. return 0;
  352. }
  353. int Text_match(T s, int i, int j, T str) {
  354. assert(str.len >= 0 && str.str);
  355. assert(s.len >= 0 && s.str);
  356. i = idx(i, s.len);
  357. j = idx(j, s.len);
  358. if (i > j) { int t = i; i = j; j = t; }
  359. assert(i >= 0 && j <= s.len);
  360. if (str.len == 0)
  361. return i + 1;
  362. else if (str.len == 1) {
  363. if (i < j && s.str[i] == *str.str)
  364. return i + 2;
  365. } else if (i + str.len <= j && equal(s, i, str))
  366. return i + str.len + 1;
  367. return 0;
  368. }
  369. int Text_rmatch(T s, int i, int j, T str) {
  370. assert(str.len >= 0 && str.str);
  371. assert(s.len >= 0 && s.str);
  372. i = idx(i, s.len);
  373. j = idx(j, s.len);
  374. if (i > j) { int t = i; i = j; j = t; }
  375. assert(i >= 0 && j <= s.len);
  376. if (str.len == 0)
  377. return j + 1;
  378. else if (str.len == 1) {
  379. if (j > i && s.str[j-1] == *str.str)
  380. return j;
  381. } else if (j - str.len >= i
  382. && equal(s, j - str.len, str))
  383. return j - str.len + 1;
  384. return 0;
  385. }
  386. void Text_fmt(int code, va_list *app,
  387. int put(int c, void *cl), void *cl,
  388. unsigned char flags[], int width, int precision) {
  389. T *s;
  390. assert(app && flags);
  391. s = va_arg(*app, T*);
  392. assert(s && s->len >= 0 && s->str);
  393. Fmt_puts(s->str, s->len, put, cl, flags,
  394. width, precision);
  395. }