📄 udtypes.cpp
字号:
#include "UDTypes.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alloc.h>
#include <conio.h>
UDTypeList udt;
UDType::UDType()
{
NumVars=0;
Size=0;
Name=NULL;
Entries=NULL;
}
void UDType::Invalidate()
{
UDType::UDType();
}
void UDType::Display(char *n=0)
{
switch(Type)
{
case VAR_STRUCT : printf("struct %s\n{\n",Name); break;
case VAR_UNION : printf("union %s\n{\n",Name); break;
case VAR_TYPEDEF: printf("typedef "); break;
}
for(int i=0;i<NumVars;i++)
{
switch(Entries[i].Type)
{
case VAR_VOID : printf("void %s\n",Entries[i].Name); break;
case VAR_CHAR : printf("char %s\n",Entries[i].Name); break;
case VAR_INT : printf("int %s\n",Entries[i].Name); break;
case VAR_LONG : printf("long %s\n",Entries[i].Name); break;
case VAR_UNION:
case VAR_STRUCT:Entries[i].ptr->Display(Entries[i].Name); break;
}
}
if (Type!=VAR_TYPEDEF)
{
printf("}");
if (n) printf("%s",n);
}
printf("\n");
}
UDType::~UDType()
{
if (Name) free(Name);
if (Entries) free(Entries);
UDType::UDType();
}
void UDType::operator =(UDType &t)
{
memcpy(this,&t,sizeof(UDType));
}
int next(char *str,char *s,char *_tmp=0)
{
char tmp[100];
sscanf(str,"%s",tmp);
int i=0;
while(tmp[i]!=0 && tmp[i]!=';' && tmp[i]!='{' && tmp[i]!='}' && tmp[i]!=',')
i++;
tmp[i]=0;
if (_tmp!=0) strcpy(_tmp,tmp);
return (strcmp(tmp,s)==0);
}
char *skipto(char *str,int c,int c1=0)
{
while(*str!=c && *str!=c1 && *str!=0) str++;
if (*str!=0) str++;
return str;
}
char *spc(char *str)
{
while((*str>=0x09 && *str<=0x0d) || *str==0x20) str++;
return str;
}
char *getdecl(char *_str,UDTypeEntry &t)
{
if (!*_str) return NULL;
static char *declstr=0;
char *str;
t.Type=VAR_UNKNOWN;
t.ptr=NULL;
char tmp[40];
// check for previous declarations
if (!declstr) { str=_str; }
else { str=declstr; }
// skip the type modifiers.
str=spc(str);
if (next(str,"signed")) str+=6;
else if (next(str,"unsigned")) str+=8;
// find the datatype.
str=spc(str);
next(str,"",tmp);
if (strcmp(tmp,"void")==0) { t.Type=VAR_VOID; str+=4; }
else if (strcmp(tmp,"short")==0) { t.Type=VAR_INT; str+=5; }
else if (strcmp(tmp,"int")==0) { t.Type=VAR_INT; str+=3; }
else if (strcmp(tmp,"char")==0) { t.Type=VAR_CHAR; str+=4; }
else if (strcmp(tmp,"long")==0)
{
t.Type=VAR_LONG;
str+=4;
str=spc(str);
if (next(str,"int")) str+=3;
}
else if (strcmp(tmp,"struct")==0)
{
char *tstr=str;
str+=6; str=spc(str);
UDType *utype=NULL;
// is it a structure defined inside this declaration?
if (*str=='{')
{
UDType newtype;
newtype.Assign(tstr);
if (newtype.NumVars!=0)
utype=udt.Add(newtype);
newtype.Invalidate();
// skip till the corresponding '}'.
int i=1;
do
{
str=skipto(str+1,'}','{');
if (*(str-1)=='{') i++;
else i--;
}while(i);
}
else
{
str=spc(str);
// get the struct name.
next(str,"",tmp);
utype=udt.GetType(tmp);
// skip the struct name.
str+=strlen(tmp);
}
if (utype) { t.Type=VAR_STRUCT; t.ptr=utype; }
}
else if (strcmp(tmp,"union")==0)
{
str+=5; str=spc(str);
UDType *utype=udt.GetType(str);
if (utype) { t.Type=VAR_UNION; t.ptr=utype; }
}
else
{
// if control comes here, then the declaration is of the form
// "typedef unsigned size_t", or something else, where int,char,long,
// struct,union have not been given. The default datatype used is 'int'.
t.Type=VAR_INT;
}
if (declstr) str=_str;
str=spc(str);
char *tstr=skipto(str,';',',');
if (*(tstr-1)==',')
{
if (!declstr) declstr=_str;
}
else declstr=NULL;
int i=tstr-str;
t.Name=(char *)malloc(i);
if (!t.Name) goto ErrorInGetDecl;
strncpy(t.Name,str,i-1); t.Name[i-1]=0;
return tstr;
ErrorInGetDecl:
t.Type=VAR_UNKNOWN;
if (t.Name) free(t.Name);
return NULL;
}
int UDType::Assign(char *str)
{
UDType::~UDType();
char tmp[100];
UDTypeEntry t;
str=spc(str);
// is it a 'struct' definition?
if (next(str,"struct") || next(str,"union"))
{
Type=(next(str,"struct"))?VAR_STRUCT:VAR_UNION;
str+=6;
str=spc(str);
// get the name field.
next(str,"",tmp);
Name=(char *)malloc(strlen(tmp)+1);
if (!Name) goto ErrorInAssign;
strcpy(Name,tmp);
str=skipto(str,'{');
str=spc(str);
NumVars=0;
char *tstr=str;
while((tstr=getdecl(tstr,t))!=NULL)
{
NumVars++;
tstr=spc(tstr);
if (*tstr=='}') break;
}
Entries = (UDTypeEntry *)malloc(sizeof(UDTypeEntry)*NumVars);
if (!Entries) goto ErrorInAssign;
NumVars=0;
while((str=getdecl(str,Entries[NumVars]))!=NULL)
{
NumVars++;
str=spc(str);
if (*str=='}') break;
}
}
else if (next(str,"typedef"))
{
Type=VAR_TYPEDEF;
str+=7; str=spc(str);
Entries=(UDTypeEntry *)malloc(sizeof(UDTypeEntry));
if (!Entries) goto ErrorInAssign;
NumVars=1;
Entries[0].ptr=NULL; Entries[0].Name=NULL;
str=getdecl(str,Entries[0]);
}
return 0;
ErrorInAssign:
UDType::~UDType();
return 1;
}
UDTypeList::UDTypeList()
{
Data.UDType::~UDType();
Next=NULL;
}
UDTypeList::~UDTypeList()
{
if (Next) delete Next;
UDTypeList::UDTypeList();
}
UDType *UDTypeList::Add(UDType &t)
{
UDTypeList *ptr=this;
while(ptr->Data.NumVars!=0)
{
if (!ptr->Next) ptr->Next = new UDTypeList;
ptr=ptr->Next;
}
ptr->Data=t;
return &ptr->Data;
}
UDType *UDTypeList::GetType(char *Name)
{
UDTypeList *ptr=this;
while(ptr && ptr->Data.NumVars!=0)
{
if (strcmp(ptr->Data.Name,Name)==0) return &ptr->Data;
ptr=ptr->Next;
}
return NULL;
}
void UDTypeList::Display()
{
UDTypeList *ptr=this;
while(ptr && ptr->Data.NumVars!=0)
{
ptr->Data.Display();
ptr=ptr->Next;
}
}
/*----------------------------------------------------------
Routines which skip any comments while reading a C-file.
----------------------------------------------------------*/
int CurrentChar;
FILE *fileopen(char *fname,char *mode)
{
FILE *fp=fopen(fname,mode);
if (fp) CurrentChar=fgetc(fp);
return fp;
}
void fileclose(FILE *fp)
{
fileclose(fp);
}
int filegetc(FILE *fp)
{
int NextChar;
NextChar=fgetc(fp);
if (CurrentChar=='/' && NextChar=='*')
{
do
{
CurrentChar=NextChar;
NextChar=fgetc(fp);
}while(!(CurrentChar=='*' && NextChar=='/'));
CurrentChar=fgetc(fp); NextChar=fgetc(fp);
}
int c=CurrentChar; CurrentChar=NextChar;
return c;
}
char *filegets(char *str,int n,FILE *fp)
{
char *t=str;
while(n--)
{
*str=filegetc(fp);
if (*str==EOF || *str=='\n') break;
str++;
}
*str=0;
return t;
}
int fileread(char *str,int size,FILE *fp)
{
int c,i;
for(i=0;i<size && (c=filegetc(fp))!=EOF;i++) *(str++)=c;
return i;
}
long fileseek(FILE *fp,int offset,int whence)
{
fseek(fp,offset,whence);
CurrentChar=fgetc(fp);
return offset+1;
}
long filetell(FILE *fp)
{
return ftell(fp)-1;
}
void FromFileToUDT(FILE *fp)
{
long pos=filetell(fp);
int c;
int bracesleft=0;
int size=0;
do
{
c=filegetc(fp);
size++;
if (c==';' && !bracesleft) break;
if (c=='{') bracesleft++;
else if (c=='}') bracesleft--;
if (bracesleft<0)
{
printf("Error in parsing datatype definition\n");
break;
}
}while(1);
char *str=(char *)malloc(size+1);
if (!str)
{
printf("Not enough memory for new datatype definition\n");
return;
}
fileseek(fp,pos,SEEK_SET);
fileread(str,size,fp);
str[size]=0;
UDType t;
t.Assign(str);
udt.Add(t);
t.Invalidate();
free(str);
}
int GetTypesFromFile(char *FileName)
{
FILE *fp;
fp=fileopen(FileName,"r");
if (!fp) return 1;
char line[128];
long fpos=0;
while(!feof(fp))
{
filegets(line,127,fp);
char *t;
// Is it an #include statement?
if (strncmp(line,"#include",8)==0)
{
t=skipto(line,'<','"');
int len=skipto(t,'>','"')-t;
t[len-1]=0;
if (GetTypesFromFile(t)!=0)
printf("Error reading include file %s\n",t);
}
else if ((t=strstr(line,"typedef"))!=NULL ||
(t=strstr(line,"struct"))!=NULL ||
(t=strstr(line,"union"))!=NULL)
{
// seek to the beginning of whichever declaration we came across.
fileseek(fp,fpos+t-line,SEEK_SET);
// add this user-defined-type to the list.
FromFileToUDT(fp);
}
fpos=filetell(fp);
}
return 0;
}
/*main()
{
GetTypesFromFile("dos.h");
udt.Display();
return 0;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -