mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
parse a type back from its encoding (some info will be lost)
This commit is contained in:
parent
c50923fa6f
commit
598edb26fd
3 changed files with 114 additions and 4 deletions
tools/qfcc
|
@ -84,6 +84,7 @@ type_t *pointer_type (type_t *aux);
|
|||
type_t *array_type (type_t *aux, int size);
|
||||
void print_type (type_t *type);
|
||||
void encode_type (struct dstring_s *encodking, type_t *type);
|
||||
type_t *parse_type (const char *str);
|
||||
int type_assignable (type_t *dst, type_t *src);
|
||||
int type_size (type_t *type);
|
||||
|
||||
|
|
|
@ -443,7 +443,7 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
|
|||
i < pr->scope->num_defs; i++) {
|
||||
*pr->scope->tail = pd;
|
||||
pr->scope->tail = &pd->def_next;
|
||||
pd->type = 0; //XXX
|
||||
pd->type = parse_type (qfo->strings + qd->full_type);
|
||||
pd->name = qfo->strings + qd->name;
|
||||
pd->ofs = qd->ofs;
|
||||
if (qd->num_relocs) {
|
||||
|
|
|
@ -40,6 +40,7 @@ static const char rcsid[] =
|
|||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
|
@ -302,13 +303,14 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
|
|||
dstring_appendstr (encoding, "f");
|
||||
break;
|
||||
case ev_vector:
|
||||
dstring_appendstr (encoding, "?");
|
||||
dstring_appendstr (encoding, "V");
|
||||
break;
|
||||
case ev_entity:
|
||||
dstring_appendstr (encoding, "?");
|
||||
dstring_appendstr (encoding, "E");
|
||||
break;
|
||||
case ev_field:
|
||||
dstring_appendstr (encoding, "F");
|
||||
_encode_type (encoding, type->aux_type, level + 1);
|
||||
break;
|
||||
case ev_func:
|
||||
dstring_appendstr (encoding, "(");
|
||||
|
@ -345,7 +347,7 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
|
|||
}
|
||||
break;
|
||||
case ev_quaternion:
|
||||
dstring_appendstr (encoding, "?");
|
||||
dstring_appendstr (encoding, "Q");
|
||||
break;
|
||||
case ev_integer:
|
||||
dstring_appendstr (encoding, "i");
|
||||
|
@ -393,6 +395,113 @@ encode_type (dstring_t *encoding, type_t *type)
|
|||
_encode_type (encoding, type, 0);
|
||||
}
|
||||
|
||||
static type_t *
|
||||
_parse_type (const char **str)
|
||||
{
|
||||
type_t new;
|
||||
dstring_t *name;
|
||||
const char *s;
|
||||
|
||||
memset (&new, 0, sizeof (new));
|
||||
switch (*(*str)++) {
|
||||
case 'v':
|
||||
return &type_void;
|
||||
case '*':
|
||||
return &type_string;
|
||||
case 'f':
|
||||
return &type_float;
|
||||
case 'V':
|
||||
return &type_vector;
|
||||
case 'E':
|
||||
return &type_entity;
|
||||
case 'F':
|
||||
return field_type (_parse_type (str));
|
||||
case '(':
|
||||
new.type = ev_func;
|
||||
new.aux_type = _parse_type (str);
|
||||
while (**str && **str != ')' && **str != '.')
|
||||
new.parm_types[new.num_parms++] = _parse_type (str);
|
||||
if (!**str)
|
||||
return 0;
|
||||
if (**str == '.') {
|
||||
(*str)++;
|
||||
new.num_parms = -new.num_parms - 1;
|
||||
}
|
||||
if (**str != ')')
|
||||
return 0;
|
||||
(*str)++;
|
||||
return find_type (&new);
|
||||
case '@':
|
||||
return &type_id;
|
||||
case '#':
|
||||
return &type_Class;
|
||||
case ':':
|
||||
return &type_SEL;
|
||||
case '^':
|
||||
return pointer_type (_parse_type (str));
|
||||
case 'Q':
|
||||
return &type_quaternion;
|
||||
case 'i':
|
||||
return &type_integer;
|
||||
case 'I':
|
||||
return &type_uinteger;
|
||||
case 's':
|
||||
return &type_short;
|
||||
case '{':
|
||||
name = dstring_newstr ();
|
||||
for (s = *str; *s && *s != '=' && *s !='}'; s++)
|
||||
;
|
||||
if (!*s)
|
||||
return 0;
|
||||
dstring_appendsubstr (name, *str, s - *str);
|
||||
*str = s;
|
||||
if (name->str[0])
|
||||
new.aux_type = find_struct (name->str);
|
||||
if (new.aux_type) {
|
||||
dstring_delete (name);
|
||||
if (**str == '=') {
|
||||
(*str)++;
|
||||
while (**str && **str != '}')
|
||||
_parse_type (str);
|
||||
if (**str != ')')
|
||||
return 0;
|
||||
}
|
||||
return new.aux_type;
|
||||
}
|
||||
if (**str != '=') {
|
||||
dstring_delete (name);
|
||||
return 0;
|
||||
}
|
||||
(*str)++;
|
||||
new.aux_type = new_struct (name->str);
|
||||
dstring_delete (name);
|
||||
while (**str && **str != '}')
|
||||
new_struct_field (new.aux_type, _parse_type (str), 0,
|
||||
vis_public);
|
||||
if (**str != ')')
|
||||
return 0;
|
||||
return new.aux_type;
|
||||
case '[':
|
||||
while (isdigit (**str)) {
|
||||
new.num_parms *= 10;
|
||||
new.num_parms += *(*str)++ - '0';
|
||||
}
|
||||
new.aux_type = _parse_type (str);
|
||||
if (**str != ']')
|
||||
return 0;
|
||||
(*str)++;
|
||||
return find_type (&new);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
type_t *
|
||||
parse_type (const char *str)
|
||||
{
|
||||
return _parse_type (&str);
|
||||
}
|
||||
|
||||
int
|
||||
type_assignable (type_t *dst, type_t *src)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue