libburn/libcevap/cgen.c

1504 lines
37 KiB
C

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include "smem.h"
char *Sfile_fgets();
int Sregex_string();
int Sregex_trimline();
#include "ctyp.h"
#include "cgen.h"
/* ----------------------------- CgeN ------------------------- */
int Cgen_new(cgen,flag)
struct CgeN **cgen;
int flag;
{
int ret;
struct CgeN *c;
*cgen= c= TSOB_FELD(struct CgeN,1);
if(c==NULL) {
fprintf(stderr,"+++ Cannot create cgen object : %s\n",strerror(errno));
return(-1);
}
c->classname= NULL;
c->structname= NULL;
c->functname= NULL;
c->is_managed_list= 0;
c->is_bossless_list= 0;
c->gen_for_stic= 1;
c->make_ansi= 0;
c->make_lowercase= 0;
c->global_include_file[0]= 0;
c->global_include_fp= NULL;
c->elements= NULL;
c->last_element= NULL;
c->may_overwrite= 0;
c->fp= NULL;
c->filename[0]= 0;
c->ptt_fp= NULL;
c->ptt_filename[0]= 0;
c->msg[0]= 0;
return(1);
}
int Cgen_destroy(cgen,flag)
struct CgeN **cgen;
int flag;
{
struct CgeN *c;
struct CtyP *ct,*next_ct;
c= *cgen;
if(c==NULL)
return(0);
if(c->fp!=NULL)
fclose(c->fp);
if(c->ptt_fp!=NULL)
fclose(c->ptt_fp);
Sregex_string(&(c->classname),NULL,0);
Sregex_string(&(c->structname),NULL,0);
Sregex_string(&(c->functname),NULL,0);
for(ct= c->elements; ct!=NULL; ct= next_ct) {
next_ct= ct->next;
Ctyp_destroy(&ct,0);
}
free((char *) c);
*cgen= NULL;
return(1);
}
int Cgen_make_names(cgen,flag)
struct CgeN *cgen;
int flag;
{
int l;
if(Sregex_string(&(cgen->structname),cgen->classname,0)<=0)
return(-1);
if(Sregex_string(&(cgen->functname),cgen->classname,0)<=0)
return(-1);
if(!cgen->make_lowercase) {
cgen->structname[0]= toupper(cgen->structname[0]);
l= strlen(cgen->structname);
cgen->structname[l-1]= toupper(cgen->structname[l-1]);
cgen->functname[0]= toupper(cgen->functname[0]);
}
return(1);
}
int Cgen_read_fp(cgen,fp,flag)
struct CgeN *cgen;
FILE *fp;
int flag;
/*
bit0= return 0 if eof at classname
*/
{
char line[4096],*cpt,*bpt;
int ret;
line[0]= 0;
while(1) {
printf("[-list] classname ?\n");
if(Sfile_fgets(line,sizeof(line)-1,fp)==NULL) {
if(!(flag&1))
return(2);
no_name:;
sprintf(cgen->msg,"No classname given.");
return(0);
}
printf("%s\n",line);
if(strcmp(line,"@@@")==0)
return(2);
if(line[0]==0 || line[0]=='#') {
/* >>> record class comments */;
} else
break;
}
cpt= line;
while(cpt[0]=='-') {
/* look for management specifiers:
-l* listable by prev-next chain
*/
if(cpt[1]=='l' || cpt[1]=='L') {
cgen->is_managed_list= 1;
} else if(cpt[1]=='b' || cpt[1]=='B') {
cgen->is_bossless_list= 1;
}
while(*cpt!=0 && !isspace(*cpt)) cpt++;
while(*cpt!=0 && isspace(*cpt)) cpt++;
if(*cpt==0)
goto no_name;
}
if(Sregex_string(&(cgen->classname),cpt,0)<=0)
return(-1);
ret= Cgen_make_names(cgen,0);
if(ret<=0)
return(ret);
while(1) {
ret= Ctyp_read_fp(&(cgen->last_element),fp,cgen->msg,
!!cgen->make_lowercase);
if(ret<=0)
return(ret);
if(ret==2)
break;
if(cgen->elements==NULL)
cgen->elements= cgen->last_element;
}
if(cgen->is_managed_list) {
sprintf(line,"-c struct %s *prev",cgen->structname);
ret= Ctyp_new_from_line(&(cgen->last_element),cgen->last_element,
line,cgen->msg,0);
if(ret<=0)
return(ret);
if(cgen->elements==NULL)
cgen->elements= cgen->last_element;
sprintf(line,"-c struct %s *next",cgen->structname);
ret= Ctyp_new_from_line(&(cgen->last_element),cgen->last_element,
line,cgen->msg,0);
if(ret<=0)
return(ret);
}
return(1);
}
int Cgen_open_wfile(cgen,flag)
struct CgeN *cgen;
int flag;
/*
bit0-3: modes
0= open cgen->fp
1= open cgen->ptt_fp
2= open cgen->global_include_fp
*/
{
struct stat stbuf;
int ret, mode;
char *name, fmode[4];
FILE *fp;
mode= flag&15;
strcpy(fmode,"w");
if(mode==0) {
name= cgen->filename;
fp= cgen->fp;
cgen->fp= NULL;
} else if(mode==1) {
name= cgen->ptt_filename;
fp= cgen->ptt_fp;
cgen->ptt_fp= NULL;
} else if(mode==2) {
strcpy(fmode,"a");
name= cgen->global_include_file;
fp= cgen->global_include_fp;
cgen->global_include_fp= NULL;
} else {
fprintf(stderr,"+++ Cgen_open_wfile : program error : unknown mode %d\n",
mode);
ret= -1; goto ex;
}
if(fmode[0]=='w' && stat(name,&stbuf)!=-1 && !cgen->may_overwrite) {
sprintf(cgen->msg,"File '%s' already existing.",name);
ret= 0; goto ex;
}
if(fp!=NULL)
{fclose(fp); fp= NULL;}
fp= fopen(name,fmode);
if(fp==NULL) {
sprintf(cgen->msg,"Cannot open file '%s' in %s-mode. %s",
name,fmode,strerror(errno));
ret= 0; goto ex;
}
ret= 1;
ex:;
if(mode==0)
cgen->fp= fp;
else if(mode==1)
cgen->ptt_fp= fp;
else if(mode==2)
cgen->global_include_fp= fp;
return(ret);
}
int Cgen_write_datestr(cgen,flag)
struct CgeN *cgen;
int flag;
/*
bit0= operate on ptt (= ANSI prototype) file rather than on internal header
*/
{
time_t t0;
char timetext[81];
FILE *fp;
if(flag&1)
fp= cgen->ptt_fp;
else
fp= cgen->fp;
t0= time(0);
strftime(timetext,sizeof(timetext),"%a, %d %b %Y %H:%M:%S GMT",
gmtime(&t0));
fprintf(fp,"/* ( derived from stub generated by CgeN on %s ) */\n",
timetext);
return(1);
}
int Cgen_write_h(cgen,flag)
struct CgeN *cgen;
int flag;
{
int ret,i,pointer_level;
FILE *fp= NULL;
struct CtyP *ct;
char pvt[16],macro_name[4096],*cpt;
if(cgen->make_ansi) {
sprintf(cgen->filename,"%s_private.h",cgen->classname);
strcpy(pvt,"_private");
} else {
sprintf(cgen->filename,"%s.h",cgen->classname);
strcpy(pvt,"");
}
ret= Cgen_open_wfile(cgen,0);
if(ret<=0)
goto ex;
sprintf(macro_name,"%s%s_includeD",cgen->functname,pvt);
macro_name[0]= toupper(macro_name[0]);
fp= cgen->fp;
/* >>> print class comments */;
fprintf(fp,"\n");
fprintf(fp,"#ifndef %s\n",macro_name);
fprintf(fp,"#define %s\n",macro_name);
fprintf(fp,"\n");
if(strlen(cgen->global_include_file)!=0) {
fprintf(fp,"#include \"%s\"\n",cgen->global_include_file);
fprintf(fp,"\n\n");
}
if(cgen->make_ansi)
fprintf(fp,"/* For function prototypes see file %s.h */\n",cgen->classname);
fprintf(fp,"\n\n");
fprintf(fp,"struct %s {\n",cgen->structname);
fprintf(fp,"\n");
ct= cgen->elements;
for(ct= cgen->elements;ct!=NULL;ct= ct->next) {
if(ct->is_comment) {
if(ct->name[0]==0) {
fprintf(fp,"\n");
continue;
}
fprintf(fp," /* ");
for(cpt= ct->name; *cpt!=0; cpt++) {
fprintf(fp,"%c",*cpt);
if(cpt[0]=='*' && cpt[1]=='/')
fprintf(fp," ");
}
fprintf(fp," */\n");
continue;
}
if(ct->is_volatile)
fprintf(fp," volatile");
if(Ctyp_is_struct(ct,0))
fprintf(fp," struct");
else if(ct->is_unsigned)
fprintf(fp," unsigned");
fprintf(fp," %s ",ct->dtype);
pointer_level= Ctyp_get_pointer_level(ct,0);
for(i=0;i<pointer_level;i++)
fprintf(fp,"*");
fprintf(fp,"%s",ct->name);
if(ct->array_size>0)
fprintf(fp,"[%lu]",ct->array_size);
fprintf(fp,";\n");
}
fprintf(fp,"\n");
fprintf(fp,"};\n");
fprintf(fp,"\n");
fprintf(fp,"\n");
fprintf(fp,"#endif /* %s */\n",macro_name);
fprintf(fp,"\n");
Cgen_write_datestr(cgen,0);
/* Eventually write start of ANSI prototype include file */
if(!cgen->make_ansi)
goto after_ansi_h;
sprintf(cgen->ptt_filename,"%s.h",cgen->classname);
ret= Cgen_open_wfile(cgen,1);
if(ret<=0)
goto ex;
sprintf(macro_name,"%s_includeD",cgen->functname);
macro_name[0]= toupper(macro_name[0]);
fp= cgen->ptt_fp;
/* >>> print class comments */;
fprintf(fp,"\n");
fprintf(fp,"#ifndef %s\n",macro_name);
fprintf(fp,"#define %s\n",macro_name);
fprintf(fp,"\n\n");
if(strlen(cgen->global_include_file)!=0) {
fprintf(fp,"#include \"%s\"\n",cgen->global_include_file);
} else {
fprintf(fp,"struct %s;\n",cgen->structname);
}
fprintf(fp,"\n\n");
fprintf(fp,"/* For inner details see file %s_private.h */\n",cgen->classname);
fprintf(fp,"\n\n");
after_ansi_h:;
if(strlen(cgen->global_include_file)==0)
goto after_global_include;
ret= Cgen_open_wfile(cgen,2);
if(ret<=0)
goto ex;
fprintf(cgen->global_include_fp,"struct %s;\n",cgen->structname);
after_global_include:;
ret= 1;
ex:;
if(cgen->fp!=NULL)
{fclose(cgen->fp); cgen->fp= NULL;}
/* ( note: cgen->ptt_fp stays open ) */
if(cgen->global_include_fp!=NULL)
{fclose(cgen->global_include_fp); cgen->global_include_fp= NULL;}
return(ret);
}
int Cgen_write_to_ptt(cgen,ptt,flag)
struct CgeN *cgen;
char *ptt;
int flag;
{
if(cgen->ptt_fp==NULL)
return(-1);
fprintf(cgen->ptt_fp,"%s;\n",ptt);
return(1);
}
int Cgen_finish_public_h(cgen,flag)
struct CgeN *cgen;
int flag;
{
char macro_name[4096];
if(cgen->ptt_fp==NULL)
return(-1);
fprintf(cgen->ptt_fp,"\n");
fprintf(cgen->ptt_fp,"\n");
sprintf(macro_name,"%s_includeD",cgen->functname);
macro_name[0]= toupper(macro_name[0]);
fprintf(cgen->ptt_fp,"#endif /* %s */\n",macro_name);
fprintf(cgen->ptt_fp,"\n");
Cgen_write_datestr(cgen,1);
if(cgen->ptt_fp!=NULL)
{fclose(cgen->ptt_fp); cgen->ptt_fp= NULL;}
return(1);
}
int Cgen_write_c_head(cgen,flag)
struct CgeN *cgen;
int flag;
{
int ret,is_pointer,is_struct,array_size;
FILE *fp= NULL;
struct CtyP *ct,*hct;
char *dtype= NULL,*name= NULL;
fp= cgen->fp;
fprintf(fp,"\n");
fprintf(fp,"/*\n");
fprintf(fp," cc -g -c %s.c\n",cgen->classname);
fprintf(fp,"*/\n");
Cgen_write_datestr(cgen,0);
fprintf(fp,"\n");
fprintf(fp,"#include <sys/types.h>\n");
fprintf(fp,"#include <stdlib.h>\n");
fprintf(fp,"#include <stdio.h>\n");
fprintf(fp,"#include <string.h>\n");
fprintf(fp,"#include <errno.h>\n");
fprintf(fp,"\n");
fprintf(fp,"#include \"%s.h\"\n",cgen->classname);
if(cgen->make_ansi) {
fprintf(fp,"#include \"%s_private.h\"\n",cgen->classname);
}
fprintf(fp,"\n");
for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
if(ct->is_comment)
continue;
Ctyp_get_dtype(ct,&dtype,0);
Ctyp_get_type_mod(ct,&is_pointer,&is_struct,&array_size,0);
/*
fprintf(stderr,"DEBUG: %s %s\n",(is_struct?"struct ":""),dtype);
*/
/* already included ? */
if(strcmp(dtype,cgen->structname)==0)
continue;
for(hct= cgen->elements; hct!=NULL && hct!=ct; hct= hct->next) {
if(hct->is_comment)
continue;
if(hct->dtype!=NULL)
if(strcmp(hct->dtype,dtype)==0)
break;
}
if(hct!=ct && hct!=NULL)
continue;
if(is_struct && (isupper(dtype[0]) && isupper(dtype[strlen(dtype)-1]))) {
dtype[0]= tolower(dtype[0]);
dtype[strlen(dtype)-1]= tolower(dtype[strlen(dtype)-1]);
fprintf(fp,"#include \"%s.h\"\n",dtype);
}
}
fprintf(fp,"\n");
if(cgen->gen_for_stic==1) {
fprintf(fp,"#include \"../s_tools/smem.h\"\n");
fprintf(fp,"#include \"../s_tools/sfile.h\"\n");
fprintf(fp,"#include \"../s_tools/sregex.h\"\n");
fprintf(fp,"\n");
} else if(cgen->gen_for_stic==2) {
fprintf(fp,"#include \"smem.h\"\n");
fprintf(fp,"\n");
}
fprintf(fp,"\n");
fprintf(fp,"/* -------------------------- %s ----------------------- */\n",
cgen->structname);
fprintf(fp,"\n");
if(dtype!=NULL)
Sregex_string(&dtype,NULL,0);
if(name!=NULL)
Sregex_string(&name,NULL,0);
return(1);
}
int Cgen_write_c_new(cgen,flag)
struct CgeN *cgen;
int flag;
{
int ret,pointer_level,management,boss_parm= 0;
unsigned long array_size;
FILE *fp= NULL;
struct CtyP *ct;
char ptt[4096];
fp= cgen->fp;
if(!cgen->is_bossless_list) {
if(cgen->elements!=NULL)
if(strcmp(cgen->elements->name,"boss")==0 && cgen->elements->is_struct &&
cgen->elements->is_pointer==1 && cgen->elements->no_initializer==0)
boss_parm= 1;
if(cgen->is_managed_list && boss_parm==0)
fprintf(stderr,
"+++ Warning: -l %s without -v struct ... *boss as first attribute\n",
cgen->classname);
}
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt,"int %s_new(struct %s **objpt, ",
cgen->functname,cgen->structname);
if(boss_parm)
sprintf(ptt+strlen(ptt),"struct %s *boss, ",cgen->elements->dtype);
sprintf(ptt+strlen(ptt),"int flag)");
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_new(objpt,\n",cgen->functname);
if(boss_parm)
fprintf(fp,"boss,");
fprintf(fp,"flag)\n");
fprintf(fp,"struct %s **objpt;\n",cgen->structname);
if(boss_parm)
fprintf(fp,"struct %s *boss;",cgen->elements->dtype);
fprintf(fp,"int flag;\n");
}
fprintf(fp,"{\n");
fprintf(fp," struct %s *o;\n",cgen->structname);
/* Is an array index i needed ? */
for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
if(ct->is_comment || ct->no_initializer)
continue;
if(ct->array_size>0)
if(strcmp(ct->dtype,"char")!=0) {
fprintf(fp," int i;\n");
break;
}
}
fprintf(fp,"\n");
if(cgen->gen_for_stic)
fprintf(fp," *objpt= o= TSOB_FELD(struct %s,1);\n",cgen->structname);
else
fprintf(fp," *objpt= o= (struct %s *) malloc(sizeof(struct %s));\n",
cgen->structname, cgen->structname);
fprintf(fp," if(o==NULL)\n");
fprintf(fp," return(-1);\n");
fprintf(fp,"\n");
for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
if(ct->is_comment || ct->no_initializer)
continue;
array_size= Ctyp_get_array_size(ct,0);
pointer_level= Ctyp_get_pointer_level(ct,0);
if(ct==cgen->elements && boss_parm) {
fprintf(fp," o->boss= boss;\n");
} else if(array_size>0) {
if(strcmp(ct->dtype,"char")==0) {
fprintf(fp," o->%s[0]= 0;\n;",ct->name);
} else if(pointer_level>0) {
fprintf(fp," for(i=0;i<%lu;i++)\n",array_size);
fprintf(fp," o->%s[i]= NULL;\n",ct->name);
} else {
fprintf(fp," for(i=0;i<%lu;i++)\n",array_size);
fprintf(fp," o->%s[i]= 0;\n",ct->name);
}
} else if(pointer_level>0) {
fprintf(fp," o->%s= NULL;\n",ct->name);
} else
fprintf(fp," o->%s= 0;\n",ct->name);
}
fprintf(fp,"\n");
fprintf(fp," return(1);\n");
fprintf(fp,"/*\n");
fprintf(fp,"failed:;\n");
fprintf(fp," %s_destroy(objpt,0);\n",cgen->functname);
fprintf(fp," return(-1);\n");
fprintf(fp,"*/\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
if(ct->is_comment)
continue;
management= Ctyp_get_management(ct,0);
if(management==4) {
if(ct->next==NULL) {
no_last_pt:;
sprintf(cgen->msg,
"Lonely -l found. A -v of same type must follow.\nName is : %s",
ct->name);
return(0);
}
if(strcmp(ct->next->dtype,ct->dtype)!=0
|| ct->next->is_pointer!=ct->is_pointer)
goto no_last_pt;
ct->next->with_getter= ct->next->with_setter= 0;
ret= Cgen_write_c_new_type(cgen,ct,ct->next,0);
if(ret<=0)
return(ret);
}
}
return(1);
}
int Cgen_write_c_new_type(cgen,ct_first,ct_last,flag)
struct CgeN *cgen;
struct CtyP *ct_first,*ct_last;
int flag;
{
int ret,l,management,pointer_level,i;
FILE *fp= NULL;
char funct[4096],classname[4096],*npt,ptt[4096];
strcpy(funct,ct_first->dtype);
strcpy(classname,funct);
l= strlen(funct);
if(l>0) {
if(cgen->make_lowercase)
funct[0]= tolower(funct[0]);
else
funct[0]= toupper(funct[0]);
funct[l-1]= tolower(funct[l-1]);
classname[0]= tolower(funct[0]);
classname[l-1]= funct[l-1];
}
fp= cgen->fp;
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt, "int %s_new_%s(struct %s *o, int flag)",
cgen->functname,ct_first->name,cgen->structname);
fprintf(fp,"%s\n",ptt);
if(ct_first->with_setter) {
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
}
} else {
fprintf(fp,"int %s_new_%s(o,flag)\n",cgen->functname,ct_first->name);
fprintf(fp,"struct %s *o;\n",cgen->structname);
fprintf(fp,"int flag;\n");
}
fprintf(fp,"{\n");
fprintf(fp," int ret;\n");
fprintf(fp," struct %s *c= NULL;\n",ct_first->dtype);
fprintf(fp,"\n");
if(ct_first->bossless_list)
fprintf(fp," ret= %s_new(&c,0);\n",funct);
else
fprintf(fp," ret= %s_new(&c,o,0);\n",funct);
fprintf(fp," if(ret<=0)\n");
fprintf(fp," return(ret);\n");
fprintf(fp," %s_link(c,o->%s,0);\n",funct,ct_last->name);
fprintf(fp," o->%s= c;\n",ct_last->name);
fprintf(fp," if(o->%s==NULL)\n",ct_first->name);
fprintf(fp," o->%s= c;\n",ct_first->name);
fprintf(fp," return(1);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
ret= 1;
ex:;
return(ret);
}
int Cgen_write_c_destroy(cgen,flag)
struct CgeN *cgen;
int flag;
{
int ret,l,management,pointer_level,i;
FILE *fp= NULL;
struct CtyP *ct,*next;
char funct[4096],*npt,ptt[4096];
fp= cgen->fp;
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt, "int %s_destroy(struct %s **objpt, int flag)",
cgen->functname,cgen->structname);
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_destroy(objpt,flag)\n",cgen->functname);
fprintf(fp,"struct %s **objpt;\n",cgen->structname);
fprintf(fp,"int flag;\n");
}
fprintf(fp,"{\n");
fprintf(fp," struct %s *o;\n",cgen->structname);
fprintf(fp,"\n");
fprintf(fp," o= *objpt;\n");
fprintf(fp," if(o==NULL)\n");
fprintf(fp," return(0);\n");
fprintf(fp,"\n");
for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
if(ct->is_comment)
continue;
management= Ctyp_get_management(ct,0);
if(management==1 || management==4) {
strcpy(funct,ct->dtype);
l= strlen(funct);
if(l>0) {
if(cgen->make_lowercase)
funct[0]= tolower(funct[0]);
else
funct[0]= toupper(funct[0]);
funct[l-1]= tolower(funct[l-1]);
}
if(strcmp(ct->dtype,"char")==0) {
if(cgen->gen_for_stic==1)
fprintf(fp," Sregex_string(");
else if(cgen->gen_for_stic==2)
fprintf(fp," Smem_freE((char *) ");
else
fprintf(fp," free(");
} else if(strcmp(ct->dtype,"LstrinG")==0 || management==4)
fprintf(fp," %s_destroy_all(",funct);
else
fprintf(fp," %s_destroy(",funct);
pointer_level= Ctyp_get_pointer_level(ct,0)-2;
for(i=0; i>pointer_level; i--)
fprintf(fp,"&");
for(i=0; i<pointer_level; i++)
fprintf(fp,"*");
fprintf(fp,"(o->%s)",ct->name);
if(strcmp(ct->dtype,"char")==0) {
if(cgen->gen_for_stic==1)
fprintf(fp,",NULL,0);\n");
else
fprintf(fp,");\n");
} else
fprintf(fp,",0);\n");
} else if(management==2) {
next= ct->next;
if(next==NULL) {
broken_chain:;
sprintf(cgen->msg,
"Lonely -c found. They have to appear in pairs.\nName is : %s",
ct->name);
ret= 0; goto ex;
}
if(next->management!=3)
goto broken_chain;
fprintf(fp," if(o->%s!=NULL)\n",ct->name);
fprintf(fp," o->%s->%s= o->%s;\n",ct->name,next->name,next->name);
fprintf(fp," if(o->%s!=NULL)\n",next->name);
fprintf(fp," o->%s->%s= o->%s;\n",next->name,ct->name,ct->name);
ct= next;
}
}
fprintf(fp,"\n");
if(cgen->gen_for_stic)
fprintf(fp," Smem_freE((char *) o);\n");
else
fprintf(fp," free((char *) o);\n");
fprintf(fp," *objpt= NULL;\n");
fprintf(fp," return(1);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
if(cgen->is_managed_list){
ret= Cgen_write_c_destroy_all(cgen,0);
if(ret<=0)
goto ex;
}
ret= 1;
ex:;
return(ret);
}
int Cgen_write_c_destroy_all(cgen,flag)
struct CgeN *cgen;
int flag;
{
int ret,l,management,pointer_level,i;
FILE *fp= NULL;
struct CtyP *ct;
char ptt[4096];
fp= cgen->fp;
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt, "int %s_destroy_all(struct %s **objpt, int flag)",
cgen->functname, cgen->structname);
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_destroy_all(objpt,flag)\n",cgen->functname);
fprintf(fp,"struct %s **objpt;\n",cgen->structname);
fprintf(fp,"int flag;\n");
}
fprintf(fp,"{\n");
fprintf(fp," struct %s *o,*n;\n",cgen->structname);
fprintf(fp,"\n");
fprintf(fp," o= *objpt;\n");
fprintf(fp," if(o==NULL)\n");
fprintf(fp," return(0);\n");
fprintf(fp," for(;o->prev!=NULL;o= o->prev);\n");
fprintf(fp," for(;o!=NULL;o= n) {\n");
fprintf(fp," n= o->next;\n");
fprintf(fp," %s_destroy(&o,0);\n",cgen->functname);
fprintf(fp," }\n");
fprintf(fp," *objpt= NULL;\n");
fprintf(fp," return(1);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
ret= 1;
ex:;
return(ret);
}
int Cgen_write_c_access(cgen,flag)
struct CgeN *cgen;
int flag;
{
int ret,l,mgt,pointer_level,i;
FILE *fp= NULL;
struct CtyP *ct;
char funct[4096],*npt,ptt[4096];
fp= cgen->fp;
for(ct= cgen->elements; ct!=NULL; ct= ct->next) {
if(ct->is_comment)
continue;
pointer_level= Ctyp_get_pointer_level(ct,0);
if(Ctyp_get_with_getter(ct,0)<=0)
goto after_getter;
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt, "int %s_get_%s(struct %s *o, ",
cgen->functname,ct->name,cgen->structname);
if(Ctyp_is_struct(ct,0))
strcat(ptt,"struct ");
strcat(ptt,ct->dtype);
strcat(ptt," ");
for(i=0; i<pointer_level+1; i++)
strcat(ptt,"*");
if(Ctyp_get_array_size(ct,0)>0)
strcat(ptt,"*");
strcat(ptt,"pt");
if(ct->management==4)
strcat(ptt,", int idx");
strcat(ptt,", int flag)");
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_get_%s(o,pt",cgen->functname,ct->name);
if(ct->management==4)
fprintf(fp,",idx");
fprintf(fp,",flag)\n");
fprintf(fp,"struct %s *o;\n",cgen->structname);
if(Ctyp_is_struct(ct,0))
fprintf(fp,"struct ");
fprintf(fp,"%s ",ct->dtype);
for(i=0; i<pointer_level+1; i++)
fprintf(fp,"*");
if(Ctyp_get_array_size(ct,0)>0)
fprintf(fp,"*");
fprintf(fp,"pt;\n");
if(ct->management==4)
fprintf(fp,"int idx;\n");
fprintf(fp,"int flag;\n");
}
if(ct->management==4)
fprintf(fp,"/* Note: idx==-1 fetches the last item of the list */\n");
fprintf(fp,"{\n");
if(ct->management==4) {
strcpy(funct,ct->dtype);
l= strlen(funct);
if(cgen->make_lowercase)
funct[0]= tolower(funct[0]);
if(l>1)
funct[l-1]= tolower(funct[l-1]);
fprintf(fp," if(idx==-1) {\n");
fprintf(fp," *pt= o->%s;\n",ct->next->name);
fprintf(fp," return(*pt!=NULL);\n");
fprintf(fp," }\n");
fprintf(fp," return(%s_by_idx(o->%s,(flag&1?1:idx),pt,flag&1));\n",
funct,ct->name);
} else {
fprintf(fp," *pt= o->%s;\n",ct->name);
fprintf(fp," return(1);\n");
}
fprintf(fp,"}\n");
fprintf(fp,"\n");
after_getter:;
if(Ctyp_get_with_setter(ct,0)<=0)
goto after_setter;
/* <<< provisory : develop a setter for arrays */
if(Ctyp_get_array_size(ct,0)>0)
goto after_setter;
mgt= Ctyp_get_management(ct,0);
if(mgt==0 ||
(mgt==1 && pointer_level==1)) {
/* -value or -managed pointers */
/* was: -value or -managed char * */
/* (mgt==1 && strcmp(ct->dtype,"char")==0 && pointer_level==1)) { */
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt, "int %s_set_%s(struct %s *o, ",
cgen->functname,ct->name,cgen->structname);
if(Ctyp_is_struct(ct,0))
strcat(ptt,"struct ");
strcat(ptt,ct->dtype);
strcat(ptt," ");
for(i=0; i<pointer_level; i++)
strcat(ptt,"*");
strcat(ptt,"value, int flag)");
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_set_%s(o,value,flag)\n",cgen->functname,ct->name);
fprintf(fp,"struct %s *o;\n",cgen->structname);
if(Ctyp_is_struct(ct,0))
fprintf(fp,"struct ");
fprintf(fp,"%s ",ct->dtype);
for(i=0; i<pointer_level; i++)
fprintf(fp,"*");
fprintf(fp,"value;\n");
fprintf(fp,"int flag;\n");
}
fprintf(fp,"{\n");
if(mgt==1 && strcmp(ct->dtype,"char")==0) {
if(cgen->gen_for_stic==1) {
fprintf(fp," if(Sregex_string(&(o->%s),value,0)<=0)\n",ct->name);
fprintf(fp," return(-1);\n");
} else if(cgen->gen_for_stic==2) {
fprintf(fp," if(Smem_clone_string(&(o->%s),value)<=0)\n",ct->name);
fprintf(fp," return(-1);\n");
} else {
fprintf(fp," char *cpt;\n");
fprintf(fp,"\n");
fprintf(fp," cpt= malloc(strlen(value)+1);\n");
fprintf(fp," if(cpt==NULL)\n");
fprintf(fp," return(-1);\n");
fprintf(fp," o->%s= cpt;\n",ct->name);
fprintf(fp," \n");
}
} else {
fprintf(fp," o->%s= value;\n",ct->name);
}
fprintf(fp," return(1);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
}
after_setter:;
}
if(cgen->is_managed_list) {
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt,"int %s_link(struct %s *o, struct %s *link, int flag)",
cgen->functname,cgen->structname,cgen->structname);
fprintf(fp,"%s\n",ptt);
/* if(cgen->readonly) */
{
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
}
} else {
fprintf(fp,"int %s_link(o,link,flag)\n",cgen->functname);
fprintf(fp,"struct %s *o;\n",cgen->structname);
fprintf(fp,"struct %s *link;\n",cgen->structname);
fprintf(fp,"int flag;\n");
}
fprintf(fp,"/*\n");
fprintf(fp," bit0= insert as link->prev rather than as link->next\n");
fprintf(fp,"*/\n");
fprintf(fp,"{\n");
fprintf(fp," if(o->prev!=NULL)\n");
fprintf(fp," o->prev->next= o->next;\n");
fprintf(fp," if(o->next!=NULL)\n");
fprintf(fp," o->next->prev= o->prev;\n");
fprintf(fp," o->prev= o->next= NULL;\n");
fprintf(fp," if(link==NULL)\n");
fprintf(fp," return(1);\n");
fprintf(fp," if(flag&1) {\n");
fprintf(fp," o->next= link;\n");
fprintf(fp," o->prev= link->prev;\n");
fprintf(fp," if(o->prev!=NULL)\n");
fprintf(fp," o->prev->next= o;\n");
fprintf(fp," link->prev= o;\n");
fprintf(fp," } else {\n");
fprintf(fp," o->prev= link;\n");
fprintf(fp," o->next= link->next;\n");
fprintf(fp," if(o->next!=NULL)\n");
fprintf(fp," o->next->prev= o;\n");
fprintf(fp," link->next= o;\n");
fprintf(fp," }\n");
fprintf(fp," return(1);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt,"int %s_count(struct %s *o, int flag)",
cgen->functname,cgen->structname);
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_count(o,flag)\n",cgen->functname);
fprintf(fp,"struct %s *o;\n",cgen->structname);
fprintf(fp,"int flag;\n");
}
fprintf(fp,"/* flag: bit1= count from start of list */\n");
fprintf(fp,"{\n");
fprintf(fp," int counter= 0;\n");
fprintf(fp,"\n");
fprintf(fp," if(flag&2)\n");
fprintf(fp," for(;o->prev!=NULL;o= o->prev);\n");
fprintf(fp," for(;o!=NULL;o= o->next)\n");
fprintf(fp," counter++;\n");
fprintf(fp," return(counter);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
fprintf(fp,"\n");
if(cgen->make_ansi) {
sprintf(ptt,
"int %s_by_idx(struct %s *o, int idx, struct %s **pt, int flag)",
cgen->functname,cgen->structname,cgen->structname);
fprintf(fp,"%s\n",ptt);
ret= Cgen_write_to_ptt(cgen, ptt, 0);
if(ret<=0)
return(ret);
} else {
fprintf(fp,"int %s_count(o,idx,pt,flag)\n",cgen->functname);
fprintf(fp,"struct %s *o;\n",cgen->structname);
fprintf(fp,"int idx;\n");
fprintf(fp,"struct %s **pt;\n",cgen->structname);
fprintf(fp,"int flag;\n");
}
fprintf(fp,
"/* flag: bit0= fetch first (idx<0) or last (idx>0) item in list\n");
fprintf(fp,
" bit1= address from start of list */\n");
fprintf(fp,"{\n");
fprintf(fp," int i,abs_idx;\n");
fprintf(fp," struct %s *npt;\n",cgen->structname);
fprintf(fp,"\n");
fprintf(fp," if(flag&2)\n");
fprintf(fp," for(;o->prev!=NULL;o= o->prev);\n");
fprintf(fp," abs_idx= (idx>0?idx:-idx);\n");
fprintf(fp," *pt= o;\n");
fprintf(fp," for(i= 0;(i<abs_idx || (flag&1)) && *pt!=NULL;i++) {\n");
fprintf(fp," if(idx>0)\n");
fprintf(fp," npt= o->next;\n");
fprintf(fp," else\n");
fprintf(fp," npt= o->prev;\n");
fprintf(fp," if(npt==NULL && (flag&1))\n");
fprintf(fp," break;\n");
fprintf(fp," *pt= npt;\n");
fprintf(fp," }\n");
fprintf(fp," return(*pt!=NULL);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
}
return(1);
}
int Cgen_write_c_method_include(cgen,flag)
struct CgeN *cgen;
int flag;
{
FILE *fp= NULL;
char filename[4096],line[4096];
struct stat stbuf;
time_t t0;
sprintf(filename,"%s.c.methods",cgen->classname);
if(stat(filename,&stbuf)!=-1)
goto write_include;
fp= fopen(filename,"w");
if(fp==NULL) {
sprintf(cgen->msg,"Cannot open file '%s' in %s-mode. %s",
filename,"w",strerror(errno));
return(0);
}
fprintf(fp,"\n");
fprintf(fp,"/* File %s */\n",filename);
fprintf(fp,"/* Manually provided C code for class %s */\n",
cgen->classname);
fprintf(fp,"/* This file gets copied to the end of %s.c */\n",
cgen->classname);
fprintf(fp,"\n");
fclose(fp); fp= NULL;
write_include:;
fp= fopen(filename,"r");
if(fp==NULL) {
sprintf(cgen->msg,"Cannot open file '%s' in %s-mode. %s",
filename,"r",strerror(errno));
return(0);
}
fprintf(cgen->fp,"\n");
fprintf(cgen->fp,
"/* -------------- end of automatically regenerated code -------------- */\n");
fprintf(cgen->fp,"\n");
while(1) {
if(Sfile_fgets(line,sizeof(line)-1,fp)==NULL)
break;
fprintf(cgen->fp,"%s\n",line);
}
fclose(fp); fp= NULL;
return(1);
}
int Cgen_write_c(cgen,flag)
struct CgeN *cgen;
int flag;
/*
bit0= also write access functions *_set_* *_get_* [*_link_*]
*/
{
int ret;
sprintf(cgen->filename,"%s.c",cgen->classname);
ret= Cgen_open_wfile(cgen,0);
if(ret<=0)
goto ex;
ret= Cgen_write_c_head(cgen,0);
if(ret<=0)
goto ex;
ret= Cgen_write_c_new(cgen,0);
if(ret<=0)
goto ex;
ret= Cgen_write_c_destroy(cgen,0);
if(ret<=0)
goto ex;
if(flag&1) {
ret= Cgen_write_c_access(cgen,0);
if(ret<=0)
goto ex;
}
ret= Cgen_write_c_method_include(cgen,0);
if(ret<=0)
goto ex;
if(cgen->make_ansi) { /* public .h file collected ANSI prototypes */
ret= Cgen_finish_public_h(cgen,0);
if(ret<=0)
goto ex;
}
ret= 1;
ex:;
if(cgen->fp!=NULL)
{fclose(cgen->fp); cgen->fp= NULL;}
return(ret);
}
int Cgen__write_global_include(global_include_file,flag)
char *global_include_file;
int flag;
/*
bit0= write footer rather than header
bit1= allow overwriting of existing file
*/
{
FILE *fp= NULL;
int ret;
char fmode[4],timetext[81],macro_name[4096],*cpt;
time_t t0;
struct stat stbuf;
strcpy(macro_name,global_include_file);
for(cpt= macro_name; *cpt!=0; cpt++) {
if(*cpt>='A' && *cpt<='Z')
*cpt= tolower(*cpt);
else if((*cpt>='a' && *cpt<='z') || (*cpt>='0' && *cpt<='9') || *cpt=='_')
;
else
*cpt= '_';
}
macro_name[0]= toupper(macro_name[0]);
strcat(macro_name,"_includeD");
strcpy(fmode,"w");
if(flag&1) {
strcpy(fmode,"a");
} else {
if(stat(global_include_file,&stbuf)!=-1 && !(flag&2)) {
fprintf(stderr,"+++ File '%s' already existing.",global_include_file);
ret= 0; goto ex;
}
}
fp= fopen(global_include_file,fmode);
if(fp==NULL) {
fprintf(stderr,"+++ Cannot open file '%s' in %s-mode. %s",
global_include_file,fmode,strerror(errno));
ret= 0; goto ex;
}
if(flag&1) {
fprintf(fp,"\n");
fprintf(fp,"#endif /* %s */\n\n",macro_name);
t0= time(0);
strftime(timetext,sizeof(timetext),"%a, %d %b %Y %H:%M:%S GMT",
gmtime(&t0));
fprintf(fp,"/* ( derived from stub generated by CgeN on %s ) */\n",
timetext);
} else {
fprintf(fp,"\n");
fprintf(fp,"#ifndef %s\n",macro_name);
fprintf(fp,"#define %s\n",macro_name);
fprintf(fp,"\n");
}
ex:;
if(fp!=NULL)
fclose(fp);
return(ret);
}
/* ---------------- Sfile and Sregex Emancipation copies ---------------- */
char *Sfile_fgets(line,maxl,fp)
char *line;
int maxl;
FILE *fp;
{
int l;
char *ret;
ret= fgets(line,maxl,fp);
if(ret==NULL)
return(NULL);
l= strlen(line);
if(l>0) if(line[l-1]=='\r') line[--l]= 0;
if(l>0) if(line[l-1]=='\n') line[--l]= 0;
if(l>0) if(line[l-1]=='\r') line[--l]= 0;
return(ret);
}
int Sregex_string_cut(handle,text,len,flag)
char **handle;
char *text;
int len;
int flag;
/*
bit0= append (text!=NULL)
bit1= prepend (text!=NULL)
*/
{
int l=0;
char *old_handle;
if((flag&(1|2))&&*handle!=NULL)
l+= strlen(*handle);
old_handle= *handle;
if(text!=NULL) {
l+= len;
*handle= TSOB_FELD(char,l+1);
if(*handle==NULL) {
*handle= old_handle;
return(0);
}
if((flag&2) && old_handle!=NULL) {
strncpy(*handle,text,len);
strcpy((*handle)+len,old_handle);
} else {
if((flag&1) && old_handle!=NULL)
strcpy(*handle,old_handle);
else
(*handle)[0]= 0;
if(len>0)
strncat(*handle,text,len);
}
} else {
*handle= NULL;
}
if(old_handle!=NULL)
Smem_freE(old_handle);
return(1);
}
int Sregex_string(handle,text,flag)
char **handle;
char *text;
int flag;
/*
bit0= append (text!=NULL)
bit1= prepend (text!=NULL)
*/
{
int ret,l=0;
if(text!=NULL)
l= strlen(text);
/* #define Sregex_looking_for_contenT 1 */
#ifdef Sregex_looking_for_contenT
/* a debugging point if a certain text content has to be caught */
if(text!=NULL)
if(strcmp(text,"clear")==0)
ret= 0;
#endif
ret= Sregex_string_cut(handle,text,l,flag&(1|2));
return(ret);
}
int Sregex_trimline(line,flag)
/*
removes line endings as well as leading and trailing blanks
*/
char *line;
int flag;
/*
bit0= do not remove line end (protects trailing blanks if line end is present)
bit1= do not remove leading blanks
bit2= do not remove trailing blanks
bit3= remove surrounding quotation marks (after removing line end)
*/
{
char *cpt,*wpt;
int l;
if(!(flag&1)){
l= strlen(line);
if(l>0) if(line[l-1]=='\r') line[--l]= 0;
if(l>0) if(line[l-1]=='\n') line[--l]= 0;
if(l>0) if(line[l-1]=='\r') line[--l]= 0;
}
if(flag&3){
l= strlen(line);
if(l>1) if(line[0]==34 && line[l-1]==34) {
wpt= line;
cpt= wpt+1;
while(*cpt!=0)
*(wpt++)= *(cpt++);
line[l-2]= 0;
}
}
if(!(flag&2)){
wpt= cpt= line;
while(*(cpt)!=0) {
if(!isspace(*cpt))
break;
cpt++;
}
while(*(cpt)!=0)
*(wpt++)= *(cpt++);
*wpt= 0;
}
if(!(flag&4)){
l= strlen(line);
if(l<=0)
return(1);
cpt= line+l;
while(cpt-->=line){
if(!isspace(*cpt))
break;
*(cpt)= 0;
}
}
return(1);
}
/* -------------------------------------------------------------- */
main(argc,argv)
int argc;
char **argv;
{
struct CgeN *cgen= NULL;
int ret, msg_printed= 0,first=1,gen_for_stic= 1, make_ansi= 0, i;
int make_lowercase= 0, may_overwrite= 0;
char global_include_file[4096];
global_include_file[0]= 0;
for(i= 1; i<argc; i++) {
if(strcmp(argv[i],"-no_stic")==0)
gen_for_stic= 0;
else if(strcmp(argv[i],"-smem_local")==0)
gen_for_stic= 2;
else if(strcmp(argv[i],"-ansi")==0)
make_ansi= 1;
else if(strcmp(argv[i],"-global_include")==0) {
if(i+1>=argc)
strcpy(global_include_file,"global_include.h");
else {
i++;
strcpy(global_include_file,argv[i]);
}
} else if(strcmp(argv[i],"-lowercase")==0) {
make_lowercase= 1;
} else if(strcmp(argv[i],"-overwrite")==0) {
may_overwrite= 1;
} else {
fprintf(stderr,"+++ %s: Unrecognized option: %s\n",argv[0],argv[i]);
{ret= 0; goto ex;}
}
}
if(strlen(global_include_file)>0) {
/* begin */
ret= Cgen__write_global_include(global_include_file,(!!may_overwrite)<<1);
if(ret<=0)
goto ex;
}
while(!feof(stdin)) {
ret= Cgen_new(&cgen,0);
if(ret<=0)
goto ex;
/* <<< can be done neater */
cgen->gen_for_stic= gen_for_stic;
cgen->make_ansi= make_ansi;
strcpy(cgen->global_include_file,global_include_file);
cgen->make_lowercase= make_lowercase;
cgen->may_overwrite= may_overwrite;
ret= Cgen_read_fp(cgen,stdin,first);
if(ret<=0)
goto ex;
if(ret==2)
break;
first= 0;
ret= Cgen_write_h(cgen,0);
if(ret<=0)
goto ex;
ret= Cgen_write_c(cgen,1);
if(ret<=0)
goto ex;
}
if(strlen(global_include_file)>0) {
/* finalize */
ret= Cgen__write_global_include(global_include_file,1);
if(ret<=0)
goto ex;
}
ret= 1;
ex:
if(cgen!=NULL)
if(cgen->msg[0]!=0) {
fprintf(stderr,"+++ %s\n",cgen->msg);
msg_printed= 1;
}
if(ret<=0 &&!msg_printed) {
if(errno>0)
fprintf(stderr,"+++ Error : %s\n",strerror(errno));
else if(ret==-1)
fprintf(stderr,
"+++ Program run failed (probably due to lack of memory)\n");
else
fprintf(stderr,"+++ Program run failed\n");
}
Cgen_destroy(&cgen,0);
exit(1-ret);
}