home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_11_11
/
splash
/
readme.2nd
< prev
next >
Wrap
Text File
|
1993-01-15
|
8KB
|
244 lines
For support Email to morris@netcom.com or jegm@sgi.com
I would welcome bug reports for a while!
Also comments are always welcome.
The latest version of SPLASH is always available via anonymous
FTP from netcom.com in ~ftp/pub/morris/splash.tar.Z (for Unix)
and ~ftp/pub/morris/splash.zoo (for MSDOS)
Introducing SPLASH
==================
SPLASH is a c++ class library that implements my favourite perl
constructs. Obviously I can't duplicate all the functionality of perl,
and wouldn't need to as perl already exists!! However I find this
useful, because it allows me to do Perl-like things in my programs.
This Code is not copyright, use as you will. The regexp code is by
Henry Spencer, see the comments for Copyright info. The only changes I
have made are to the header file, by adding a c++ prototype field.
The Class Hierarchy and member functions are are fully described in
the file splash.doc
Building NOTES
==============
This must be compiled with a 3.0 or greater c++ compiler that can
handle Templates and nested classes.
It has been tested on Borland c++ v3.1 and USL-based 3.0. GCC v2.2.2
doesn't like the Copy constructor syntax in template classes, and gives
an assert error as well.
To build:
compile splash.c++ and regex.c. Link in with your App.
Include splash.h, (and assoc.h if used).
> cc -c regex.c
> CC -c splash.c++
> CC yourapp.c++ splash.o regex.o -o yourapp
To test:
> CC -DTEST spltest.c++ splash.c++ regex.o -o spltest
> spltest > x
> diff x splash.v
and
> CC -DTEST slicetst.c++ splash.o regex.o -o slicetst
> slicetst > x
> diff x slicetst.v
This will do a full regression test. splash.v & slicetst.v contains the
sample output of a correct run, so no differences should be
encountered.
regex.c is not an ANSI c file, so you will have to turn off prototype
checking on your ANSI c compiler (or select kr checking).
Some of the samples use a file called tracer.h, this is a fairly useful
Debugging helper grabbed from the net and slightly modified. I include
tracer.h and tracer.c++ for completeness, however they are not required.
CAVEATS (known ones that is)
=======
This is not an optimised implementation, by any stretch of the
imagination. It is a quick and dirty, "but it works" one.
No "out of memory checking" is done, I thought I'd wait for
exceptions!!
I have taken a few liberties in translating the selected perl
functionality into a class library, apologies to Larry Wall, and
anyone else this may offend. You are welcome to fix it, just tell me
how you did it.
A SPList<T> can only contain a list of type T, it cannot, as yet,
have multiple types in the same list. (This is feasible but messy).
Assigning to an element of a SPList that is greater than the current
length of the SPList will expand the list as in perl, but the values
in the newly created elements will be undefined, unlike perl. Except
SPStringList which will create empty strings. Also if <T> is a class
then the values will be whatever the default constructor creates.
Anything that you make a SPList out of must define an operator<(),
for the sort routine. Its ok if it is a dummy.
The first index of a list is always 0. (Again this could be fixed).
Unlike perl you can also access characters within
a SPString using the '[]' syntax. But you must use substr() to
change them.
Note that SPStrings cannot have embedded '\0' like perl, this
is an efficiency trade off, because '\0' as a terminator is so
ingrained in c++ and c strings. (This could be fixed by carefully
replacing all str... functions with mem... functions
Regular Expressions
-------------------
Regular expressions may be slightly different, I used the straight
Henry Spencer version. I'm not sure what changes Larry made to them.
(It definitely doesn't support \w \b \s \S \d \D, or global match
mode). - If someone can make Larry's regexp stuff into a stand-alone
package like the original regex stuff, then I'll use it!
The g & o options are not supported in the m() functions.
I will try to support the 'g' option for m() in a list context.
SPStringList::m(exp, targ) and SPString::m(exp, list) are used to
simulate $&, $0 - $9 in perl. In both cases the list gets loaded with
the subexpression matches. The 0'th element is equivalent to $& in perl
and the 1'st element is equivalent to $1 etc.
Note that in the SPStringlist::m() member function, result lists are
appended whereas in SPString::m(s, list) 'list' is reset first.
eg
{
SPString s;
SPStringList l1, l2;
s= "hello frobo goodbye";
l1.push("was here first1"); l2.push("was here first2");
s.m("(.*)frobo(.*)", l2); // Overwrites l with new list
l1.m("(.*)frobo(.*)", s); // appends l with new list
// produces this result:
// l2[0] is "hello frobo goodbye" // equiv of $&
// l2[1] is "hello " // equiv of $1
// l2[2] is " goodbye" // $2
// and
// l1[0] is "was here first"
// l1[1] is "hello frobo goodbye" // equiv of $&
// l1[2] is "hello " // $1
// l1[3] is " goodbye" // $2
// an l1.reset() preceding the l1.m() would get rid of l1[0] in the
// above example.
}
To get the exact perl semantics of the m function in a list context
you can use the global m() function as follows:-
{
SPStringList sl;
sl = m("(..) (..)", "ab cd ef"); // sl[0] gets "ab", sl[1] gets "cd"
}
SP expressions (s/123/$&*2/e) in a substitute command
(SPString::s()) are obviously not done. However $& and $0-$9 are
correctly expanded and substituted.
Also remember that if you want to put a \ in the regular expression
then you must actually type \\ as the c compiler will interpret a \ for
you. What happens to things like \t is up to your compiler.
I/O
---
I/O is done using standard c++ streams. I think this is ok, although
some perl-ism maybe introduced one day.
eg to copy a text file a line at a time:-
{
ifstream fin("file1.txt");
ofstream fout("file2.txt");
SPString si;
while(fin >> si) fout << si << endl;
}
This will read the entire file into a SPStringList:-
{
SPStringList l;
ifstream fin("file1.txt");
fin >> l;
}
One nifty outcome of using streams this way is the following syntax
will load a SPStringList and SPList<T> in a reasonably compact
way:-
{
SPStringList slist;
strstream ss;
ss << "one\n" << "two\nthree\nfour\n";
ss >> slist; // creates a 4 element string list
strstream iss;
SPList<int> il;
iss << "1 2 3 4 5 6 7 8 9 10" << endl; // quick load an integer array
iss >> il; // creates a 10 element integer list
}
Iterators
---------
There is no iterator per-se, but all lists (including Assoc) allow
an index to step through the list one by one. So iteration can be
achieved, albeit clumsily.
eg
SPList<int> intlist;
for(int i=0;i<inlist.scalar();i++){
cout << intlist[i];
}
foreach could be simulated with the following macro:-
#define FOREACH(var, array)\
for(int i=0;i<array.scalar() && (var=array[i], 1);i++)
eg
{
SPList<int> fred;
int val, tot= 0;
{ // this is useful to avoid the 'i' in the macro colliding
FOREACH(val, fred){
tot += val;
}
}
}
A SPList or SPStringList may be used in an if statement to test
if the list is empty or not.
eg
{
SPList<int> il;
if(il) cout << "List is not empty" << endl;
else il.push(1);
}
==========
Disclaimer
==========
This is a personal work, and SGI is not responsible for anything
contained herein.