home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / splash / part03 < prev    next >
Encoding:
Text File  |  1993-01-18  |  36.2 KB  |  1,346 lines

  1. Newsgroups: comp.sources.misc
  2. From: morris@netcom.com (Jim Morris)
  3. Subject: v34i123: splash - Small Perl-like List And String Handling class lib, v1.8, Part03/03
  4. Message-ID: <1993Jan18.214349.164@sparky.imd.sterling.com>
  5. X-Md4-Signature: 9f37b009e02a527e22270bc4faf8732e
  6. Date: Mon, 18 Jan 1993 21:43:49 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: morris@netcom.com (Jim Morris)
  10. Posting-number: Volume 34, Issue 123
  11. Archive-name: splash/part03
  12. Environment: C++
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  Changelog Makefile.std Todo assoc.h readme.2nd regexp.doc
  19. #   regexp.h regmagic.h slicetst.c++ splash.v
  20. # Wrapped by kent@sparky on Mon Jan 18 15:29:06 1993
  21. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 3 (of 3)."'
  24. if test -f 'Changelog' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'Changelog'\"
  26. else
  27.   echo shar: Extracting \"'Changelog'\" \(3452 characters\)
  28.   sed "s/^X//" >'Changelog' <<'END_OF_FILE'
  29. XCHANGELOG
  30. X---------
  31. Xv1.1    - Added PerlString::tr()
  32. X    - Added PerlString::operator+=(char)
  33. X    - Added PerlString(const char) constructor
  34. X
  35. Xv1.2    - Fixed a test case in PerlClass
  36. X    - Increased initial allocation of PerlString to 32 characters
  37. X    - Optimized PerlStringList::grep() by only compiling regexp once
  38. X    - Added PerlString::m(const Regexp&...) so that pre-compiled regular
  39. X      expressions can be used
  40. X    - changed "fprintf(stderr..." to "cerr << ..." in regexp.h
  41. X    - Added c, d & s options to the PerlString::tr() function
  42. X    - fixed some bugs in tr() range processing
  43. X
  44. Xv1.3    - Cleaned up MArray constructor - Thanks Michael
  45. X    - Cleaned up tr() some more. Fixed d and s and c option.
  46. X    - Added PerlStringList PerlString::split()
  47. X    - Added operator>>() for PerlString
  48. X    - Added operator>>() for PerlStringList
  49. X    - Fixed operator<<() for PerlStringList
  50. X    - Added operator>>() for PerlList
  51. X    - Fixed operator<<() for PerlList
  52. X
  53. Xv1.4    - Implemented PerlList::sort()
  54. X    - Implemented PerlString:s(), the substitute command
  55. X    - Added subexpression replacement in PerlString:s()
  56. X    - split out the test code from perlclass.c++ into perltest.c++
  57. X    - fixed bug in substr() for default length
  58. X    - Added the 'g' option for PerlString:s()
  59. X    - Changed the way that PerlString::m(s, l) works, now the list
  60. X      'l' is reset first.
  61. X    - Added PerlList<T>:operator void*() so a list can be used in
  62. X      a conditional, and returns 0 if the list is empty
  63. X    - Added PerlStringList m(pat, str) to match perl syntax
  64. X    - Added case insensitive matching to Regexp class
  65. X    - Added 'i' option to PerlStringList::grep
  66. X    - Added 'i' option to the m() functions
  67. X    - Added 'i' option to PerlString::s() function
  68. X    - Added a generic Makefile - Hooray
  69. X
  70. Xv1.5    - Added PerlList<T>::isempty()
  71. X    - Added PerlListBase instead of MArray, which uses the empty
  72. X      space technique at front and back as suggested by MG.
  73. X    - Changed PerlListBase::operator[]() to allow indexing non-existing
  74. X      elements, and implemented auto grow.
  75. X    - Fixed splice() to append to end of list if offset is > number
  76. X      of items in list, this matches perls behaviour
  77. X    - Fixed potential overrunning end of string in substring class
  78. X    - added a const version of Binar::key() and value()
  79. X    - Replaced MArray with VarString class for improved string
  80. X      handling - ie faster
  81. X
  82. Xv1.6    - Changed VarString::operator=() to not delete and new if
  83. X      enough is already allocated. (as per MG)
  84. X    - Fixed a grow() bug in VarString::add(char)
  85. X    - Sped up tr() by replacing lookup with indexed array for search
  86. X    - Fixed split() so it splits on whitespace by default
  87. X    - Added a PerlString::substring(Range) for convenience
  88. X    - Fixed split() to use regular expression for pattern, as per
  89. X      Perl (including subexpressions)
  90. X    - Fixed pop() to not give an assertion error when list is empty
  91. X      but to return an undefined element instead
  92. X    - Added special awk case to split("' '")
  93. X    - Added special case for empty string in split("")
  94. X
  95. Xv1.7    - Changed Names from Perl... to SP... for release to alt.sources
  96. X    - Added typdefs so old names would still work
  97. X    - renamed all files from perlclass.* to splash.*
  98. X    - Put a check in SPString::index() for offset < 0
  99. X
  100. Xv1.8    - added comparison operators to SPString to allow permutations
  101. X      of comparisons with char *'s.
  102. X    - added Slice and SubList to handle SPList slices
  103. X    - Added intersection and union of Ranges and test for validity
  104. X    - Added operator++ for extendng end of range by one
  105. X    - Stored length of Range rather than calculate it every time
  106. X    
  107. X    
  108. END_OF_FILE
  109.   if test 3452 -ne `wc -c <'Changelog'`; then
  110.     echo shar: \"'Changelog'\" unpacked with wrong size!
  111.   fi
  112.   # end of 'Changelog'
  113. fi
  114. if test -f 'Makefile.std' -a "${1}" != "-c" ; then 
  115.   echo shar: Will not clobber existing file \"'Makefile.std'\"
  116. else
  117.   echo shar: Extracting \"'Makefile.std'\" \(690 characters\)
  118.   sed "s/^X//" >'Makefile.std' <<'END_OF_FILE'
  119. X#
  120. X#
  121. X# Generic Makefile for splash and tests
  122. X#
  123. X#
  124. X
  125. XCC = cc
  126. XCFLAGS = -g
  127. XLFLAGS =
  128. X
  129. X# uncomment the next file if your USL cfront breaks enums
  130. X#DEFS = -DUSLCOMPILER
  131. X
  132. Xspltest: spltest.o tsplash.o regex.o
  133. X    $(CC) $(CFLAGS) $(LFLAGS) -DTEST -o spltest spltest.c++ tsplash.o regex.o
  134. X
  135. Xtsplash.o: splash.c++
  136. X    $(CC) $(CFLAGS) $(DEFS) -DTEST -c splash.c++
  137. X    mv splash.o tsplash.o
  138. X
  139. Xtsplash.o splash.o: splash.h regexp.h
  140. Xregex.o: regex.h
  141. X
  142. Xassoc: assoc.c++ splash.o regex.o
  143. X    $(CC) $(CFLAGS) $(LFLAGS) $(DEFS) -DTESTASSOC assoc.c++ splash.o regex.o -o assoc
  144. X
  145. Xtest:
  146. X    spltest > x
  147. X    diff x splash.v
  148. X
  149. Xchgfnt: chgfnt.o splash.o regex.o
  150. X    $(CC) $(CFLAGS) $(DEFS)  -DTESTCHGFNT  chgfnt.c++ splash.o regex.o -o chgfnt
  151. X    
  152. END_OF_FILE
  153.   if test 690 -ne `wc -c <'Makefile.std'`; then
  154.     echo shar: \"'Makefile.std'\" unpacked with wrong size!
  155.   fi
  156.   # end of 'Makefile.std'
  157. fi
  158. if test -f 'Todo' -a "${1}" != "-c" ; then 
  159.   echo shar: Will not clobber existing file \"'Todo'\"
  160. else
  161.   echo shar: Extracting \"'Todo'\" \(265 characters\)
  162.   sed "s/^X//" >'Todo' <<'END_OF_FILE'
  163. XThese are things I am likely to do in the near future.
  164. X======================================================
  165. X
  166. XImplement the g option for m() functions generating lists
  167. X
  168. XImplement some form of iterator along the lines of Perls foreach
  169. X
  170. XOptimise, Optimise, Optimise
  171. END_OF_FILE
  172.   if test 265 -ne `wc -c <'Todo'`; then
  173.     echo shar: \"'Todo'\" unpacked with wrong size!
  174.   fi
  175.   # end of 'Todo'
  176. fi
  177. if test -f 'assoc.h' -a "${1}" != "-c" ; then 
  178.   echo shar: Will not clobber existing file \"'assoc.h'\"
  179. else
  180.   echo shar: Extracting \"'assoc.h'\" \(2827 characters\)
  181.   sed "s/^X//" >'assoc.h' <<'END_OF_FILE'
  182. X/*
  183. X * Version 1.6
  184. X * Feeble attempt to duplicate perl associative arrays
  185. X * So feeble I won't even call it PerlAssoc!
  186. X * Anyway the key can only be a string, the value can be anything.
  187. X * Written by Jim Morris,  jegm@sgi.com
  188. X */
  189. X#ifndef    _SPASSOC_H
  190. X#define _SPASSOC_H
  191. X
  192. X#include <iostream.h>
  193. X#include "splash.h"
  194. X
  195. Xtemplate<class T>
  196. Xclass Binar
  197. X{
  198. Xprivate:
  199. X    SPString k;
  200. X    T v;
  201. X
  202. Xpublic:
  203. X    Binar(SPString a, T b) : k(a), v(b){}
  204. X    Binar(SPString a) : k(a){}
  205. X    Binar(){}
  206. X    
  207. X    Binar<T>& operator=(const Binar<T>& n){ k= n.k; v= n.v; return *this; }
  208. X    SPString& key(void){ return k; }
  209. X    const SPString& key(void) const { return k; }
  210. X    T& value(void){ return v; }
  211. X    const T& value(void) const { return v; }
  212. X    int operator==(const Binar<T>& b) const{return ((k == b.k) && (v == b.v));}    
  213. X    int operator<(const Binar& b) const {return v < b.v;} // to keep sort quiet
  214. X};
  215. X
  216. Xtemplate<class T>
  217. Xclass Assoc
  218. X{
  219. Xprivate:
  220. X    SPList<Binar<T> > dat;
  221. X    Binar<T> def;
  222. X    
  223. Xpublic:
  224. X    Assoc():def(""){}
  225. X    Assoc(SPString dk, T dv) : def(dk, dv){}
  226. X
  227. X    int scalar(void) const { return dat.scalar(); }
  228. X    
  229. X    SPStringList keys(void);
  230. X    SPList<T> values(void);
  231. X    
  232. X    int isin(const SPString& k) const;
  233. X    T adelete(const SPString& k);
  234. X        
  235. X    T& operator()(const SPString& k);
  236. X    Binar<T>& operator[](int i){ return dat[i]; }
  237. X};
  238. X
  239. Xtemplate<class T>
  240. XSPStringList Assoc<T>::keys(void)
  241. X{
  242. X    SPStringList r;
  243. X    for(int i=0;i<dat.scalar();i++)
  244. X    r.push(dat[i].key());
  245. X    return r;
  246. X}    
  247. X
  248. Xtemplate<class T>
  249. XSPList<T> Assoc<T>::values(void)
  250. X{
  251. X    SPList<T> r;
  252. X    for(int i=0;i<dat.scalar();i++)
  253. X    r.push(dat[i].value());
  254. X    return r;
  255. X}
  256. X
  257. Xtemplate<class T>
  258. XT& Assoc<T>::operator()(const SPString& k)
  259. X{
  260. X    for(int i=0;i<dat.scalar();i++){
  261. X    if(k == dat[i].key()) return dat[i].value();
  262. X    }
  263. X    
  264. X    dat.push(Binar<T>(k, def.value()));
  265. X    return dat[i].value();
  266. X}
  267. X
  268. Xtemplate<class T>
  269. XT Assoc<T>::adelete(const SPString& k)
  270. X{
  271. X    for(int i=0;i<dat.scalar();i++){
  272. X    if(k == dat[i].key()){
  273. X        T r= dat[i].value();
  274. X        dat.splice(i, 1);
  275. X        return r;
  276. X    }
  277. X    }
  278. X    
  279. X    return def.value();
  280. X}
  281. X
  282. Xtemplate<class T>
  283. Xint Assoc<T>::isin(const SPString& k) const
  284. X{
  285. X    for(int i=0;i<dat.scalar();i++){
  286. X    if(k == dat[i].key()) return i+1;
  287. X    }
  288. X    return 0;
  289. X}
  290. X
  291. Xtemplate<class T>
  292. Xostream& operator<<(ostream& os, Binar<T>& a)
  293. X{
  294. X    os << "(" << a.key() << ", " << a.value() << ")";
  295. X    return os;
  296. X}
  297. X
  298. Xtemplate<class T>
  299. Xostream& operator<<(ostream& os, Assoc<T>& a)
  300. X{
  301. X    for(int i=0;i<a.scalar();i++){
  302. X#ifdef    TEST
  303. X    os << "[" << i << "] " << a[i] << endl;
  304. X#else
  305. X    os << a[i] << endl;
  306. X#endif
  307. X    }
  308. X    return os;
  309. X}
  310. X
  311. X#if 0
  312. Xtemplate<class T>
  313. Xistream& operator>>(istream& s, Binar<T>& a)
  314. X{
  315. Xchar c= 0;
  316. X
  317. X    s >> c;
  318. X    if(c == '('){
  319. X    s >> a.key()
  320. X    }
  321. X    os << "(" << a.key() << ", " << a.value() << ")";
  322. X    return os;
  323. X}
  324. X#endif
  325. X#endif
  326. END_OF_FILE
  327.   if test 2827 -ne `wc -c <'assoc.h'`; then
  328.     echo shar: \"'assoc.h'\" unpacked with wrong size!
  329.   fi
  330.   # end of 'assoc.h'
  331. fi
  332. if test -f 'readme.2nd' -a "${1}" != "-c" ; then 
  333.   echo shar: Will not clobber existing file \"'readme.2nd'\"
  334. else
  335.   echo shar: Extracting \"'readme.2nd'\" \(7332 characters\)
  336.   sed "s/^X//" >'readme.2nd' <<'END_OF_FILE'
  337. XFor support Email to morris@netcom.com or jegm@sgi.com
  338. X
  339. XI would welcome bug reports for a while!
  340. XAlso comments are always welcome.
  341. X
  342. XThe latest version of SPLASH is always available via anonymous
  343. XFTP from netcom.com in ~ftp/pub/morris/splash.tar.Z (for Unix)
  344. Xand ~ftp/pub/morris/splash.zoo (for MSDOS)
  345. X
  346. XIntroducing SPLASH
  347. X==================
  348. X
  349. XSPLASH is a c++ class library that implements my favourite perl
  350. Xconstructs.  Obviously I can't duplicate all the functionality of perl,
  351. Xand wouldn't need to as perl already exists!! However I find this
  352. Xuseful, because it allows me to do Perl-like things in my programs.
  353. X
  354. XThis Code is not copyright, use as you will.  The regexp code is by
  355. XHenry Spencer, see the comments for Copyright info.  The only changes I
  356. Xhave made are to the header file, by adding a c++ prototype field.
  357. X
  358. XThe Class Hierarchy and member functions are are fully described in
  359. Xthe file splash.doc
  360. X         
  361. XBuilding NOTES
  362. X==============
  363. XThis must be compiled with a 3.0 or greater c++ compiler that can
  364. Xhandle Templates and nested classes.
  365. X
  366. XIt has been tested on Borland c++ v3.1 and USL-based 3.0.  GCC v2.2.2
  367. Xdoesn't like the Copy constructor syntax in template classes, and gives
  368. Xan assert error as well.
  369. X
  370. XTo build:
  371. X
  372. Xcompile splash.c++ and regex.c. Link in with your App.
  373. XInclude splash.h, (and assoc.h if used).
  374. X
  375. X> cc -c regex.c
  376. X> CC -c splash.c++
  377. X> CC yourapp.c++ splash.o regex.o -o yourapp
  378. X
  379. XTo test:
  380. X
  381. X> CC -DTEST spltest.c++ splash.c++ regex.o -o spltest
  382. X> spltest > x
  383. X> diff x splash.v
  384. X
  385. Xand
  386. X
  387. X> CC -DTEST slicetst.c++ splash.o regex.o -o slicetst
  388. X> slicetst > x
  389. X> diff x slicetst.v
  390. X
  391. XThis will do a full regression test. splash.v & slicetst.v contains the
  392. Xsample output of a correct run, so no differences should be
  393. Xencountered.
  394. X
  395. Xregex.c is not an ANSI c file, so you will have to turn off prototype
  396. Xchecking on your ANSI c compiler (or select kr checking).
  397. X
  398. XSome of the samples use a file called tracer.h, this is a fairly useful
  399. XDebugging helper grabbed from the net and slightly modified. I include
  400. Xtracer.h and tracer.c++ for completeness, however they are not required.
  401. X
  402. XCAVEATS (known ones that is)
  403. X=======
  404. XThis is not an optimised implementation, by any stretch of the
  405. Ximagination. It is a quick and dirty, "but it works" one.
  406. X
  407. XNo "out of memory checking" is done, I thought I'd wait for
  408. Xexceptions!!
  409. X
  410. XI have taken a few liberties in translating the selected perl
  411. Xfunctionality into a class library, apologies to Larry Wall, and
  412. Xanyone else this may offend.  You are welcome to fix it, just tell me
  413. Xhow you did it.
  414. X
  415. XA SPList<T> can only contain a list of type T, it cannot, as yet,
  416. Xhave multiple types in the same list. (This is feasible but messy).
  417. X
  418. XAssigning to an element of a SPList that is greater than the current
  419. Xlength of the SPList will expand the list as in perl, but the values
  420. Xin the newly created elements will be undefined, unlike perl. Except
  421. XSPStringList which will create empty strings. Also if <T> is a class
  422. Xthen the values will be whatever the default constructor creates.
  423. X
  424. XAnything that you make a SPList out of must define an operator<(),
  425. Xfor the sort routine. Its ok if it is a dummy.
  426. X
  427. XThe first index of a list is always 0. (Again this could be fixed).
  428. X
  429. XUnlike perl you can also access characters within
  430. Xa SPString using the '[]' syntax. But you must use substr() to
  431. Xchange them.
  432. X
  433. XNote that SPStrings cannot have embedded '\0' like perl, this
  434. Xis an efficiency trade off, because '\0' as a terminator is so
  435. Xingrained in c++ and c strings. (This could be fixed by carefully
  436. Xreplacing all str... functions with mem... functions
  437. X
  438. XRegular Expressions
  439. X-------------------
  440. X
  441. XRegular expressions may be slightly different, I used the straight
  442. XHenry Spencer version. I'm not sure what changes Larry made to them.
  443. X(It definitely doesn't support \w \b \s \S \d \D, or global match
  444. Xmode). - If someone can make Larry's regexp stuff into a stand-alone
  445. Xpackage like the original regex stuff, then I'll use it!
  446. X
  447. XThe g & o options are not supported in the m() functions.
  448. XI will try to support the 'g' option for m() in a list context.
  449. X
  450. XSPStringList::m(exp, targ) and SPString::m(exp, list) are used to
  451. Xsimulate $&, $0 - $9 in perl. In both cases the list gets loaded with
  452. Xthe subexpression matches. The 0'th element is equivalent to $& in perl
  453. Xand the 1'st element is equivalent to $1 etc.
  454. X
  455. XNote that in the SPStringlist::m() member function, result lists are
  456. Xappended whereas in SPString::m(s, list) 'list' is reset first.
  457. Xeg
  458. X{
  459. XSPString s;
  460. XSPStringList l1, l2;
  461. X
  462. X    s= "hello frobo goodbye";
  463. X    l1.push("was here first1"); l2.push("was here first2");
  464. X    s.m("(.*)frobo(.*)", l2); // Overwrites l with new list
  465. X    l1.m("(.*)frobo(.*)", s); // appends l with new list
  466. X// produces this result:
  467. X// l2[0] is "hello frobo goodbye"    // equiv of $&
  468. X// l2[1] is "hello "            // equiv of $1
  469. X// l2[2] is " goodbye"            //        $2
  470. X// and
  471. X// l1[0] is "was here first"
  472. X// l1[1] is "hello frobo goodbye"    // equiv of $&
  473. X// l1[2] is "hello "            //          $1
  474. X// l1[3] is " goodbye"            //        $2
  475. X// an l1.reset() preceding the l1.m() would get rid of l1[0] in the
  476. X// above example.    
  477. X}
  478. X
  479. XTo get the exact perl semantics of the m function in a list context
  480. Xyou can use the global m() function as follows:-
  481. X{
  482. XSPStringList sl;
  483. Xsl = m("(..) (..)", "ab cd ef"); // sl[0] gets "ab", sl[1] gets "cd"
  484. X}
  485. X
  486. XSP expressions (s/123/$&*2/e) in a substitute command
  487. X(SPString::s()) are obviously not done. However $& and $0-$9 are
  488. Xcorrectly expanded and substituted.
  489. X
  490. XAlso remember that if you want to put a \ in the regular expression
  491. Xthen you must actually type \\ as the c compiler will interpret a \ for
  492. Xyou. What happens to things like \t is up to your compiler.
  493. X
  494. X
  495. XI/O
  496. X---
  497. XI/O is done using standard c++ streams. I think this is ok, although
  498. Xsome perl-ism maybe introduced one day.
  499. Xeg to copy a text file a line at a time:-
  500. X{
  501. Xifstream fin("file1.txt");
  502. Xofstream fout("file2.txt");
  503. XSPString si;
  504. X
  505. X    while(fin >> si) fout << si << endl;
  506. X}
  507. X
  508. XThis will read the entire file into a SPStringList:-
  509. X{
  510. XSPStringList l;
  511. Xifstream fin("file1.txt");
  512. X
  513. X    fin >> l;
  514. X}
  515. X
  516. XOne nifty outcome of using streams this way is the following syntax
  517. Xwill load a SPStringList and SPList<T> in a reasonably compact
  518. Xway:-
  519. X{
  520. XSPStringList slist;
  521. Xstrstream ss;
  522. X    ss << "one\n" << "two\nthree\nfour\n";
  523. X    ss >> slist; // creates a 4 element string list
  524. X
  525. Xstrstream iss;
  526. XSPList<int> il;
  527. X
  528. X    iss << "1 2 3 4 5 6 7 8 9 10" << endl; // quick load an integer array
  529. X    iss >> il; // creates a 10 element integer list
  530. X}
  531. X
  532. X
  533. XIterators
  534. X---------
  535. XThere is no iterator per-se, but all lists (including Assoc) allow
  536. Xan index to step through the list one by one. So iteration can be
  537. Xachieved, albeit clumsily.
  538. Xeg
  539. X
  540. XSPList<int> intlist;
  541. X
  542. Xfor(int i=0;i<inlist.scalar();i++){
  543. X    cout << intlist[i];
  544. X}
  545. X
  546. Xforeach could be simulated with the following macro:-
  547. X
  548. X#define FOREACH(var, array)\
  549. X  for(int i=0;i<array.scalar() && (var=array[i], 1);i++)
  550. X
  551. Xeg
  552. X{
  553. X
  554. X    SPList<int> fred;
  555. X    int val, tot= 0;
  556. X
  557. X    {    // this is useful to avoid the 'i' in the macro colliding
  558. X    FOREACH(val, fred){
  559. X        tot += val;
  560. X    }
  561. X    }
  562. X}
  563. X
  564. XA SPList or SPStringList may be used in an if statement to test
  565. Xif the list is empty or not.
  566. Xeg
  567. X{
  568. XSPList<int> il;
  569. X
  570. X    if(il) cout << "List is not empty" << endl;
  571. X    else il.push(1);
  572. X}
  573. X
  574. X==========
  575. XDisclaimer
  576. X==========
  577. X
  578. XThis is a personal work, and SGI is not responsible for anything
  579. Xcontained herein.
  580. END_OF_FILE
  581.   if test 7332 -ne `wc -c <'readme.2nd'`; then
  582.     echo shar: \"'readme.2nd'\" unpacked with wrong size!
  583.   fi
  584.   # end of 'readme.2nd'
  585. fi
  586. if test -f 'regexp.doc' -a "${1}" != "-c" ; then 
  587.   echo shar: Will not clobber existing file \"'regexp.doc'\"
  588. else
  589.   echo shar: Extracting \"'regexp.doc'\" \(3706 characters\)
  590.   sed "s/^X//" >'regexp.doc' <<'END_OF_FILE'
  591. XREGULAR EXPRESSION SYNTAX
  592. X=========================
  593. XA regular expression is zero or more branches, separated by |. It matches
  594. Xanything that matches one of the branches. A branch is zero or more pieces,
  595. Xconcatenated. It matches a match for the first, followed by a match for the
  596. Xsecond, etc.
  597. X
  598. XA piece is an atom possibly followed by *, +, or ?.
  599. XAn atom followed by * matches a sequence of 0 or more matches of the atom.
  600. XAn atom followed by + matches a sequence of 1 or more matches of the atom.
  601. XAn atom followed by ? matches a match of the atom, or the null string.
  602. X
  603. XAn atom is a regular expression in parentheses (matching a match for the
  604. Xregular expression), a range (see below),
  605. X. (matching any single character),
  606. X^ (matching the null string at the beginning of the input string),
  607. X$ (matching the null string at the end of the input string),
  608. Xa \ followed by a single character (matching that character),
  609. Xor a single character with no other significance (matching that character).
  610. X
  611. XA range is a sequence of characters enclosed in []. It normally matches any
  612. Xsingle character from the sequence. If the sequence begins with ^, it matches
  613. Xany single character not from the rest of the sequence. If two characters in
  614. Xthe sequence are separated by -, this is shorthand for the full list of ASCII
  615. Xcharacters between them (e.g. [0-9] matches any decimal digit). To include a
  616. Xliteral ] in the sequence, make it the first character (following a possible
  617. X^). To include a literal -, make it the first or last character. AMBIGUITY If
  618. Xa regular expression could match two different parts of the input string, it
  619. Xwill match the one which begins earliest. If both begin in the same place but
  620. Xmatch different lengths, or match the same length in different ways, life gets
  621. Xmessier, as follows.
  622. X
  623. XIn general, the possibilities in a list of branches are considered in
  624. Xleft-to-right order, the possibilities for *, +, and ? are considered
  625. Xlongest-first, nested constructs are considered from the outermost in, and
  626. Xconcatenated constructs are considered leftmost-first. The match that will be
  627. Xchosen is the one that uses the earliest possibility in the first choice that
  628. Xhas to be made. If there is more than one choice, the next will be made in the
  629. Xsame manner (earliest possibility) subject to the decision on the first
  630. Xchoice. And so forth.
  631. X
  632. XFor example, '(ab|a)b*c' could match 'abc' in one of two ways. The first
  633. Xchoice is between 'ab' and 'a'; since 'ab' is earlier, and does lead to a
  634. Xsuccessful overall match, it is chosen. Since the 'b' is already spoken for,
  635. Xthe 'b*' must match its last possibility, the empty string, since it must
  636. Xrespect the earlier choice.
  637. X
  638. XIn the particular case where no |'s are present and there is only one *, +, or
  639. X?, the net effect is that the longest possible match will be chosen. So 'ab*',
  640. Xpresented with 'xabbbby', will match 'abbbb'. Note that if 'ab*' is tried
  641. Xagainst 'xabyabbbz', it will match 'ab' just after 'x', due to the
  642. Xbegins-earliest rule. (In effect, the decision on where to start the match is
  643. Xthe first choice to be made, hence subsequent choices must respect it even if
  644. Xthis leads them to less-preferred alternatives.
  645. X
  646. XREGULAR EXPRESSION SUBSTITUTION
  647. X===============================
  648. XSubstitutions are made according to the most recent RE search. Each instance
  649. Xof '$&' in the paste buffer is replaced by the string that matched the whole
  650. Xregular expression. Each instance of '$n', where n is a digit between 1 and 9,
  651. Xis replaced by the substrings that matched parenthesized expressions within
  652. Xthe regular expression, with parenthesized expressions numbered in
  653. Xleft-to-right order of their opening parentheses. To get a literal '$' or '\'
  654. Xinto dest, prefix it with '\'.
  655. X
  656. END_OF_FILE
  657.   if test 3706 -ne `wc -c <'regexp.doc'`; then
  658.     echo shar: \"'regexp.doc'\" unpacked with wrong size!
  659.   fi
  660.   # end of 'regexp.doc'
  661. fi
  662. if test -f 'regexp.h' -a "${1}" != "-c" ; then 
  663.   echo shar: Will not clobber existing file \"'regexp.h'\"
  664. else
  665.   echo shar: Extracting \"'regexp.h'\" \(3886 characters\)
  666.   sed "s/^X//" >'regexp.h' <<'END_OF_FILE'
  667. X/*
  668. X * version 1.8
  669. X * Regexp is a class that encapsulates the Regular expression
  670. X * stuff. Hopefully this means I can plug in different regexp
  671. X * libraries without the rest of my code needing to be changed.
  672. X * Written by Jim Morris,  jegm@sgi.com
  673. X */
  674. X#ifndef    _REGEXP_H
  675. X#define _REGEXP_H
  676. X#include    <iostream.h>
  677. X#include    <stdlib.h>
  678. X#include    <malloc.h>
  679. X#include    <string.h>
  680. X#include    <assert.h>
  681. X#include    <ctype.h>
  682. X
  683. X#include    "regex.h"
  684. X
  685. X/*
  686. X * Note this is an inclusive range where it goes
  687. X * from start() to, and including, end()
  688. X */
  689. Xclass Range
  690. X{
  691. Xprivate:
  692. X    int st, en, len;
  693. X    
  694. Xpublic:
  695. X    Range()
  696. X    {
  697. X    st=0; en= -1; len= 0;
  698. X    }
  699. X    
  700. X    Range(int s, int e)
  701. X    {
  702. X    st= s; en= e; len= (en - st) + 1;
  703. X     assert(st <= en && st >= 0); 
  704. X    }
  705. X
  706. X    // test validity of the range
  707. X    operator void *() { return (st <= en && st >= 0)? this : 0;}
  708. X    int start(void) const { return st;}
  709. X    int end(void) const { return en;}
  710. X    int length(void) const { return len;}
  711. X
  712. X    void set(int a, int b)
  713. X    {
  714. X    st= a; en= b; len= (en - st) + 1;
  715. X     assert(st <= en && st >= 0); 
  716. X    }
  717. X
  718. X    int operator<(const Range& r) const // for sorting
  719. X    {
  720. X        return ((st == r.st) ? (en < r.en) : (st < r.st));
  721. X    }
  722. X
  723. X    // x++ operator extends end of range by one
  724. X    void operator++(int){ en++; len++; }
  725. X    
  726. X    // ++x operator extends start of range by one
  727. X    void operator++(void){ st++; len--; }
  728. X
  729. X#if 0
  730. X    // Don't need these yet
  731. X    Range operator&(const Range& r) const // returns intersection of two ranges
  732. X    {
  733. X        Range ret;
  734. X        if(en >= 0 && r.en >= 0 && (st <= r.en) && (en >= r.st)){  // if any overlap
  735. X            ret.st= (st > r.st) ? st : r.st;
  736. X            ret.en= (en < r.en) ? en : r.en;
  737. X        }
  738. X        return ret;
  739. X    }
  740. X    
  741. X    Range operator|(const Range& r) const // returns union of two ranges if consecutive
  742. X    {
  743. X        Range ret;
  744. X        if(en >= 0 && r.en >= 0 && (st <= r.en+1) && (en >= r.st-1)){  // if any overlap or contiguous
  745. X            ret.st= (st < r.st) ? st : r.st;
  746. X            ret.en= (en > r.en) ? en : r.en;
  747. X        }
  748. X        return ret;
  749. X    }
  750. X#endif
  751. X
  752. X    friend ostream& operator<<(ostream& os, const Range& r)
  753. X    {
  754. X        os << r.st << " - " << r.en << " (" << (r.en - r.st)+1 << ")";
  755. X        return os;
  756. X    }
  757. X};
  758. X
  759. Xclass Regexp
  760. X{
  761. Xpublic:
  762. X    enum options {def=0, nocase=1};
  763. X    
  764. Xprivate:
  765. X    regexp *repat;
  766. X    const char *target; // only used as a base address to get an offset
  767. X    int res;
  768. X    int iflg;
  769. X#ifndef    __TURBOC__
  770. X    void strlwr(char *s)
  771. X    {
  772. X    while(*s){
  773. X        *s= tolower(*s);
  774. X        s++;
  775. X    }
  776. X    }
  777. X#endif    
  778. Xpublic:
  779. X    Regexp(const char *rege, int ifl= 0)
  780. X    {
  781. X        iflg= ifl;
  782. X        if(iflg == nocase){ // lowercase fold
  783. X            char *r= new char[strlen(rege)+1];
  784. X            strcpy(r, rege);
  785. X            strlwr(r);
  786. X            if((repat=regcomp(r)) == NULL){
  787. X            cerr << "regcomp() error" << endl;
  788. X            exit(1);
  789. X            }
  790. X            delete [] r;
  791. X    }else{
  792. X        if((repat=regcomp (rege)) == NULL){
  793. X            cerr << "regcomp() error" << endl;
  794. X            exit(1);
  795. X        }
  796. X        }
  797. X    }
  798. X    
  799. X    ~Regexp()
  800. X    {
  801. X    free(repat);
  802. X    }    
  803. X
  804. X    int match(const char *targ)
  805. X    {
  806. X        int res;
  807. X        if(iflg == nocase){ // fold lowercase
  808. X            char *r= new char[strlen(targ)+1];
  809. X            strcpy(r, targ);
  810. X            strlwr(r);
  811. X            res= regexec(repat, r); 
  812. X            target= r; // looks bad but is really ok, really
  813. X            delete [] r;
  814. X        }else{
  815. X        res= regexec(repat, targ);
  816. X        target= targ;
  817. X    }
  818. X
  819. X    return ((res == 0) ? 0 : 1);
  820. X    }
  821. X    
  822. X    int groups(void) const
  823. X    {
  824. X    int res= 0;
  825. X    for (int i=0; i<NSUBEXP; i++) {
  826. X        if(repat->startp[i] == NULL) break;
  827. X        res++;
  828. X    }
  829. X    return res;
  830. X    }
  831. X    
  832. X    Range getgroup(int n) const
  833. X    {
  834. X    assert(n < NSUBEXP);
  835. X    return Range((int)(repat->startp[n] - (char *)target),
  836. X             (int)(repat->endp[n] - (char *)target) - 1);
  837. X    }
  838. X};
  839. X#endif
  840. END_OF_FILE
  841.   if test 3886 -ne `wc -c <'regexp.h'`; then
  842.     echo shar: \"'regexp.h'\" unpacked with wrong size!
  843.   fi
  844.   # end of 'regexp.h'
  845. fi
  846. if test -f 'regmagic.h' -a "${1}" != "-c" ; then 
  847.   echo shar: Will not clobber existing file \"'regmagic.h'\"
  848. else
  849.   echo shar: Extracting \"'regmagic.h'\" \(153 characters\)
  850.   sed "s/^X//" >'regmagic.h' <<'END_OF_FILE'
  851. X/*
  852. X * The first byte of the regexp internal "program" is actually this magic
  853. X * number; the start node begins in the second byte.
  854. X */
  855. X#define    MAGIC    0234
  856. END_OF_FILE
  857.   if test 153 -ne `wc -c <'regmagic.h'`; then
  858.     echo shar: \"'regmagic.h'\" unpacked with wrong size!
  859.   fi
  860.   # end of 'regmagic.h'
  861. fi
  862. if test -f 'slicetst.c++' -a "${1}" != "-c" ; then 
  863.   echo shar: Will not clobber existing file \"'slicetst.c++'\"
  864. else
  865.   echo shar: Extracting \"'slicetst.c++'\" \(1927 characters\)
  866.   sed "s/^X//" >'slicetst.c++' <<'END_OF_FILE'
  867. X#ifdef    TEST
  868. X
  869. X#include <iostream.h>
  870. X
  871. X#include "splash.h"
  872. X
  873. Xtypedef int INT;
  874. X
  875. Xtemplate <class T>
  876. Xostream& operator<<(ostream& os, const SubList<T>& sl)
  877. X{
  878. X    os << SPList<T>(sl) << endl;
  879. X    return os;
  880. X}
  881. X
  882. Xint main()
  883. X{
  884. X#if    1
  885. X    Slice sl1;
  886. X
  887. X    sl1.add(1); sl1.add(2);
  888. X    cout << "1,2 " << sl1 << endl;
  889. X
  890. X    Slice sl2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1);
  891. X    cout << "1,2,3,4,5,6,7,8,9,10 " << sl2 << endl;
  892. X
  893. X    sl1.add(5); sl1.add(10);
  894. X    cout << "1,2,5,10 " << sl1 << endl;
  895. X
  896. X    Slice sl3(39, 1, 38, 2, 4, 5, 37, 7, 8, 9, 20, 22, -1);
  897. X    cout << "39,1,38,2,4,5,37,7,8,9,20,22 " << sl3 << endl;
  898. X
  899. X    SPList<INT> ix1, ix2;
  900. X    ix1.push(1); ix1.push(2); ix1.push(3); ix1.push(4);
  901. X    ix2.push(22); ix2.push(33);
  902. X    cout << "ix1= " << ix1 << endl << "ix2= " << ix2 << endl;
  903. X
  904. X    ix1(1, 2)= ix2;
  905. X    
  906. X    cout << "ix1(1, 2)= ix2: ix1= " << ix1 << endl;
  907. X    
  908. X    SPList<INT> tl(ix1(2, 3));
  909. X    
  910. X    cout << "tl ctor(ix1(2, 3)): tl= " << tl << endl;
  911. X    
  912. X    SPList<INT> tl2;
  913. X    
  914. X    tl2.push(0); tl2.push(1); tl2.push(2); tl2.push(3); tl2.push(4);
  915. X    cout << "tl2= " << tl2 << endl;
  916. X    
  917. X    cout << "tl2(2, 3)= " << tl2(2, 3) << endl;
  918. X    cout << "tl2(Slice(1, 2, 4, -1))= " << tl2(Slice(1, 2, 4, -1)) << endl;
  919. X    
  920. X    tl= tl2(Range(2, 4));
  921. X    cout << "tl= tl2(Range(2, 4)): tl= " << tl << endl;
  922. X    
  923. X    tl2(Slice(1, 2, -1))= ix2;
  924. X    
  925. X    cout << "tl2(Slice(1, 2, -1))= ix2: tl2 = " << tl2 << endl;
  926. X
  927. X    SPList<INT> tl3;
  928. X    
  929. X    tl3= tl2(1, 4);
  930. X    
  931. X    cout << "tl3= tl2(1, 4): tl3 = " << tl3 << endl;
  932. X    
  933. X    tl3.push(tl2(1, 2));
  934. X    
  935. X    cout << "tl3.push(tl2(1, 2)): tl3= " << tl3 << endl;
  936. X    
  937. X    cout << "tl3(Slice(4, 1, -1))= " << tl3(Slice(4, 1, -1)) << endl;
  938. X    
  939. X    cout << "tl3(Slice(2, 1, -1))= " << tl3(Slice(2, 1, -1)) << endl;
  940. X#endif
  941. X    SPList<int> tl4;
  942. X    for(int i=0;i<40;i++) tl4.push(i);
  943. X
  944. X    cout << "tl4(\"1..3,6,10-22,30,31,35,37\") = " << tl4("1..3,6,10-22,30,31,35,37") << endl;
  945. X
  946. X
  947. X    
  948. X}
  949. X#endif
  950. END_OF_FILE
  951.   if test 1927 -ne `wc -c <'slicetst.c++'`; then
  952.     echo shar: \"'slicetst.c++'\" unpacked with wrong size!
  953.   fi
  954.   # end of 'slicetst.c++'
  955. fi
  956. if test -f 'splash.v' -a "${1}" != "-c" ; then 
  957.   echo shar: Will not clobber existing file \"'splash.v'\"
  958. else
  959.   echo shar: Extracting \"'splash.v'\" \(6620 characters\)
  960.   sed "s/^X//" >'splash.v' <<'END_OF_FILE'
  961. Xx is empty
  962. Xx.isempty() is true
  963. Xx is not empty
  964. Xx.isempty() is false
  965. Xx.split(a b c d e f)= 6: [0](1)"a"
  966. X[1](1)"b"
  967. X[2](1)"c"
  968. X[3](1)"d"
  969. X[4](1)"e"
  970. X[5](1)"f"
  971. X
  972. Xx[0] = (1)"a"
  973. Xz= x; z[0]="x" z: [0](1)"x"
  974. X[1](1)"b"
  975. X[2](1)"c"
  976. X[3](1)"d"
  977. X[4](1)"e"
  978. X[5](1)"f"
  979. X
  980. Xss= (19)"1.2.3.4.5.6.7.8.9.0", y= ss.split("\."), y=
  981. X[0](1)"1"
  982. X[1](1)"2"
  983. X[2](1)"3"
  984. X[3](1)"4"
  985. X[4](1)"5"
  986. X[5](1)"6"
  987. X[6](1)"7"
  988. X[7](1)"8"
  989. X[8](1)"9"
  990. X[9](1)"0"
  991. X
  992. Xy.join(" ")(19)"1 2 3 4 5 6 7 8 9 0"
  993. X(15)"a b c
  994. Xd e    f   g"
  995. Xxx.split()= [0](1)"a"
  996. X[1](1)"b"
  997. X[2](1)"c"
  998. X[3](1)"d"
  999. X[4](1)"e"
  1000. X[5](1)"f"
  1001. X[6](1)"g"
  1002. X
  1003. X(13)"a b c d e f g"
  1004. Xxx.split(",")= [0](13)"a b c d e f g"
  1005. X
  1006. X(20)"  a b c d e f g hi  "
  1007. Xxx.split("")= [0](1)" "
  1008. X[1](1)" "
  1009. X[2](1)"a"
  1010. X[3](1)" "
  1011. X[4](1)"b"
  1012. X[5](1)" "
  1013. X[6](1)"c"
  1014. X[7](1)" "
  1015. X[8](1)"d"
  1016. X[9](1)" "
  1017. X[10](1)"e"
  1018. X[11](1)" "
  1019. X[12](1)"f"
  1020. X[13](1)" "
  1021. X[14](1)"g"
  1022. X[15](1)" "
  1023. X[16](1)"h"
  1024. X[17](1)"i"
  1025. X[18](1)" "
  1026. X[19](1)" "
  1027. X
  1028. X(18)"a,b,c,d,,e,f,g,,,,"
  1029. Xxx.split(",")= [0](1)"a"
  1030. X[1](1)"b"
  1031. X[2](1)"c"
  1032. X[3](1)"d"
  1033. X[4](0)""
  1034. X[5](1)"e"
  1035. X[6](1)"f"
  1036. X[7](1)"g"
  1037. X
  1038. X(16)"a,b,c,d,,e,f,g,,"
  1039. Xxx.split(",", 5)= [0](1)"a"
  1040. X[1](1)"b"
  1041. X[2](1)"c"
  1042. X[3](1)"d"
  1043. X[4](8)",e,f,g,,"
  1044. X
  1045. X(16)" a b c d e f g  "
  1046. Xxx.split(" ")= [0](0)""
  1047. X[1](1)"a"
  1048. X[2](1)"b"
  1049. X[3](1)"c"
  1050. X[4](1)"d"
  1051. X[5](1)"e"
  1052. X[6](1)"f"
  1053. X[7](1)"g"
  1054. X
  1055. X(13)"a b c d,e,f g"
  1056. Xxx.split("([ ,])+")= [0](1)"a"
  1057. X[1](1)" "
  1058. X[2](1)"b"
  1059. X[3](1)" "
  1060. X[4](1)"c"
  1061. X[5](1)" "
  1062. X[6](1)"d"
  1063. X[7](1)","
  1064. X[8](1)"e"
  1065. X[9](1)","
  1066. X[10](1)"f"
  1067. X[11](1)" "
  1068. X[12](1)"g"
  1069. X
  1070. X(4)",,,,"
  1071. Xxx.split(",")= 
  1072. X(0)""
  1073. Xxx.split(",")= 
  1074. X(23)"   a b c    d    e
  1075. Xf  g   "
  1076. Xxx.split("' '")= [0](1)"a"
  1077. X[1](1)"b"
  1078. X[2](1)"c"
  1079. X[3](1)"d"
  1080. X[4](1)"e"
  1081. X[5](1)"f"
  1082. X[6](1)"g"
  1083. X
  1084. Xx = [0](1)"a"
  1085. X[1](1)"b"
  1086. X[2](1)"c"
  1087. X[3](1)"d"
  1088. X[4](1)"e"
  1089. X[5](1)"f"
  1090. X
  1091. Xx.pop() : (1)"f", (1)"e"
  1092. Xx= [0](1)"a"
  1093. X[1](1)"b"
  1094. X[2](1)"c"
  1095. X[3](1)"d"
  1096. X
  1097. Xx.shift() : (1)"a", (1)"b"
  1098. Xx= [0](1)"c"
  1099. X[1](1)"d"
  1100. X
  1101. Xx.unshift(y): [0](1)"1"
  1102. X[1](1)"2"
  1103. X[2](1)"3"
  1104. X[3](1)"4"
  1105. X[4](1)"5"
  1106. X[5](1)"6"
  1107. X[6](1)"7"
  1108. X[7](1)"8"
  1109. X[8](1)"9"
  1110. X[9](1)"0"
  1111. X[10](1)"c"
  1112. X[11](1)"d"
  1113. X
  1114. Xil is empty
  1115. Xil is not empty
  1116. Xil(1, 2, 3, 4) : [0]1 [1]2 [2]3 [3]4 
  1117. X
  1118. Xil3= il; il3[0]= 9999; il3 = [0]9999 [1]2 [2]3 [3]4 
  1119. X
  1120. Xil= [0]1 [1]2 [2]3 [3]4 
  1121. X
  1122. Xil.reverse: [0]4 [1]3 [2]2 [3]1 
  1123. X
  1124. Xil1.sort(): [0]1 [1]2 [2]3 [3]4 
  1125. X
  1126. Xy = 
  1127. X[0](3)"one"
  1128. X[1](3)"two"
  1129. X[2](5)"three"
  1130. X[3](4)"four"
  1131. Xy.reverse() [0](4)"four" [1](5)"three" [2](3)"two" [3](3)"one" 
  1132. X
  1133. Xy.sort() [0](4)"four" [1](3)"one" [2](5)"three" [3](3)"two" 
  1134. X
  1135. Xy.sort().reverse() [0](3)"two" [1](5)"three" [2](3)"one" [3](4)"four" 
  1136. X
  1137. Xil2.push(3, 4) : [0]3 [1]4 
  1138. X
  1139. Xil.push(il2) : [0]1 [1]2 [2]3 [3]4 [4]3 [5]4 
  1140. X
  1141. Xil.pop() : 4, 3
  1142. Xil.unshift(il2) : [0]3 [1]4 [2]1 [3]2 [4]3 [5]4 
  1143. X
  1144. Xil.shift() : 3, 4
  1145. Xtesting splice:
  1146. Xx = [0](1)"a"
  1147. X[1](1)"b"
  1148. X[2](1)"c"
  1149. X[3](1)"d"
  1150. X[4](1)"e"
  1151. X[5](1)"f"
  1152. X[6](1)"g"
  1153. X[7](1)"h"
  1154. X[8](1)"i"
  1155. X
  1156. Xz= x.splice(2, 3): z= [0](1)"c"
  1157. X[1](1)"d"
  1158. X[2](1)"e"
  1159. X
  1160. Xx = [0](1)"a"
  1161. X[1](1)"b"
  1162. X[2](1)"f"
  1163. X[3](1)"g"
  1164. X[4](1)"h"
  1165. X[5](1)"i"
  1166. X
  1167. Xx.splice(2, 0, z): 
  1168. Xx= [0](1)"a"
  1169. X[1](1)"b"
  1170. X[2](1)"c"
  1171. X[3](1)"d"
  1172. X[4](1)"e"
  1173. X[5](1)"f"
  1174. X[6](1)"g"
  1175. X[7](1)"h"
  1176. X[8](1)"i"
  1177. X
  1178. Xz.splice(1, 1, x): [0](1)"d" 
  1179. Xz= [0](1)"c"
  1180. X[1](1)"a"
  1181. X[2](1)"b"
  1182. X[3](1)"c"
  1183. X[4](1)"d"
  1184. X[5](1)"e"
  1185. X[6](1)"f"
  1186. X[7](1)"g"
  1187. X[8](1)"h"
  1188. X[9](1)"i"
  1189. X[10](1)"e"
  1190. X
  1191. Xx= [0](1)"a"
  1192. X[1](1)"b"
  1193. X[2](1)"c"
  1194. X[3](1)"d"
  1195. X[4](1)"e"
  1196. X[5](1)"f"
  1197. X[6](1)"g"
  1198. X[7](1)"h"
  1199. X[8](1)"i"
  1200. X
  1201. Xz.splice(20, 1, x): 
  1202. Xz= [0](1)"c"
  1203. X[1](1)"a"
  1204. X[2](1)"b"
  1205. X[3](1)"c"
  1206. X[4](1)"d"
  1207. X[5](1)"e"
  1208. X[6](1)"f"
  1209. X[7](1)"g"
  1210. X[8](1)"h"
  1211. X[9](1)"i"
  1212. X[10](1)"e"
  1213. X[11](1)"a"
  1214. X[12](1)"b"
  1215. X[13](1)"c"
  1216. X[14](1)"d"
  1217. X[15](1)"e"
  1218. X[16](1)"f"
  1219. X[17](1)"g"
  1220. X[18](1)"h"
  1221. X[19](1)"i"
  1222. X
  1223. X4, 3
  1224. X101, 5678, 1234
  1225. XIndex check done
  1226. X201, 0, 200
  1227. X
  1228. Xtesting regexp stuff:
  1229. Xx.m(".*X((...)...(...))", "12345Xabcxyzdef") returns 4
  1230. Xsubs matched = [0](15)"12345Xabcxyzdef"
  1231. X[1](9)"abcxyzdef"
  1232. X[2](3)"abc"
  1233. X[3](3)"def"
  1234. X
  1235. Xrst.m(rexp) returns 1
  1236. X
  1237. Xtesting grep:
  1238. Xx: 
  1239. X[0](4)"abcd"
  1240. X[1](5)"a2345"
  1241. X[2](5)"X2345"
  1242. X[3](6)"Xaaaaa"
  1243. X[4](5)"aaaaa"
  1244. X
  1245. Xgrep(^a.*)
  1246. XExpect 3 matches:
  1247. X[0](4)"abcd"
  1248. X[1](5)"a2345"
  1249. X[2](5)"aaaaa"
  1250. X
  1251. Xs1= (6)"abcdef", s1.m("^cde") : 0
  1252. Xs1= (6)"abcdef", s1.m("^..cde") : 1
  1253. Xsl = m("(..) (..)", "ab cd ef"); sl = 
  1254. X[0](2)"ab"
  1255. X[1](2)"cd"
  1256. X
  1257. Xs= (3)"ABC": s.m(ncr)= 1
  1258. Xs= (3)"ABC": s.m(cr)= 0
  1259. Xs.m("abc", "i")= 1
  1260. Xs.m("abc")= 0
  1261. Xtest string stuff:
  1262. XEmpty string: (0)"" length= 0,  strlen(s2) = 0
  1263. Xs1:(7)"string1"
  1264. Xs[0]= s, s[5]= g
  1265. Xconst char *s= s1: s= string1
  1266. Xs2=s1,  s2:(7)"string1"
  1267. Xs1.chop()(6)"string"
  1268. Xs3= s: s3 = (6)"string"
  1269. Xindex("ri") in (6)"string": 2
  1270. Xindex((1)"1") in (6)"string": -1
  1271. Xrindex(abc) in(9)"abcabcabc": 6
  1272. Xrindex(abc, 5) in(9)"abcabcabc": 3
  1273. Xsubstr(5, 3) in (9)"abcabcabc": (3)"cab"
  1274. Xs3.substr(5, 3) = "XXX"(9)"abcabXXXc"
  1275. Xs3.substr(5, 3) = s1(12)"abcabstringc"
  1276. Xs3.substr(5, 3) = s1.substr(1, 3)(12)"abcabtriingc"
  1277. Xs3.substr(0, 6) = s1.substr(0, 3)(9)"strriingc"
  1278. Xs3.substr(-3, 2) = s1.substr(0, 2)(9)"strriistc"
  1279. Xs1 = (10)"1234567890"
  1280. Xs1.substr(0, 10)= s1.substr(1, 9) (9)"234567890"
  1281. Xs1 = (10)"1234567890"
  1282. Xs1.substr(1, 9)= s1.substr(0, 10) (11)"11234567890"
  1283. Xs1.substr(7, 10)= "abcdefghij" (17)"1234567abcdefghij"
  1284. Xs1.substr(10, 5)= "abcdefghij" (20)"1234567890abcdefghij"
  1285. Xs1.substr(20, 1)= "abcdefghij" (20)"1234567890abcdefghij"
  1286. X(6)"abcdef" + (6)"123456": (12)"abcdef123456"
  1287. X(6)"abcdef" + "hello"= (11)"abcdefhello"
  1288. X"hello" + (6)"abcdef"= (11)"helloabcdef"
  1289. X(6)"abcdef" + 'x' = (7)"abcdefx"
  1290. X(3)"abc" == (3)"def": 0
  1291. X(3)"abc" != (3)"def": 1
  1292. X(3)"abc" == (3)"abc": 1
  1293. X(3)"abc" != (3)"abc": 0
  1294. X(3)"abc" < (3)"def": 1
  1295. X(3)"abc" > (3)"def": 0
  1296. X(3)"abc" <= (3)"def": 1
  1297. X(3)"abc" >= (3)"abc": 1
  1298. X(3)"abc" == abc:1
  1299. Xabc == (3)"abc"1
  1300. X(3)"abc" != abc:0
  1301. Xabc != (3)"abc"0
  1302. Xs1 = (9)"abcdefghi", s1.tr("ceg", "123") = 3, s1 = (9)"ab1d2f3hi"
  1303. Xs1.tr("a-z", "A-Z") = 9, s1 = (9)"ABCDEFGHI"
  1304. Xs1.tr("efg", "") = 3, s1 = (9)"abcdefghi"
  1305. Xs1.tr("ac-e", "X") = 4, s1 = (9)"XbXXXfghi"
  1306. Xs1 = (12)"abcdefghiiii", s1.tr("ac-e", "X", "s") = 4, s1 = (10)"XbXfghiiii"
  1307. Xs1.tr("ac-e", "", "d") = 4, s1 = (5)"bfghi"
  1308. Xs1.tr("ac-e", "d", "d") = 4, s1 = (6)"dbfghi"
  1309. Xs1.tr("ac-e", "", "cd") = 5, s1 = (4)"acde"
  1310. X(10)"bookkeeper": s1.tr("a-zA-Z", "", "s") = 10, s1 = (7)"bokeper"
  1311. X(15)"abc123def456ghi": s1.tr("a-zA-Z", " ", "c") = 6, s1 = (15)"abc   def   ghi"
  1312. X(21)"abc123def456ghi789aaa": s1.tr("a-zA-Z", " ", "cs") = 9, s1 = (15)"abc def ghi aaa"
  1313. X(12)"abcdddaaaxxx": s1.tr("a", "d", "s") = 4, s1 = (9)"dbcdddxxx"
  1314. X(9)"abcdefghi" s1.s("def", "FED") = 1, s1= (9)"abcFEDghi"
  1315. X(9)"abcDEFghi" s1.s("def", "FED") = 0, s1= (9)"abcDEFghi"
  1316. X(9)"abcDEFghi" s1.s("def", "FED", "i") = 1, s1= (9)"abcFEDghi"
  1317. X(9)"abcdefghi" s1.s("(...)(...)", "\$,$&,$2 $1") = 1, s1= (19)"$,abcdef,def abcghi"
  1318. X(15)"abcdefabcghiabc" s1.s("abc", "XabcX", "g") = 3, s1= (21)"XabcXdefXabcXghiXabcX"
  1319. X(15)"abcdefabcghiabc" s1.s("abc", "X", "g") = 3, s1= (9)"XdefXghiX"
  1320. X(15)"abcdefabcghiabc" s1.s("abc(.)", "X$1abcX$1", "g") = 2, s1= (21)"XdabcXdefXgabcXghiabc"
  1321. X(15)"abcdefabcghiabc" s1.s("(.)abc", "$1X$1abcX", "g") = 2, s1= (21)"abcdefXfabcXghiXiabcX"
  1322. X(10)"1234567890" s1.s("(.)(.)", "$2$1", "g") = 5, s1= (10)"2143658709"
  1323. END_OF_FILE
  1324.   if test 6620 -ne `wc -c <'splash.v'`; then
  1325.     echo shar: \"'splash.v'\" unpacked with wrong size!
  1326.   fi
  1327.   # end of 'splash.v'
  1328. fi
  1329. echo shar: End of archive 3 \(of 3\).
  1330. cp /dev/null ark3isdone
  1331. MISSING=""
  1332. for I in 1 2 3 ; do
  1333.     if test ! -f ark${I}isdone ; then
  1334.     MISSING="${MISSING} ${I}"
  1335.     fi
  1336. done
  1337. if test "${MISSING}" = "" ; then
  1338.     echo You have unpacked all 3 archives.
  1339.     rm -f ark[1-9]isdone
  1340. else
  1341.     echo You still must unpack the following archives:
  1342.     echo "        " ${MISSING}
  1343. fi
  1344. exit 0
  1345. exit 0 # Just in case...
  1346.