/* WebDownloader for X-Window
* Copyright (C) 1999-2002 Koshelev Maxim
* This Program is free but not GPL!!! You can't modify it
* without agreement with author. You can't distribute modified
* program but you can distribute unmodified program.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include "autoadd.h"
#include "dbc.h"
#include "locstr.h"
struct d4xAASubStr:tNode{
int type;
int left_int,right_int,cur_int,int_len;
char *left_str,*right_str,*cur_str;
int str_len;
int end_flag;
int period;
d4xAASubStr();
void print();
char *first();
char *next();
char *last();
char *scan(char *str);
~d4xAASubStr();
private:
char *last_str;
int sub_scan(char **cur);
void next_str();
void set_last(char *str);
};
enum D4X_AUTO_ADD_ENUM{
DAA_STR,
DAA_INT_INT,
DAA_STR_STR,
DAA_STRS,
DAA_UNKNOWN
};
/******************************************************************/
d4xAASubStr::d4xAASubStr(){
type=DAA_UNKNOWN;
period=1;
left_int=right_int=cur_int=int_len=0;
left_str=right_str=cur_str=NULL;
last_str=NULL;
};
char *d4xAASubStr::last(){
return(copy_string(last_str));
};
void d4xAASubStr::set_last(char *a){
if (last_str) delete[] last_str;
last_str=copy_string(a);
};
void d4xAASubStr::print(){
switch(type){
case DAA_STR:
printf("%s",left_str);
break;
case DAA_INT_INT:
printf("%i - %i",left_int,right_int);
break;
case DAA_STR_STR:
printf("%s - %s",left_str,right_str);
break;
case DAA_STRS:{
char *cur=left_str;
for (int i=0;i<left_int;i++){
printf("%s",cur);
cur+=strlen(cur)+1;
};
break;
};
};
if (period)
printf(" / %i",period);
printf("\n");
};
static char *str_skip_digits_or_(char *cur,char orwhat){
while(*cur){
if (!isdigit(*cur) && *cur!=orwhat)
break;
cur++;
};
return(cur);
};
int d4xAASubStr::sub_scan(char **cur){
switch (**cur){
case '}':
break;
case '/':{
*cur+=1;
if (sscanf(*cur,"%i",&period)!=1 || period<=1)
return(1);
*cur=str_skip_digits_or_(*cur,0);
if (**cur!='}') return(1);
break;
};
default:
return(1);
};
return(0);
};
char *d4xAASubStr::scan(char *str){
DBC_RETVAL_IF_FAIL(str!=NULL,str);
char *cur=str;
if (*cur!='{' && *cur!='['){
type=DAA_STR;
while(*cur && *cur!='{' && *cur!='[')
cur++;
int len=cur-str;
left_str=new char[len+1];
memcpy(left_str,str,len);
left_str[len]=0;
return(cur);
};
if (*cur=='['){
cur+=1;
if (*cur=='['){
type=DAA_STR;
left_str=new char[2];
left_str[0]='[';
left_str[1]=0;
return(cur+1);
};
char *end=index(cur,']');
if (end==NULL || end==cur || *cur==',')
return(str);
str_len=end-cur;
left_str=new char[str_len+1];
memcpy(left_str,cur,str_len);
left_str[str_len]=0;
cur=left_str;
left_int=1;
while (*cur){
if (*cur==','){
*cur=0;
left_int+=1;
};
cur+=1;
};
type=DAA_STRS;
return(end+1);
};
cur+=1;
if (*cur=='{'){
type=DAA_STR;
left_str=new char[2];
left_str[0]='{';
left_str[1]=0;
return(cur+1);
};
if (sscanf(cur,"%u-%u",&left_int,&right_int)==2){
char a[100];
sprintf(a,"%i-%i",left_int,right_int);
if (!begin_string(cur,a)){
char *b=index(cur,'-');
if (b)
int_len=b-cur;
else
int_len=0;
};
cur=str_skip_digits_or_(cur,'-');
if (sub_scan(&cur)) return(str);
type=DAA_INT_INT;
return(cur+1);
};
char *end=index_mult(cur,"}/");
if (end){
char *tmp=cur;
for (tmp=cur;tmp<end;tmp++)
if (*tmp=='-') break;
if (*tmp!='-') return(str);
if (tmp-cur!=end-tmp-1) return(str);
str_len=tmp-cur;
type=DAA_STR_STR;
left_str=new char[str_len+1];
right_str=new char[str_len+1];
memcpy(left_str,cur,str_len);
memcpy(right_str,tmp+1,str_len);
left_str[str_len]=right_str[str_len]=0;
if (sub_scan(&end)) return(str);
return(end+1);
};
return(str);
};
char *d4xAASubStr::first(){
end_flag=0;
if (type==DAA_STR){
end_flag=1;
set_last(left_str);
return(copy_string(left_str));
};
if (type==DAA_INT_INT){
cur_int=left_int;
char tmp[100];
if (int_len){
char a[100];
sprintf(a,"%%0%ii",int_len);
sprintf(tmp,a,cur_int);
}else
sprintf(tmp,"%i",cur_int);
set_last(tmp);
return(copy_string(tmp));
};
if (type==DAA_STR_STR){
set_last(left_str);
cur_str=copy_string(left_str);
return(copy_string(left_str));
};
if (type==DAA_STRS){
cur_int=0;
set_last(left_str);
return(copy_string(left_str));
};
return(NULL);
};
void d4xAASubStr::next_str(){
for (int per=0;per<period;per++){
for(int i=0;i<str_len;i++){
if (cur_str[i]!=right_str[i]){
cur_str[i]+=cur_str[i]>right_str[i]?-1:1;
break;
};
if (cur_str[i]==right_str[i])
cur_str[i]=left_str[i];
};
if (strcmp(cur_str,right_str)==0) break;
};
};
char *d4xAASubStr::next(){
if (type==DAA_STR){
end_flag=1;
set_last(left_str);
return(copy_string(left_str));
};
if (type==DAA_INT_INT){
if (cur_int!=right_int){
for (int per=0;per<period && cur_int!=right_int;per++)
cur_int+=right_int<cur_int?-1:1;
}else{
end_flag=1;
};
char tmp[100];
if (int_len){
char a[100];
sprintf(a,"%%0%ii",int_len);
sprintf(tmp,a,cur_int);
}else
sprintf(tmp,"%i",cur_int);
set_last(tmp);
return(copy_string(tmp));
};
if (type==DAA_STR_STR){
if (strcmp(cur_str,right_str)!=0){
next_str();
}else
end_flag=1;
set_last(cur_str);
return(copy_string(cur_str));
};
if (type==DAA_STRS){
char *rval=left_str;
if (cur_int+1>=left_int){
end_flag=1;
}else{
cur_int+=1;
};
for (int i=0;i<cur_int;i++){
rval+=strlen(rval)+1;
};
set_last(rval);
return(copy_string(rval));
};
return(NULL);
};
d4xAASubStr::~d4xAASubStr(){
if (left_str) delete[] left_str;
if (right_str) delete[] right_str;
if (cur_str) delete[] cur_str;
if (last_str) delete[] last_str;
};
/******************************************************************/
d4xAutoGenerator::d4xAutoGenerator(){
// do nothing
};
int d4xAutoGenerator::init(char *str){
char *cur=str;
while(*cur){
d4xAASubStr *tmp=new d4xAASubStr;
char *a=tmp->scan(cur);
if (a==cur){
delete(tmp);
return(1);
};
list.insert(tmp);
cur=a;
};
// print();
return(0);
};
char *d4xAutoGenerator::first(){
d4xAASubStr *tmp=(d4xAASubStr *)list.first();
if (tmp==NULL) return(NULL);
char *rval=tmp->first();
tmp=(d4xAASubStr *)(tmp->prev);
while(tmp){
char *a=tmp->first();
char *b=sum_strings(rval,a,NULL);
delete[] rval;
delete[] a;
rval=b;
tmp=(d4xAASubStr *)(tmp->prev);
};
return(rval);
};
char *d4xAutoGenerator::next(){
d4xAASubStr *tmp=(d4xAASubStr *)list.first();
if (tmp==NULL) return(NULL);
char *rval=NULL;
int end_flag=0;
int last=0;
if (tmp->end_flag){
end_flag=1;
last=1;
rval=tmp->first();
}else{
rval=tmp->next();
};
tmp=(d4xAASubStr *)(tmp->prev);
int flast=1;
while(tmp){
char *a=NULL;
if (last && flast){
if (tmp->end_flag){
last=1;
a=tmp->first();
}else{
flast=0;
a=tmp->next();
};
}else{
a=tmp->last();
};
char *b=sum_strings(rval,a,NULL);
delete[] rval;
delete[] a;
rval=b;
if (tmp->end_flag && tmp->prev==NULL && flast) end_flag=1;
else end_flag=0;
tmp=(d4xAASubStr *)(tmp->prev);
};
if (end_flag){
delete[] rval;
rval=NULL;
};
return(rval);
};
void d4xAutoGenerator::print(){
d4xAASubStr *tmp=(d4xAASubStr *)list.first();
while(tmp){
tmp->print();
tmp=(d4xAASubStr *)(tmp->prev);
};
};
d4xAutoGenerator::~d4xAutoGenerator(){
//do nothing?
};
syntax highlighted by Code2HTML, v. 0.9.1