PageRenderTime 63ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/source/src/Kernel/Types/string.cpp

http://itexmacs.googlecode.com/
C++ | 405 lines | 330 code | 50 blank | 25 comment | 115 complexity | cb3ab510846e99c32c9bc5db408b4789 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. /******************************************************************************
  2. * MODULE : string.cpp
  3. * DESCRIPTION: Fixed size strings with reference counting.
  4. * Zero characters can be part of string.
  5. * COPYRIGHT : (C) 1999 Joris van der Hoeven
  6. *******************************************************************************
  7. * This software falls under the GNU general public license version 3 or later.
  8. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  9. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
  10. ******************************************************************************/
  11. #include "string.hpp"
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. /******************************************************************************
  16. * Low level routines and constructors
  17. ******************************************************************************/
  18. static inline int
  19. round_length (int n) {
  20. n=(n+3)&(0xfffffffc);
  21. if (n<24) return n;
  22. register int i=32;
  23. while (n>i) i<<=1;
  24. return i;
  25. }
  26. string_rep::string_rep (int n2):
  27. n(n2), a ((n==0)?((char*) NULL):tm_new_array<char> (round_length(n))) {}
  28. void
  29. string_rep::resize (register int m) {
  30. register int nn= round_length (n);
  31. register int mm= round_length (m);
  32. if (mm != nn) {
  33. if (mm != 0) {
  34. register int i, k= (m<n? m: n);
  35. char* b= tm_new_array<char> (mm);
  36. for (i=0; i<k; i++) b[i]= a[i];
  37. if (nn != 0) tm_delete_array (a);
  38. a= b;
  39. }
  40. else if (nn != 0) tm_delete_array (a);
  41. }
  42. n= m;
  43. }
  44. string::string (char c) {
  45. rep= tm_new<string_rep> (1);
  46. rep->a[0]=c;
  47. }
  48. string::string (const char* a) {
  49. int i, n=strlen(a);
  50. rep= tm_new<string_rep> (n);
  51. for (i=0; i<n; i++)
  52. rep->a[i]=a[i];
  53. }
  54. string::string (const char* a, int n) {
  55. register int i;
  56. rep= tm_new<string_rep> (n);
  57. for (i=0; i<n; i++)
  58. rep->a[i]=a[i];
  59. }
  60. /******************************************************************************
  61. * Common routines for strings
  62. ******************************************************************************/
  63. bool
  64. string::operator == (const char* s) {
  65. register int i, n= rep->n;
  66. register char* S= rep->a;
  67. for (i=0; i<n; i++) {
  68. if (s[i]!=S[i]) return false;
  69. if (s[i]=='\0') return false;
  70. }
  71. return (s[i]=='\0');
  72. }
  73. bool
  74. string::operator != (const char* s) {
  75. register int i, n= rep->n;
  76. register char* S= rep->a;
  77. for (i=0; i<n; i++) {
  78. if (s[i]!=S[i]) return true;
  79. if (s[i]=='\0') return true;
  80. }
  81. return (s[i]!='\0');
  82. }
  83. bool
  84. string::operator == (string a) {
  85. register int i;
  86. if (rep->n!=a->n) return false;
  87. for (i=0; i<rep->n; i++)
  88. if (rep->a[i]!=a->a[i]) return false;
  89. return true;
  90. }
  91. bool
  92. string::operator != (string a) {
  93. register int i;
  94. if (rep->n!=a->n) return true;
  95. for (i=0; i<rep->n; i++)
  96. if (rep->a[i]!=a->a[i]) return true;
  97. return false;
  98. }
  99. string
  100. string::operator () (int begin, int end) {
  101. register int i;
  102. string r (end-begin);
  103. for (i=begin; i<end; i++) r[i-begin]=rep->a[i];
  104. return r;
  105. }
  106. string
  107. copy (string s) {
  108. register int i, n=N(s);
  109. string r (n);
  110. for (i=0; i<n; i++) r[i]=s[i];
  111. return r;
  112. }
  113. string&
  114. operator << (string& a, char x) {
  115. a->resize (N(a)+ 1);
  116. a [N(a)-1]=x;
  117. return a;
  118. }
  119. string&
  120. operator << (string& a, string b) {
  121. register int i, k1= N(a), k2=N(b);
  122. a->resize (k1+k2);
  123. for (i=0; i<k2; i++) a[i+k1]= b[i];
  124. return a;
  125. }
  126. string
  127. operator * (string a, string b) {
  128. register int i, n1=N(a), n2=N(b);
  129. string c(n1+n2);
  130. for (i=0; i<n1; i++) c[i]=a[i];
  131. for (i=0; i<n2; i++) c[i+n1]=b[i];
  132. return c;
  133. }
  134. string
  135. operator * (const char* a, string b) {
  136. return string (a) * b;
  137. }
  138. string
  139. operator * (string a, const char* b) {
  140. return a * string (b);
  141. }
  142. bool
  143. operator <= (string s1, string s2) {
  144. register int i;
  145. for (i=0; i<N(s1); i++) {
  146. if (i>=N(s2)) return false;
  147. if (s1[i]<s2[i]) return true;
  148. if (s2[i]<s1[i]) return false;
  149. }
  150. return true;
  151. }
  152. tm_ostream&
  153. operator << (tm_ostream& out, string a) {
  154. int i, n=N(a);
  155. if (n==0) return out;
  156. for (i=0; i<n; i++) out << a[i];
  157. return out;
  158. }
  159. int
  160. hash (string s) {
  161. register int i, h=0, n=N(s);
  162. for (i=0; i<n; i++) {
  163. h=(h<<9)+(h>>23);
  164. h=h+((int) s[i]);
  165. }
  166. return h;
  167. }
  168. /******************************************************************************
  169. * Conversion routines
  170. ******************************************************************************/
  171. bool
  172. as_bool (string s) {
  173. return (s == "true");
  174. }
  175. int
  176. as_int (string s) {
  177. int i=0, n=N(s), val=0;
  178. if (n==0) return 0;
  179. if (s[0]=='-') i++;
  180. while (i<n) {
  181. if (s[i]<'0') break;
  182. if (s[i]>'9') break;
  183. val *= 10;
  184. val += (int) (s[i]-'0');
  185. i++;
  186. }
  187. if (s[0]=='-') val=-val;
  188. return val;
  189. }
  190. double
  191. as_double (string s) {
  192. double x= 0.0;
  193. {
  194. int i, n= N(s);
  195. STACK_NEW_ARRAY (buf, char, n+1);
  196. for (i=0; i<n; i++) buf[i]=s[i];
  197. buf[n]='\0';
  198. sscanf (buf, "%lf", &x);
  199. STACK_DELETE_ARRAY (buf);
  200. } // in order to avoid segmentation fault due to compiler bug
  201. return x;
  202. }
  203. char*
  204. as_charp (string s) {
  205. int i, n= N(s);
  206. char *s2= tm_new_array<char> (n+1);
  207. for (i=0; i<n; i++) s2[i]=s[i];
  208. s2[n]= '\0';
  209. return s2;
  210. }
  211. string
  212. as_string_bool (bool f) {
  213. if (f) return string ("true");
  214. else return string ("false");
  215. }
  216. string
  217. as_string (int i) {
  218. char buf[64];
  219. sprintf (buf, "%i", i);
  220. // sprintf (buf, "%i\0", i);
  221. return string (buf);
  222. }
  223. string
  224. as_string (unsigned int i) {
  225. char buf[64];
  226. sprintf (buf, "%i", i);
  227. // sprintf (buf, "%i\0", i);
  228. return string (buf);
  229. }
  230. string
  231. as_string (double x) {
  232. char buf[64];
  233. sprintf (buf, "%g", x);
  234. // sprintf (buf, "%g\0", x);
  235. return string(buf);
  236. }
  237. string
  238. as_string (const char* s) {
  239. return string (s);
  240. }
  241. bool
  242. is_bool (string s) {
  243. return (s == "true") || (s == "false");
  244. }
  245. bool
  246. is_int (string s) {
  247. int i=0, n=N(s);
  248. if (n==0) return false;
  249. if (s[i]=='+') i++;
  250. if (s[i]=='-') i++;
  251. if (i==n) return false;
  252. for (; i<n; i++)
  253. if ((s[i]<'0') || (s[i]>'9')) return false;
  254. return true;
  255. }
  256. bool
  257. is_double (string s) {
  258. int i=0, n=N(s);
  259. if (n==0) return false;
  260. if (s[i]=='+') i++;
  261. if (s[i]=='-') i++;
  262. if (i==n) return false;
  263. for (; i< n; i++)
  264. if ((s[i]<'0') || (s[i]>'9')) break;
  265. if (i==n) return true;
  266. if (s[i]=='.') {
  267. i++;
  268. if (i==n) return false;
  269. for (; i< n; i++)
  270. if ((s[i]<'0') || (s[i]>'9')) break;
  271. }
  272. if (i==n) return true;
  273. if (s[i++]!='e') return false;
  274. if (s[i]=='+') i++;
  275. if (s[i]=='-') i++;
  276. if (i==n) return false;
  277. for (; i< n; i++)
  278. if ((s[i]<'0') || (s[i]>'9')) return false;
  279. return true;
  280. }
  281. bool
  282. is_charp (string s) { (void) s;
  283. return true;
  284. }
  285. bool
  286. is_quoted (string s) {
  287. return (N(s)>=2) && (s[0]=='\042') && (s[N(s)-1]=='\042');
  288. }
  289. bool
  290. is_id (string s) {
  291. int i=0, n=N(s);
  292. if (n==0) return false;
  293. for (i=0; i< n; i++) {
  294. if ((i>0) && (s[i]>='0') && (s[i]<='9')) continue;
  295. if ((s[i]>='a') && (s[i]<='z')) continue;
  296. if ((s[i]>='A') && (s[i]<='Z')) continue;
  297. if (s[i]=='_') continue;
  298. return false;
  299. }
  300. return true;
  301. }
  302. /******************************************************************************
  303. * Error messages
  304. ******************************************************************************/
  305. static void (*the_info_handler) (string, string, int) = NULL;
  306. static void (*the_wait_handler) (string, string, int) = NULL;
  307. static void (*the_warning_handler) (string, string, int) = NULL;
  308. static void (*the_error_handler) (string, string, int) = NULL;
  309. void
  310. set_info_handler (void (*routine) (string, string, int)) {
  311. the_info_handler= routine; }
  312. void
  313. system_info (string message, string argument, int level) {
  314. if (DEBUG_AUTO)
  315. cout << "TeXmacs] " << message << " " << argument << LF;
  316. if (the_info_handler != NULL)
  317. the_info_handler (message, argument, level);
  318. }
  319. void
  320. set_wait_handler (void (*routine) (string, string, int)) {
  321. the_wait_handler= routine; }
  322. void
  323. system_wait (string message, string argument, int level) {
  324. if (the_wait_handler == NULL) {
  325. if (DEBUG_AUTO) {
  326. if (message == "") cout << "TeXmacs] Done" << LF;
  327. else {
  328. if (argument == "") cout << "TeXmacs] " << message << LF;
  329. else cout << "TeXmacs] " << message << " " << argument << LF;
  330. cout << "TeXmacs] Please wait..." << LF;
  331. }
  332. }
  333. }
  334. else the_wait_handler (message, argument, level);
  335. }
  336. void
  337. set_warning_handler (void (*routine) (string, string, int)) {
  338. the_warning_handler= routine; }
  339. void
  340. system_warning (string message, string argument, int level) {
  341. if (DEBUG_AUTO)
  342. cout << "TeXmacs] Warning: " << message << " " << argument << LF;
  343. if (the_info_handler != NULL)
  344. the_info_handler ("Warning: " * message, argument, level);
  345. }
  346. void
  347. set_error_handler (void (*routine) (string, string, int)) {
  348. the_error_handler= routine; }
  349. void
  350. system_error (string message, string argument, int level) {
  351. if (DEBUG_AUTO)
  352. cout << "TeXmacs] Error: " << message << " " << argument << LF;
  353. if (the_info_handler != NULL)
  354. the_info_handler ("Error: " * message, argument, level);
  355. }