365 lines
7.0 KiB
C
365 lines
7.0 KiB
C
|
|
/*
|
|
cc -g -o ctyp.c
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include "smem.h"
|
|
extern char *Sfile_fgets();
|
|
extern int Sregex_string();
|
|
extern int Sregex_trimline();
|
|
|
|
#include "ctyp.h"
|
|
|
|
|
|
/* -------------------------- CtyP ----------------------- */
|
|
|
|
|
|
int Ctyp_new(objpt,link,flag)
|
|
struct CtyP **objpt;
|
|
struct CtyP *link;
|
|
int flag;
|
|
{
|
|
struct CtyP *o;
|
|
int ret;
|
|
|
|
*objpt= o= TSOB_FELD(struct CtyP,1);
|
|
if(o==NULL)
|
|
return(-1);
|
|
|
|
o->is_comment= 0;
|
|
o->is_pointer= 0;
|
|
o->is_struct= 0;
|
|
o->is_unsigned= 0;
|
|
o->is_volatile= 0;
|
|
o->array_size= 0;
|
|
o->management= 0;
|
|
o->with_getter= 1;
|
|
o->with_setter= 1;
|
|
o->bossless_list= 0;
|
|
o->no_initializer= 0;
|
|
o->dtype= NULL;
|
|
o->name= NULL;
|
|
o->prev= NULL;
|
|
o->next= NULL;
|
|
|
|
if(link!=NULL)
|
|
link->next= o;
|
|
o->prev= link;
|
|
|
|
return(1);
|
|
failed:;
|
|
Ctyp_destroy(objpt,0);
|
|
return(-1);
|
|
}
|
|
|
|
|
|
int Ctyp_destroy(objpt,flag)
|
|
struct CtyP **objpt;
|
|
int flag;
|
|
{
|
|
struct CtyP *o;
|
|
|
|
o= *objpt;
|
|
if(o==NULL)
|
|
return(0);
|
|
|
|
if(o->prev!=NULL)
|
|
o->prev->next= o->next;
|
|
if(o->next!=NULL)
|
|
o->next->prev= o->prev;
|
|
Sregex_string(&(o->dtype),NULL,0);
|
|
Sregex_string(&(o->name),NULL,0);
|
|
|
|
free((char *) o);
|
|
*objpt= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int Ctyp_get_pointer_level(ct,flag)
|
|
struct CtyP *ct;
|
|
int flag;
|
|
{
|
|
return(ct->is_pointer);
|
|
}
|
|
|
|
|
|
int Ctyp_is_struct(ct,flag)
|
|
struct CtyP *ct;
|
|
int flag;
|
|
{
|
|
return(ct->is_struct);
|
|
}
|
|
|
|
|
|
int Ctyp_get_array_size(ct,flag)
|
|
struct CtyP *ct;
|
|
int flag;
|
|
{
|
|
return(ct->array_size);
|
|
}
|
|
|
|
|
|
int Ctyp_get_management(ct,flag)
|
|
struct CtyP *ct;
|
|
int flag;
|
|
{
|
|
return(ct->management);
|
|
}
|
|
|
|
|
|
int Ctyp_get_with_getter(ct,flag)
|
|
struct CtyP *ct;
|
|
int flag;
|
|
{
|
|
return(ct->with_getter);
|
|
}
|
|
|
|
|
|
int Ctyp_get_with_setter(ct,flag)
|
|
struct CtyP *ct;
|
|
int flag;
|
|
{
|
|
return(ct->with_setter);
|
|
}
|
|
|
|
|
|
int Ctyp_get_dtype(ct,text,flag)
|
|
struct CtyP *ct;
|
|
char **text; /* must point to NULL of freeable memory */
|
|
int flag;
|
|
/*
|
|
bit0=eventually prepend "struct "
|
|
*/
|
|
{
|
|
if((flag&1) && ct->is_struct) {
|
|
if(Sregex_string(text,"struct ",0)<=0)
|
|
return(-1);
|
|
} else {
|
|
if(Sregex_string(text,"",0)<=0)
|
|
return(-1);
|
|
}
|
|
if(Sregex_string(text,ct->dtype,1)<=0)
|
|
return(-1);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int Ctyp_get_name(ct,text,flag)
|
|
struct CtyP *ct;
|
|
char **text; /* must point to NULL of freeable memory */
|
|
int flag;
|
|
{
|
|
if(Sregex_string(text,ct->name,0)<=0)
|
|
return(-1);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int Ctyp_get_type_mod(ct,is_spointer,is_struct,array_size,flag)
|
|
struct CtyP *ct;
|
|
int *is_spointer,*is_struct,*array_size;
|
|
int flag;
|
|
{
|
|
*is_spointer= ct->is_pointer;
|
|
*is_struct= ct->is_struct;
|
|
*array_size= ct->array_size;
|
|
}
|
|
|
|
int Ctyp_new_from_line(ct,link,line,msg,flag)
|
|
struct CtyP **ct;
|
|
struct CtyP *link;
|
|
char *line;
|
|
char *msg;
|
|
int flag;
|
|
/*
|
|
bit0= make struct ClassnamE to struct classname
|
|
*/
|
|
{
|
|
struct CtyP *o;
|
|
char *cpt,*bpt;
|
|
int ret,l;
|
|
char orig_line[4096];
|
|
|
|
ret= Ctyp_new(ct,*ct,0);
|
|
if(ret<=0) {
|
|
sprintf(msg,"Failed to create CtyP object (due to lack of memory ?)");
|
|
goto ex;
|
|
}
|
|
o= *ct;
|
|
|
|
strcpy(orig_line,line);
|
|
cpt= line;
|
|
while(*cpt!=0 && isspace(*cpt)) cpt++;
|
|
if(cpt[0]=='#') {
|
|
cpt++;
|
|
if(cpt[1]==' ')
|
|
cpt++;
|
|
l= strlen(cpt);
|
|
if(cpt[0]==' ')
|
|
cpt++;
|
|
if(l>1)
|
|
if(cpt[l-1]==' ')
|
|
cpt[l-1]= 0;
|
|
if(Sregex_string(&(o->name),cpt,0)<=0)
|
|
{ret= -1; goto ex;}
|
|
o->is_comment= 1;
|
|
{ret= 1; goto ex;}
|
|
} else if(cpt[0]==0) {
|
|
if(Sregex_string(&(o->name),cpt,0)<=0)
|
|
{ret= -1; goto ex;}
|
|
o->is_comment= 1;
|
|
{ret= 1; goto ex;}
|
|
} else if(cpt[0]=='/' && cpt[1]=='*') {
|
|
sprintf(msg,
|
|
"C-style multi line comments (/* ... */) not supported yet. Use #.");
|
|
goto ex;
|
|
|
|
/* >>> */
|
|
|
|
}
|
|
cpt= line;
|
|
while(cpt[0]=='-') {
|
|
/* look for management specifiers:
|
|
-v* just a value
|
|
-m* allocated memory which needs to be freed
|
|
-c* mutual link (like prev+next)
|
|
-l* list of -m chained by mutual links prev and next
|
|
|
|
-r* read-only : no setter function
|
|
-p* private : neither setter nor getter function
|
|
-b* bossless_list : Class_new(o,flag), not Class_new(o,boss,flag)
|
|
-i* no_initializer : do not initialize element in <Class>_new()
|
|
#... line is a comment
|
|
*/
|
|
if(cpt[1]=='v' || cpt[1]=='V') {
|
|
o->management= 0;
|
|
} else if(cpt[1]=='m' || cpt[1]=='M') {
|
|
o->management= 1;
|
|
} else if(cpt[1]=='c' || cpt[1]=='C') {
|
|
o->management= 2;
|
|
if(o->prev!=NULL)
|
|
if(o->prev->management==2)
|
|
o->management= 3;
|
|
} else if(cpt[1]=='l' || cpt[1]=='L') {
|
|
o->management= 4;
|
|
} else if(cpt[1]=='r' || cpt[1]=='R') {
|
|
o->with_setter= 0;
|
|
} else if(cpt[1]=='p' || cpt[1]=='P') {
|
|
o->with_setter= 0;
|
|
o->with_getter= 0;
|
|
} else if(cpt[1]=='b' || cpt[1]=='B') {
|
|
o->bossless_list= 1;
|
|
} else if(cpt[1]=='i' || cpt[1]=='I') {
|
|
o->no_initializer= 1;
|
|
}
|
|
while(*cpt!=0 && !isspace(*cpt)) cpt++;
|
|
while(*cpt!=0 && isspace(*cpt)) cpt++;
|
|
if(*cpt==0)
|
|
goto no_name;
|
|
}
|
|
|
|
if(strncmp(cpt,"struct ",7)==0) {
|
|
o->is_struct= 1;
|
|
cpt+= 7;
|
|
} else if(strncmp(cpt,"unsigned ",9)==0) {
|
|
o->is_unsigned= 1;
|
|
cpt+= 9;
|
|
} else if(strncmp(cpt,"volatile ",9)==0) {
|
|
o->is_volatile= 1;
|
|
cpt+= 9;
|
|
if(strncmp(cpt,"unsigned ",9)==0) {
|
|
o->is_unsigned= 1;
|
|
cpt+= 9;
|
|
}
|
|
}
|
|
if(*cpt==0)
|
|
goto no_name;
|
|
while(*cpt!=0 && isspace(*cpt)) cpt++;
|
|
bpt= cpt;
|
|
while(*bpt!=0 && !isspace(*bpt)) bpt++;
|
|
if(*bpt==0)
|
|
goto no_name;
|
|
if(*bpt==0) {
|
|
no_name:;
|
|
sprintf(msg,"No name found after type description : %s",orig_line);
|
|
ret= 0; goto ex;
|
|
}
|
|
*bpt= 0;
|
|
if(Sregex_string(&(o->dtype),cpt,0)<=0)
|
|
{ret= -1; goto ex;}
|
|
if((flag&1) && o->is_struct && strlen(o->dtype)>=3)
|
|
if(isupper(o->dtype[0]) && islower(o->dtype[1]) &&
|
|
isupper(o->dtype[strlen(o->dtype)-1])) {
|
|
o->dtype[0]= tolower(o->dtype[0]);
|
|
o->dtype[strlen(o->dtype)-1]= tolower(o->dtype[strlen(o->dtype)-1]);
|
|
}
|
|
cpt= bpt+1;
|
|
while(*cpt!=0 && isspace(*cpt)) cpt++;
|
|
if(*cpt==0)
|
|
goto no_name;
|
|
for(;*cpt=='*';cpt++)
|
|
o->is_pointer++;
|
|
if(*cpt==0)
|
|
goto no_name;
|
|
bpt= strchr(cpt,'[');
|
|
if(bpt!=NULL) {
|
|
if(strchr(bpt,']')!=NULL)
|
|
*strchr(bpt,']')= 0;
|
|
sscanf(bpt+1,"%lu",&(o->array_size));
|
|
*bpt= 0;
|
|
}
|
|
if(Sregex_string(&(o->name),cpt,0)<=0)
|
|
{ret= -1; goto ex;}
|
|
if(o->management==1) {
|
|
if((!(o->is_pointer>=1 && o->is_pointer<=2)) ||
|
|
((!o->is_struct) && strcmp(o->dtype,"char")!=0 &&
|
|
(strcmp(o->dtype,"unsigned char")!=0))) {
|
|
sprintf(msg,"-m can only be applied to pointers of struct or char : %s",
|
|
orig_line);
|
|
ret= 0; goto ex;
|
|
}
|
|
}
|
|
ret= 1;
|
|
ex:;
|
|
return(ret);
|
|
}
|
|
|
|
|
|
int Ctyp_read_fp(ct,fp,msg,flag)
|
|
struct CtyP **ct;
|
|
FILE *fp;
|
|
char msg[]; /* at least [4096+256] */
|
|
int flag;
|
|
/*
|
|
bit0= make struct ClassnamE to struct classname
|
|
*/
|
|
{
|
|
int ret;
|
|
char line[4096];
|
|
struct CtyP *o;
|
|
|
|
line[0]= 0;
|
|
printf(
|
|
"[-value|-managed|-chain|-list] class element ? (e.g.: -l struct XyZ)\n");
|
|
if(Sfile_fgets(line,sizeof(line)-1,fp)==NULL)
|
|
{ret= 2; goto ex;}
|
|
printf("%s\n",line);
|
|
Sregex_trimline(line,0);
|
|
if(strcmp(line,"@")==0)
|
|
{ret= 2; goto ex;}
|
|
ret= Ctyp_new_from_line(ct,*ct,line,msg,flag&1);
|
|
if(ret<=0)
|
|
goto ex;
|
|
ret= 1;
|
|
ex:;
|
|
return(ret);
|
|
}
|
|
|