mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-10 11:58:37 +00:00
Unify duplicate typesymbol checking.
This commit is contained in:
parent
09161bf269
commit
05cf368202
@ -3138,6 +3138,13 @@ static void decl_const(int vclass)
|
|||||||
needtoken(tTERM);
|
needtoken(tTERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_struct_name(const char *name)
|
||||||
|
{
|
||||||
|
LayoutSpec spec = deduce_layout_spec_by_name(name);
|
||||||
|
if (!can_redef_layout_spec(spec, Layout_PawnStruct))
|
||||||
|
error(110, name, layout_spec_name(spec));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* declstruct - declare a struct type
|
* declstruct - declare a struct type
|
||||||
*/
|
*/
|
||||||
@ -3148,6 +3155,7 @@ static void declstruct(void)
|
|||||||
int tok;
|
int tok;
|
||||||
pstruct_t *pstruct;
|
pstruct_t *pstruct;
|
||||||
int size;
|
int size;
|
||||||
|
LayoutSpec spec;
|
||||||
|
|
||||||
/* get the explicit tag (required!) */
|
/* get the explicit tag (required!) */
|
||||||
tok = lex(&val,&str);
|
tok = lex(&val,&str);
|
||||||
@ -3156,10 +3164,7 @@ static void declstruct(void)
|
|||||||
error(93);
|
error(93);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pstructs_find(str) != NULL)
|
check_struct_name(str);
|
||||||
{
|
|
||||||
error(98);
|
|
||||||
}
|
|
||||||
|
|
||||||
pstruct = pstructs_add(str);
|
pstruct = pstructs_add(str);
|
||||||
|
|
||||||
@ -3246,8 +3251,9 @@ static void declstruct(void)
|
|||||||
*/
|
*/
|
||||||
static void domethodmap()
|
static void domethodmap()
|
||||||
{
|
{
|
||||||
int val;
|
|
||||||
char *str;
|
char *str;
|
||||||
|
LayoutSpec spec;
|
||||||
|
int val, extends;
|
||||||
char mapname[sNAMEMAX + 1];
|
char mapname[sNAMEMAX + 1];
|
||||||
methodmap_t *map;
|
methodmap_t *map;
|
||||||
methodmap_t *parent = NULL;
|
methodmap_t *parent = NULL;
|
||||||
@ -3261,11 +3267,11 @@ static void domethodmap()
|
|||||||
if (!isupper(*mapname))
|
if (!isupper(*mapname))
|
||||||
error(109, decltype);
|
error(109, decltype);
|
||||||
|
|
||||||
int maptag = pc_addtag(mapname);
|
spec = deduce_layout_spec_by_name(mapname);
|
||||||
if (methodmap_find_by_tag(maptag))
|
if (!can_redef_layout_spec(spec, Layout_MethodMap))
|
||||||
error(103, decltype, mapname);
|
error(110, mapname, layout_spec_name(spec));
|
||||||
|
|
||||||
int extends = matchtoken('<');
|
extends = matchtoken('<');
|
||||||
if (extends) {
|
if (extends) {
|
||||||
if (lex(&val, &str) != tSYMBOL) {
|
if (lex(&val, &str) != tSYMBOL) {
|
||||||
error(93);
|
error(93);
|
||||||
@ -3279,7 +3285,8 @@ static void domethodmap()
|
|||||||
|
|
||||||
map = (methodmap_t *)calloc(1, sizeof(methodmap_t));
|
map = (methodmap_t *)calloc(1, sizeof(methodmap_t));
|
||||||
map->parent = parent;
|
map->parent = parent;
|
||||||
map->tag = maptag;
|
map->tag = pc_addtag(mapname);
|
||||||
|
map->spec = Layout_MethodMap;
|
||||||
strcpy(map->name, mapname);
|
strcpy(map->name, mapname);
|
||||||
|
|
||||||
methodmap_add(map);
|
methodmap_add(map);
|
||||||
@ -3597,6 +3604,7 @@ static void decl_enum(int vclass)
|
|||||||
cell increment,multiplier;
|
cell increment,multiplier;
|
||||||
constvalue *enumroot;
|
constvalue *enumroot;
|
||||||
symbol *enumsym;
|
symbol *enumsym;
|
||||||
|
LayoutSpec spec;
|
||||||
|
|
||||||
/* get an explicit tag, if any (we need to remember whether an explicit
|
/* get an explicit tag, if any (we need to remember whether an explicit
|
||||||
* tag was passed, even if that explicit tag was "_:", so we cannot call
|
* tag was passed, even if that explicit tag was "_:", so we cannot call
|
||||||
@ -3604,8 +3612,9 @@ static void decl_enum(int vclass)
|
|||||||
*/
|
*/
|
||||||
if (lex(&val,&str)==tLABEL) {
|
if (lex(&val,&str)==tLABEL) {
|
||||||
tag = pc_addtag(str);
|
tag = pc_addtag(str);
|
||||||
if (methodmap_find_by_tag(tag))
|
spec = deduce_layout_spec_by_tag(tag);
|
||||||
error(110, str, "methodmap");
|
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||||
|
error(110, str, layout_spec_name(spec));
|
||||||
explicittag=TRUE;
|
explicittag=TRUE;
|
||||||
} else {
|
} else {
|
||||||
lexpush();
|
lexpush();
|
||||||
@ -3618,11 +3627,13 @@ static void decl_enum(int vclass)
|
|||||||
strcpy(enumname,str); /* save enum name (last constant) */
|
strcpy(enumname,str); /* save enum name (last constant) */
|
||||||
if (!explicittag) {
|
if (!explicittag) {
|
||||||
tag=pc_addtag(enumname);
|
tag=pc_addtag(enumname);
|
||||||
if (methodmap_find_by_tag(tag))
|
spec = deduce_layout_spec_by_tag(tag);
|
||||||
error(110, str, "methodmap");
|
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||||
|
error(110, enumname, layout_spec_name(spec));
|
||||||
} else {
|
} else {
|
||||||
if (methodmap_find_by_name(enumname))
|
spec = deduce_layout_spec_by_name(enumname);
|
||||||
error(110, str, "methodmap");
|
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||||
|
error(110, enumname, layout_spec_name(spec));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lexpush(); /* analyze again */
|
lexpush(); /* analyze again */
|
||||||
|
|||||||
@ -141,12 +141,12 @@ static char *errmsg[] = {
|
|||||||
/*095*/ "cannot have required parameters after optional parameters\n",
|
/*095*/ "cannot have required parameters after optional parameters\n",
|
||||||
/*096*/ "could not find member \"%s\" in struct \"%s\"\n",
|
/*096*/ "could not find member \"%s\" in struct \"%s\"\n",
|
||||||
/*097*/ "symbol \"%s\" does not have a matching type\n",
|
/*097*/ "symbol \"%s\" does not have a matching type\n",
|
||||||
/*098*/ "struct requires unique struct name\n",
|
/*098*/ "UNUSED\n",
|
||||||
/*099*/ "member \"%s\" appears more than once in struct \"%s\"\n",
|
/*099*/ "member \"%s\" appears more than once in struct \"%s\"\n",
|
||||||
/*100*/ "function prototypes do not match\n",
|
/*100*/ "function prototypes do not match\n",
|
||||||
/*101*/ "specify either all dimensions or only the last dimension\n",
|
/*101*/ "specify either all dimensions or only the last dimension\n",
|
||||||
/*102*/ "cannot find %s %s\n",
|
/*102*/ "cannot find %s %s\n",
|
||||||
/*103*/ "%s %s was already defined\n",
|
/*103*/ "UNUSED\n",
|
||||||
/*104*/ "cannot find any methods for %s\n",
|
/*104*/ "cannot find any methods for %s\n",
|
||||||
/*105*/ "cannot find method %s.%s\n",
|
/*105*/ "cannot find method %s.%s\n",
|
||||||
/*106*/ "cannot call methods on an array\n",
|
/*106*/ "cannot call methods on an array\n",
|
||||||
|
|||||||
@ -484,3 +484,85 @@ void methodmaps_free()
|
|||||||
methodmap_first = NULL;
|
methodmap_first = NULL;
|
||||||
methodmap_last = NULL;
|
methodmap_last = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayoutSpec deduce_layout_spec_by_tag(int tag)
|
||||||
|
{
|
||||||
|
symbol *sym;
|
||||||
|
const char *name;
|
||||||
|
methodmap_t *map;
|
||||||
|
if ((map = methodmap_find_by_tag(tag)) != NULL)
|
||||||
|
return map->spec;
|
||||||
|
if (tag & FUNCTAG)
|
||||||
|
return Layout_FuncTag;
|
||||||
|
|
||||||
|
name = pc_tagname(tag);
|
||||||
|
if (pstructs_find(name))
|
||||||
|
return Layout_PawnStruct;
|
||||||
|
if ((sym = findglb(name, sGLOBAL)) != NULL)
|
||||||
|
return Layout_Enum;
|
||||||
|
|
||||||
|
return Layout_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutSpec deduce_layout_spec_by_name(const char *name)
|
||||||
|
{
|
||||||
|
symbol *sym;
|
||||||
|
methodmap_t *map;
|
||||||
|
int tag = pc_findtag(name);
|
||||||
|
if (tag != -1 && (tag & FUNCTAG))
|
||||||
|
return Layout_FuncTag;
|
||||||
|
if (pstructs_find(name))
|
||||||
|
return Layout_PawnStruct;
|
||||||
|
if ((map = methodmap_find_by_name(name)) != NULL)
|
||||||
|
return map->spec;
|
||||||
|
if ((sym = findglb(name, sGLOBAL)) != NULL)
|
||||||
|
return Layout_Enum;
|
||||||
|
|
||||||
|
return Layout_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *layout_spec_name(LayoutSpec spec)
|
||||||
|
{
|
||||||
|
switch (spec) {
|
||||||
|
case Layout_None:
|
||||||
|
return "<none>";
|
||||||
|
case Layout_Enum:
|
||||||
|
return "enum";
|
||||||
|
case Layout_FuncTag:
|
||||||
|
return "functag";
|
||||||
|
case Layout_PawnStruct:
|
||||||
|
return "deprecated-struct";
|
||||||
|
case Layout_MethodMap:
|
||||||
|
return "methodmap";
|
||||||
|
case Layout_Class:
|
||||||
|
return "class";
|
||||||
|
}
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
|
||||||
|
int can_redef_layout_spec(LayoutSpec def1, LayoutSpec def2)
|
||||||
|
{
|
||||||
|
// Normalize the ordering, since these checks are symmetrical.
|
||||||
|
if (def1 > def2) {
|
||||||
|
LayoutSpec temp = def2;
|
||||||
|
def2 = def1;
|
||||||
|
def1 = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (def1) {
|
||||||
|
case Layout_None:
|
||||||
|
return TRUE;
|
||||||
|
case Layout_Enum:
|
||||||
|
if (def2 == Layout_Enum || def2 == Layout_FuncTag)
|
||||||
|
return TRUE;
|
||||||
|
return def2 == Layout_MethodMap;
|
||||||
|
case Layout_FuncTag:
|
||||||
|
return def2 == Layout_Enum || def2 == Layout_FuncTag;
|
||||||
|
case Layout_PawnStruct:
|
||||||
|
case Layout_MethodMap:
|
||||||
|
return FALSE;
|
||||||
|
case Layout_Class:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|||||||
@ -67,6 +67,18 @@ typedef struct pstruct_s
|
|||||||
struct pstruct_s *next;
|
struct pstruct_s *next;
|
||||||
} pstruct_t;
|
} pstruct_t;
|
||||||
|
|
||||||
|
// The ordering of these definitions should be preserved for
|
||||||
|
// can_redef_layout_spec().
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Layout_None,
|
||||||
|
Layout_Enum,
|
||||||
|
Layout_FuncTag,
|
||||||
|
Layout_PawnStruct,
|
||||||
|
Layout_MethodMap,
|
||||||
|
Layout_Class
|
||||||
|
} LayoutSpec;
|
||||||
|
|
||||||
typedef struct methodmap_method_s
|
typedef struct methodmap_method_s
|
||||||
{
|
{
|
||||||
char name[sNAMEMAX+1];
|
char name[sNAMEMAX+1];
|
||||||
@ -78,6 +90,7 @@ typedef struct methodmap_s
|
|||||||
struct methodmap_s *next;
|
struct methodmap_s *next;
|
||||||
struct methodmap_s *parent;
|
struct methodmap_s *parent;
|
||||||
int tag;
|
int tag;
|
||||||
|
LayoutSpec spec;
|
||||||
char name[sNAMEMAX+1];
|
char name[sNAMEMAX+1];
|
||||||
methodmap_method_t **methods;
|
methodmap_method_t **methods;
|
||||||
size_t nummethods;
|
size_t nummethods;
|
||||||
@ -100,6 +113,14 @@ funcenum_t *funcenums_add(const char *name);
|
|||||||
funcenum_t *funcenums_find_byval(int value);
|
funcenum_t *funcenums_find_byval(int value);
|
||||||
functag_t *functags_add(funcenum_t *en, functag_t *src);
|
functag_t *functags_add(funcenum_t *en, functag_t *src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a name or tag, find any extra weirdness it has associated with it.
|
||||||
|
*/
|
||||||
|
LayoutSpec deduce_layout_spec_by_tag(int tag);
|
||||||
|
LayoutSpec deduce_layout_spec_by_name(const char *name);
|
||||||
|
const char *layout_spec_name(LayoutSpec spec);
|
||||||
|
int can_redef_layout_spec(LayoutSpec olddef, LayoutSpec newdef);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Heap functions
|
* Heap functions
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
native CloseHandle(Handle:this);
|
|
||||||
|
|
||||||
methodmap Handle {
|
|
||||||
Close = CloseHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
methodmap Crab {
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Crab {
|
|
||||||
};
|
|
||||||
|
|
||||||
public main()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user