mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-07 18:38: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);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
@ -3148,6 +3155,7 @@ static void declstruct(void)
|
||||
int tok;
|
||||
pstruct_t *pstruct;
|
||||
int size;
|
||||
LayoutSpec spec;
|
||||
|
||||
/* get the explicit tag (required!) */
|
||||
tok = lex(&val,&str);
|
||||
@ -3156,10 +3164,7 @@ static void declstruct(void)
|
||||
error(93);
|
||||
}
|
||||
|
||||
if (pstructs_find(str) != NULL)
|
||||
{
|
||||
error(98);
|
||||
}
|
||||
check_struct_name(str);
|
||||
|
||||
pstruct = pstructs_add(str);
|
||||
|
||||
@ -3246,8 +3251,9 @@ static void declstruct(void)
|
||||
*/
|
||||
static void domethodmap()
|
||||
{
|
||||
int val;
|
||||
char *str;
|
||||
LayoutSpec spec;
|
||||
int val, extends;
|
||||
char mapname[sNAMEMAX + 1];
|
||||
methodmap_t *map;
|
||||
methodmap_t *parent = NULL;
|
||||
@ -3261,11 +3267,11 @@ static void domethodmap()
|
||||
if (!isupper(*mapname))
|
||||
error(109, decltype);
|
||||
|
||||
int maptag = pc_addtag(mapname);
|
||||
if (methodmap_find_by_tag(maptag))
|
||||
error(103, decltype, mapname);
|
||||
spec = deduce_layout_spec_by_name(mapname);
|
||||
if (!can_redef_layout_spec(spec, Layout_MethodMap))
|
||||
error(110, mapname, layout_spec_name(spec));
|
||||
|
||||
int extends = matchtoken('<');
|
||||
extends = matchtoken('<');
|
||||
if (extends) {
|
||||
if (lex(&val, &str) != tSYMBOL) {
|
||||
error(93);
|
||||
@ -3279,7 +3285,8 @@ static void domethodmap()
|
||||
|
||||
map = (methodmap_t *)calloc(1, sizeof(methodmap_t));
|
||||
map->parent = parent;
|
||||
map->tag = maptag;
|
||||
map->tag = pc_addtag(mapname);
|
||||
map->spec = Layout_MethodMap;
|
||||
strcpy(map->name, mapname);
|
||||
|
||||
methodmap_add(map);
|
||||
@ -3597,15 +3604,17 @@ static void decl_enum(int vclass)
|
||||
cell increment,multiplier;
|
||||
constvalue *enumroot;
|
||||
symbol *enumsym;
|
||||
LayoutSpec spec;
|
||||
|
||||
/* 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
|
||||
* pc_addtag() here
|
||||
*/
|
||||
if (lex(&val,&str)==tLABEL) {
|
||||
tag=pc_addtag(str);
|
||||
if (methodmap_find_by_tag(tag))
|
||||
error(110, str, "methodmap");
|
||||
tag = pc_addtag(str);
|
||||
spec = deduce_layout_spec_by_tag(tag);
|
||||
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||
error(110, str, layout_spec_name(spec));
|
||||
explicittag=TRUE;
|
||||
} else {
|
||||
lexpush();
|
||||
@ -3618,11 +3627,13 @@ static void decl_enum(int vclass)
|
||||
strcpy(enumname,str); /* save enum name (last constant) */
|
||||
if (!explicittag) {
|
||||
tag=pc_addtag(enumname);
|
||||
if (methodmap_find_by_tag(tag))
|
||||
error(110, str, "methodmap");
|
||||
spec = deduce_layout_spec_by_tag(tag);
|
||||
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||
error(110, enumname, layout_spec_name(spec));
|
||||
} else {
|
||||
if (methodmap_find_by_name(enumname))
|
||||
error(110, str, "methodmap");
|
||||
spec = deduce_layout_spec_by_name(enumname);
|
||||
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||
error(110, enumname, layout_spec_name(spec));
|
||||
}
|
||||
} else {
|
||||
lexpush(); /* analyze again */
|
||||
|
||||
@ -141,12 +141,12 @@ static char *errmsg[] = {
|
||||
/*095*/ "cannot have required parameters after optional parameters\n",
|
||||
/*096*/ "could not find member \"%s\" in struct \"%s\"\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",
|
||||
/*100*/ "function prototypes do not match\n",
|
||||
/*101*/ "specify either all dimensions or only the last dimension\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",
|
||||
/*105*/ "cannot find method %s.%s\n",
|
||||
/*106*/ "cannot call methods on an array\n",
|
||||
|
||||
@ -484,3 +484,85 @@ void methodmaps_free()
|
||||
methodmap_first = 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;
|
||||
} 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
|
||||
{
|
||||
char name[sNAMEMAX+1];
|
||||
@ -78,6 +90,7 @@ typedef struct methodmap_s
|
||||
struct methodmap_s *next;
|
||||
struct methodmap_s *parent;
|
||||
int tag;
|
||||
LayoutSpec spec;
|
||||
char name[sNAMEMAX+1];
|
||||
methodmap_method_t **methods;
|
||||
size_t nummethods;
|
||||
@ -100,6 +113,14 @@ funcenum_t *funcenums_add(const char *name);
|
||||
funcenum_t *funcenums_find_byval(int value);
|
||||
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
|
||||
*/
|
||||
|
||||
@ -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