⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splash.cpp

📁 SPLASH is a c++ class library that implements many of the Perl constructs and data types, including
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	    rg= re.getgroup(0);
	    if(rg.end()+1 < length()){
		SPString st(substr(rg.end()+1));
//		cout << "Substring: " << st << endl;
		cnt += st.s(exp, repl, opts);
		substr(rg.end()+1)= st;
//		cout << "NewString: " << *this << endl;
	    }
	}	

	if(!strchr(repl, '$')){ // straight, simple substitution
	    rg= re.getgroup(0);
	    substr(rg.start(), rg.length())= repl;
	    cnt++;	
	}else{ // need to do subexpression substitution
	    char c;
	    const char *src= repl;
	    SPString dst;
	    int no;
	    while ((c = *src++) != '\0') {
		if(c == '$' && *src == '&'){
		    no = 0; src++;
		}else if(c == '$' && '0' <= *src && *src <= '9')
		    no = *src++ - '0';
		else no = -1;

		if(no < 0){	/* Ordinary character. */
		    if(c == '\\' && (*src == '\\' || *src == '$'))
			c = *src++;
		    dst += c;
		}else{
		    rg= re.getgroup(no);
		    dst += substr(rg.start(), rg.length());
		}
	    }
	    rg= re.getgroup(0);
	    substr(rg.start(), rg.length())= dst;
	    cnt++;
	}

	return cnt;
    }
    return cnt;
}

SPStringList SPString::split(const char *pat, int limit)
{
SPStringList l;

    l.split(*this, pat, limit);
    return l;
}

//************************************************************
// SPStringList stuff
//************************************************************

int SPStringList::split(const char *str, const char *pat, int limit)
{
Regexp re(pat);
Range rng;
SPString s(str);
int cnt= 1;
    
    if(*pat == '\0'){ // special empty string case splits entire thing
	while(*str){
	    s= *str++;
	    push(s);
	}
	return count();
    }

    if(strcmp(pat, "' '") == 0){ // special awk case
	char *p, *ws= " \t\n";
	TempString t(str); // can't hack users data
	p= strtok(t, ws);
	while(p){
	    push(p);
	    p= strtok(NULL, ws);
	}
	return count();
    }

    while(re.match(s) && (limit < 0 || cnt < limit)){ // find separator
	rng= re.getgroup(0); // full matched string (entire separator)
	push(s.substr(0, rng.start()));
	for(int i=1;i<re.groups();i++){
	    push(s.substr(re.getgroup(i))); // add subexpression matches
	}
	
	s= s.substr(rng.end()+1);
	cnt++;
    }
    if(s.length()) push(s);

    if(limit < 0){ // strip trailing null entries
	int off= count()-1;
	while(off >= 0 && (*this)[off].length() == 0){
	    off--;
	}
	splice(off+1);
    }
    return count();
}

SPString SPStringList::join(const char *pat)
{
SPString ts;

    for(int i=0;i<count();i++){
	ts += (*this)[i];
	if(i<count()-1) ts += pat;
    }
    return ts;
}


SPStringList::SPStringList(const SPStringList& n)
{
    for(int i=0;i<n.count();i++){
	push(n[i]);
    }
}

SPStringList& SPStringList::operator=(const SPList<SPString>& n)
{
    if(this == &n) return *this;
    // erase old one
    reset();
    
    for(int i=0;i<n.count();i++){
	push(n[i]);
    }
    return *this;
}

int SPStringList::m(const char *rege, const char *targ, const char *opts)
{
int iflg= strchr(opts, 'i') != NULL;
Regexp r(rege, iflg?Regexp::nocase:0);
    if(!r.match(targ)) return 0;
    Range rng;
    for (int i=0; i<r.groups(); i++){
        rng= r.getgroup(i);
	push(SPString(targ).substr(rng.start(), rng.length()));
    }
    return r.groups();
}

SPStringList SPStringList::grep(const char *rege, const char *opts)
{
SPStringList rt;
int iflg= strchr(opts, 'i') != NULL;

    Regexp rexp(rege, iflg?Regexp::nocase:0);    // compile once
    for(int i=0;i<count();i++){
    	if(rexp.match((*this)[i])){
	    rt.push((*this)[i]);
	}
    }
    return rt;
}

#if 1
SPStringList m(const char *pat, const char *str, const char *opts)
{
SPStringList l;
    l.m(pat, str, opts);
    l.shift(); // remove the first element which would be $&
    return l;
}
#endif
//************************************************************
// streams stuff
//************************************************************

istream& operator>>(istream& ifs, SPString& s)
{
char c;
#if 0
char buf[40];
#else
char buf[132];
#endif

    s= ""; // empty string
    ifs.get(buf, sizeof buf); 
    // This is tricky because a line teminated by end of file that is not terminated
    // with a '\n' first is considered an OK line, but ifs.good() will fail.
    // This will correctly return the last line if it is terminated by eof with the
    // stream still in a non-fail condition, but at eof, so next call will fail as
    // expected
    if(ifs){ 		// previous operation was ok
        s += buf; 	// append buffer to string
//	cout << "<" << buf << ">" << endl;
	// if its a long line continue appending to string
	while(ifs.good() && (c=ifs.get()) != '\n'){
//	    cout << "eof1= " << ifs.eof() << endl;
	    ifs.putback(c);
//          cout << "eof2= " << ifs.eof() << endl;
	    if(ifs.get(buf, sizeof buf)) s += buf; // append to line
	}
    }
    return ifs;    
}

istream& operator>>(istream& ifs, SPStringList& sl)
{
SPString s;

    // Should I reset sl first?
    sl.reset(); // I think so, to be consistent
    
    while(ifs >> s){
	sl.push(s);
//	cout << "<" << s << ">" << endl;
    };
    return ifs;    
}

ostream& operator<<(ostream& os,  const SPString& arr)
{
#ifdef TEST
    os << "(" << arr.length() << ")" << "\"";
    os << (const char *)arr;
    os << "\"";
#else
    os << (const char *)arr;
#endif
    return os;   
}

ostream& operator<<(ostream& os,  const SPStringList& arr)
{

    for(int i=0;i<arr.count();i++)
#ifdef TEST
	os << "[" << i << "]" << arr[i] << endl;
#else	 
	os << arr[i] << endl; 
#endif	 
    return os;   
}

//************************************************************
// Slice stuff
//************************************************************

// a..b is range a thru b
// a-b is also range a thru b
// a,b,c is a and b and c
Slice::Slice(const char *s)
{
SPStringList sl;
SPString sep;
int i1, i2;

    rl= new SPList<Range>;
    sl.split(s, "([-,]|\\.\\.)"); // split on separators and save them
//    cout << sl << endl;
    
    while(sl){
	i1= atoi(sl.shift()); // +++ should check it is a valid number	    	
        if(sl){
	    sep= sl.shift(); // get separator
            if(sep == "-" || sep == ".."){ // its a range
		if(sl.isempty()){ // check there is more
                    cerr << "\nError in Slice, bad range in string: " << s << endl;
		    return;                         
                }
		i2= atoi(sl.shift()); // +++ get end of range
                rl->push(Range(i1, i2)); // +++ Should see if range is reversed, or contiguous
                if(sl && (sep=sl.shift()) != ","){
                    cerr << "\nError in Slice, Range not terminated correctly in string: "
                         << s << " by: " << sep << endl;
                }
            }else if(sep == ","){ // its a single
		add(i1);
            }else{ // oops
            	cerr << "\nError in Slice, bad separator in string: " << s
		     << "at: " << sep << endl;
                return;
            }
        }else add(i1); // last one must be a single
    }
    cout << *this << endl;
}

void Slice::add(int i)
{
int n= rl->count()-1;
    // if and only if this index is one greater than the previous on
    if(n >= 0 && (*rl)[n].end() == i-1){ // extend end of range by 1
	((*rl)[n])++;
    }else rl->push(Range(i, i));
}

// a list of at least one indices, terminated by -1
Slice::Slice(int n, ...)
{
va_list ap;
int arg;
va_start(ap, n);

    rl= new SPList<Range>;
    add(n);
    while((arg=va_arg(ap, int)) >= 0){
	add(arg);
    }
    va_end(ap);
}

ostream& operator<<(ostream& os, const Slice& sl)
{
    for(int i=0;i<sl.rl->count();i++){
        os << (*sl.rl)[i] << endl;
    }
    return os;
}

#ifdef __TURBOC__
int Regexp::groups(void) const
{
    int res= 0;
    for (int i=0; i<NSUBEXP; i++) {
	if(repat->startp[i] == NULL) break;
	res++;
    }
    return res;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -