#include <nidl.h>
#include <ast.h>
#include <cspell.h>
#include <cspeldcl.h>
#include <genpipes.h>
#include <bedeck.h>
#define MAX_TAIL_LEN 15
typedef enum {p_k, a_k, f_k} type_kind_t;
typedef struct {
int len;
struct {
type_kind_t kind;
union {
struct {
AST_array_n_t *array;
boolean in_typedef_or_struct;
} array_info;
struct {
AST_parameter_n_t *param_list;
boolean function_def;
} function_info;
} content;
} vec[MAX_TAIL_LEN];
} type_tail_t;
static void CSPELL_add_paren_to_tail
(
type_tail_t *tail
)
{
int i;
i = (tail->len) ++;
if (tail->len > MAX_TAIL_LEN) INTERNAL_ERROR("Data structure too compilicated; Tail array overflow");
(tail->vec)[i].kind = p_k;
}
static void CSPELL_add_array_to_tail
(
type_tail_t *tail,
AST_array_n_t *array,
boolean in_typedef_or_struct
)
{
int i;
i = (tail->len) ++;
if (tail->len > MAX_TAIL_LEN) INTERNAL_ERROR("Data structure too compilicated; Tail array overflow");
(tail->vec)[i].kind = a_k;
(tail->vec)[i].content.array_info.array = array;
(tail->vec)[i].content.array_info.in_typedef_or_struct =
in_typedef_or_struct;
}
static void CSPELL_add_func_to_tail
(
type_tail_t *tail,
AST_parameter_n_t *pl,
boolean function_def
)
{
int i;
i = (tail->len) ++;
if (tail->len > MAX_TAIL_LEN) INTERNAL_ERROR("Data structure too compilicated; Tail array overflow");
(tail->vec)[i].kind = f_k;
(tail->vec)[i].content.function_info.param_list = pl;
(tail->vec)[i].content.function_info.function_def = function_def;
}
static void CSPELL_array_bounds (
FILE *fid,
AST_array_n_t *array,
boolean in_typedef_or_struct
);
static void CSPELL_function_sig (
FILE *fid,
AST_parameter_n_t *pp,
boolean func_def,
boolean encoding_services
);
static void CSPELL_type_tail
(
FILE *fid,
type_tail_t *tail,
boolean encoding_services
)
{
int i;
for (i = 0; i < tail->len; i++)
switch (tail->vec[i].kind) {
case p_k:
fprintf (fid, ")");
break;
case a_k:
CSPELL_array_bounds (
fid,
tail->vec[i].content.array_info.array,
tail->vec[i].content.array_info.in_typedef_or_struct);
break;
case f_k:
CSPELL_function_sig (
fid,
tail->vec[i].content.function_info.param_list,
tail->vec[i].content.function_info.function_def,
encoding_services);
break;
default:
INTERNAL_ERROR("Invalid tail kind");
}
}
void spell_name
(
FILE *fid,
NAMETABLE_id_t name
)
{
char const *str;
NAMETABLE_id_to_string (name, &str);
fprintf (fid, "%s", str);
}
static void CSPELL_type_exp (
FILE *fid,
AST_type_n_t *tp,
type_tail_t *tail,
AST_type_n_t *in_typedef,
boolean in_struct,
boolean func_def,
boolean spell_tag
);
boolean CSPELL_scalar_type_suffix
(
FILE *fid,
AST_type_n_t *tp
)
{
boolean result = true;
switch (tp->kind) {
case AST_small_unsigned_k:
case AST_short_unsigned_k:
case AST_long_unsigned_k:
case AST_hyper_unsigned_k:
fprintf (fid, "u");
default:
break;
}
switch (tp->kind) {
case AST_boolean_k:
fprintf (fid, "boolean");
break;
case AST_byte_k:
fprintf (fid, "byte");
break;
case AST_character_k:
fprintf (fid, "char");
break;
case AST_small_integer_k:
case AST_small_unsigned_k:
fprintf (fid, "small_int");
break;
case AST_short_integer_k:
case AST_short_unsigned_k:
fprintf (fid, "short_int");
break;
case AST_long_integer_k:
case AST_long_unsigned_k:
fprintf (fid, "long_int");
break;
case AST_hyper_integer_k:
case AST_hyper_unsigned_k:
fprintf (fid, "hyper_int");
break;
case AST_short_float_k:
fprintf (fid, "short_float");
break;
case AST_long_float_k:
fprintf (fid, "long_float");
break;
case AST_enum_k:
fprintf (fid, "enum");
break;
default:
result = false;
}
return result;
}
static void spell_idl_scalar_type_name
(
FILE *fid,
AST_type_n_t *tp
)
{
fprintf(fid, "idl_");
if (CSPELL_scalar_type_suffix(fid, tp))
fprintf(fid, " ");
else
INTERNAL_ERROR("Invalid type kind");
}
static void CSPELL_function_sig
(
FILE *fid,
AST_parameter_n_t *pp,
boolean func_def ATTRIBUTE_UNUSED,
boolean encoding_services
)
{
fprintf (fid, "(\n");
CSPELL_parameter_list (fid, pp, encoding_services);
fprintf (fid, "\n)");
}
static boolean DDBE_array_is_C_like
(
AST_array_n_t *array
)
{
int i;
AST_array_index_n_t *index_array_ptr;
index_array_ptr = array->index_vec;
for (i = 1; i < array->index_count; i++)
{
index_array_ptr ++;
if ( !(AST_FIXED_LOWER_SET(index_array_ptr))
|| !(AST_FIXED_UPPER_SET(index_array_ptr)) )
{
return( false );
}
}
return( true );
}
static void CSPELL_array_bounds
(
FILE *fid,
AST_array_n_t *array,
boolean in_typedef_or_struct
)
{
int i;
AST_array_index_n_t *index_array_ptr;
long array_dim_size;
if ( ! DDBE_array_is_C_like(array) )
{
if( ! in_typedef_or_struct ) fprintf (fid, "[]");
else fprintf (fid, "[1]");
return;
}
index_array_ptr = array->index_vec;
for (i = 0; i < array->index_count; i++) {
if ( (AST_FIXED_LOWER_SET(index_array_ptr))
&& (AST_FIXED_UPPER_SET(index_array_ptr)) ) {
array_dim_size = index_array_ptr->upper_bound->value.int_val
- index_array_ptr->lower_bound->value.int_val + 1;
fprintf (fid, "[%ld]", array_dim_size);
}
else {
if ((i == 0) && ( ! in_typedef_or_struct )) fprintf (fid, "[]");
else fprintf (fid, "[1]");
}
index_array_ptr ++;
}
}
void CSPELL_pipe_struct_routine_decl
(
FILE *fid,
AST_type_n_t *p_pipe_type,
BE_pipe_routine_k_t routine_kind,
boolean cast
)
{
type_tail_t tail;
const char *name = "";
if (!cast)
{
name = (routine_kind == BE_pipe_push_k) ? "push" :
((routine_kind == BE_pipe_pull_k) ? "pull" : "alloc");
}
fprintf( fid, "void (* %s)(\n",name);
fprintf (fid, "rpc_ss_pipe_state_t state,\n" );
if ( routine_kind == BE_pipe_alloc_k )
{
fprintf( fid, "idl_ulong_int bsize,\n" );
}
tail.len = 0;
CSPELL_type_exp (fid, p_pipe_type->type_structure.pipe->base_type,
&tail, NULL, false, false, true);
fprintf( fid, "%s*buf,\n",
(routine_kind == BE_pipe_alloc_k) ? "*" : "");
CSPELL_type_tail (fid, &tail, false);
if ( routine_kind == BE_pipe_pull_k )
{
fprintf( fid, "idl_ulong_int esize,\n" );
}
fprintf( fid, "idl_ulong_int %c%ccount\n",
((routine_kind == BE_pipe_push_k) ? ' ' : '*'),
((routine_kind == BE_pipe_alloc_k) ? 'b' : 'e') );
fprintf (fid, ")" );
if (!cast) fprintf (fid, ";\n");
}
static void CSPELL_pipe_def
(
FILE *fid,
AST_type_n_t *p_pipe_type
)
{
fprintf( fid, "struct " );
spell_name (fid, p_pipe_type->name);
fprintf( fid, " {\n" );
CSPELL_pipe_struct_routine_decl( fid, p_pipe_type, BE_pipe_pull_k, FALSE );
CSPELL_pipe_struct_routine_decl( fid, p_pipe_type, BE_pipe_push_k, FALSE );
CSPELL_pipe_struct_routine_decl( fid, p_pipe_type, BE_pipe_alloc_k, FALSE );
fprintf( fid, "rpc_ss_pipe_state_t state;\n" );
fprintf( fid, "} " );
}
static void CSPELL_type_exp
(
FILE *fid,
AST_type_n_t *tp,
type_tail_t *tail,
AST_type_n_t *in_typedef,
boolean in_struct,
boolean func_def,
boolean spell_tag
)
{
AST_field_n_t *fp;
AST_arm_n_t *cp;
AST_disc_union_n_t *vp;
AST_constant_n_t *ecp;
int pointer_count;
AST_type_n_t *pointee_tp;
boolean parenthesized;
boolean first = true;
boolean n_e_union;
if (in_typedef == tp && tp->defined_as)
CSPELL_type_exp (
fid,
tp->defined_as,
tail,
in_typedef,
in_struct,
func_def,
spell_tag);
else if (in_typedef != tp && tp->rep_as_type
&& !(in_typedef != NULL && in_typedef->name == tp->name))
{
fprintf( fid, "/* Type must appear in user header or IDL */ " );
spell_name (fid, tp->rep_as_type->type_name);
fprintf (fid, " ");
}
else if (in_typedef != tp && tp->cs_char_type
&& !(in_typedef != NULL && in_typedef->name == tp->name))
{
fprintf( fid, "/* Type must appear in user header or IDL */ " );
spell_name (fid, tp->cs_char_type->type_name);
fprintf (fid, " ");
}
else if (AST_DEF_AS_TAG_SET(tp))
{
if (tp->kind == AST_disc_union_k
&& tp->type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID)
fprintf(fid, "union ");
else
fprintf (fid, "struct ");
if (tp->kind == AST_structure_k)
spell_name (fid, tp->type_structure.structure->tag_name);
else if (tp->kind == AST_disc_union_k)
spell_name (fid, tp->type_structure.disc_union->tag_name);
fprintf (fid, " ");
}
else if (in_typedef != tp && tp->name != NAMETABLE_NIL_ID)
{
spell_name (fid, tp->name);
fprintf (fid, " ");
}
else if (in_typedef == NULL && tp->kind == AST_structure_k &&
tp->type_structure.structure->tag_name != NAMETABLE_NIL_ID)
{
fprintf (fid, "struct ");
spell_name (fid, tp->type_structure.structure->tag_name);
fprintf (fid, " ");
}
else if (in_typedef == NULL && tp->kind == AST_disc_union_k &&
tp->type_structure.disc_union->tag_name != NAMETABLE_NIL_ID)
{
if (tp->type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID)
fprintf (fid, "union ");
else
fprintf (fid, "struct ");
spell_name (fid, tp->type_structure.disc_union->tag_name);
fprintf (fid, " ");
}
else switch (tp->kind) {
case AST_boolean_k:
case AST_byte_k:
case AST_small_integer_k:
case AST_small_unsigned_k:
case AST_short_integer_k:
case AST_short_unsigned_k:
case AST_long_integer_k:
case AST_long_unsigned_k:
case AST_hyper_integer_k:
case AST_hyper_unsigned_k:
case AST_character_k:
case AST_short_float_k:
case AST_long_float_k:
spell_idl_scalar_type_name (fid, tp);
break;
case AST_handle_k:
fprintf (fid, "handle_t ");
break;
case AST_enum_k:
fprintf (fid, "enum {");
for (ecp = tp->type_structure.enumeration->enum_constants;
ecp != NULL; ecp = ecp->next) {
if (first)
first = false;
else
fprintf (fid, ",\n");
spell_name (fid, ecp->name);
fprintf(fid, " = %ld", ecp->value.int_val);
}
fprintf (fid, "} ");
break;
case AST_structure_k:
fprintf (fid, "struct ");
if ( spell_tag )
spell_name (fid, tp->type_structure.structure->tag_name);
fprintf (fid, " {\n");
for (fp = tp->type_structure.structure->fields; fp != NULL;
fp = fp->next) {
CSPELL_typed_name (
fid,
fp->type,
fp->name,
in_typedef,
true,
true,
false);
fprintf (fid, ";\n");
}
fprintf (fid, "} ");
break;
case AST_disc_union_k:
vp = tp->type_structure.disc_union;
n_e_union = (vp->discrim_name == NAMETABLE_NIL_ID);
if ( ! n_e_union )
{
fprintf (fid, "struct ");
if ( spell_tag )
spell_name (fid, tp->type_structure.disc_union->tag_name);
fprintf (fid, " {\n");
CSPELL_typed_name (
fid,
vp->discrim_type,
vp->discrim_name,
in_typedef,
true,
true,
false);
fprintf (fid, ";\n");
}
fprintf (fid, "union ");
if ( n_e_union && spell_tag )
spell_name (fid, tp->type_structure.disc_union->tag_name);
fprintf (fid, " {\n");
for (cp = vp->arms; cp != NULL; cp = cp->next)
{
CSPELL_labels (fid, cp->labels);
if (cp->type == NULL)
fprintf (fid, "/* Empty arm */\n");
else
{
CSPELL_typed_name (
fid,
cp->type,
cp->name,
in_typedef,
true,
true,
false);
fprintf (fid, ";\n");
}
}
fprintf (fid, "} ");
if ( ! n_e_union )
{
spell_name (fid, vp->union_name);
fprintf (fid, ";\n");
fprintf (fid, "} ");
}
break;
case AST_pipe_k:
CSPELL_pipe_def(fid, tp);
break;
case AST_void_k:
fprintf (fid, "void ");
break;
case AST_array_k:
CSPELL_add_array_to_tail (
tail,
tp->type_structure.array,
(tp == in_typedef) || in_struct);
CSPELL_type_exp (
fid,
tp->type_structure.array->element_type,
tail,
in_typedef,
in_struct,
false,
spell_tag);
break;
case AST_pointer_k:
pointer_count = 0;
pointee_tp = tp;
while (pointee_tp->kind == AST_pointer_k
&& (in_typedef == pointee_tp ||
pointee_tp->name == NAMETABLE_NIL_ID))
{
pointee_tp = pointee_tp->type_structure.pointer->pointee_type;
pointer_count++;
}
if (( parenthesized = (pointee_tp->kind == AST_array_k
|| pointee_tp->kind == AST_function_k)))
CSPELL_add_paren_to_tail (tail);
if (pointee_tp->kind == AST_void_k) {
fprintf (fid, "idl_void_p_t ");
pointer_count--;
}
else
CSPELL_type_exp (
fid,
pointee_tp,
tail,
in_typedef,
in_struct,
false,
spell_tag);
if (parenthesized)
fprintf (fid, "(");
for (; pointer_count; pointer_count--)
fprintf (fid, "*");
break;
case AST_function_k:
CSPELL_add_func_to_tail(
tail,
tp->type_structure.function->parameters,
func_def);
CSPELL_type_exp(
fid,
tp->type_structure.function->result->type,
tail,
in_typedef,
in_struct,
false,
true);
break;
default:
INTERNAL_ERROR("Unknown type kind in CSPELL_type_exp");
}
}
void CSPELL_typed_name
(
FILE *fid,
AST_type_n_t *type,
NAMETABLE_id_t name,
AST_type_n_t *in_typedef,
boolean in_struct,
boolean spell_tag,
boolean encoding_services
)
{
type_tail_t tail;
tail.len = 0;
CSPELL_type_exp (fid, type, &tail, in_typedef, in_struct, false, spell_tag);
spell_name (fid, name);
CSPELL_type_tail (fid, &tail, encoding_services);
}
void CSPELL_function_def_header
(
FILE *fid,
AST_operation_n_t *oper,
NAMETABLE_id_t name
)
{
type_tail_t tail;
AST_type_n_t func_type_node;
func_type_node = *BE_function_p;
func_type_node.type_structure.function = oper;
tail.len = 0;
CSPELL_type_exp (fid, &func_type_node, &tail, NULL, false, true, true);
spell_name (fid, name);
CSPELL_type_tail ( fid, &tail,
(AST_ENCODE_SET(oper) || AST_DECODE_SET(oper)) );
}
void CSPELL_type_exp_simple
(
FILE *fid,
AST_type_n_t *tp
)
{
CSPELL_typed_name(fid, tp, NAMETABLE_NIL_ID, NULL, false, true, false);
}
void CSPELL_var_decl
(
FILE *fid,
AST_type_n_t *type,
NAMETABLE_id_t name
)
{
CSPELL_typed_name (fid, type, name, NULL, false, true, false);
fprintf (fid, ";\n");
}
void CSPELL_cast_exp
(
FILE *fid,
AST_type_n_t *tp
)
{
fprintf (fid, "(");
CSPELL_typed_name (fid, tp, NAMETABLE_NIL_ID, NULL, false, true, false);
fprintf (fid, ")");
}
void CSPELL_ptr_cast_exp
(
FILE *fid,
AST_type_n_t *tp
)
{
AST_type_n_t pointer_type;
AST_pointer_n_t pointer;
memset(&pointer_type, 0, sizeof(pointer_type));
pointer_type.kind = AST_pointer_k;
pointer_type.type_structure.pointer = &pointer;
memset(&pointer, 0, sizeof(pointer));
pointer.pointee_type = tp;
CSPELL_cast_exp(fid, &pointer_type);
}
void DDBE_spell_manager_param_cast
(
FILE *fid,
AST_type_n_t *tp
)
{
type_tail_t tail;
AST_type_n_t *tp_for_type_exp;
AST_type_n_t array_slice_type;
AST_array_n_t array_slice_desc;
fprintf (fid, "(");
tail.len = 0;
if (tp->kind == AST_array_k)
{
if ((tp->type_structure.array->index_count == 1)
|| !DDBE_array_is_C_like(tp->type_structure.array))
tp_for_type_exp = tp->type_structure.array->element_type;
else
{
array_slice_desc.element_type
= tp->type_structure.array->element_type;
array_slice_desc.index_count
= tp->type_structure.array->index_count - 1;
array_slice_desc.index_vec
= &(tp->type_structure.array->index_vec[1]);
array_slice_type = *tp;
array_slice_type.name = NAMETABLE_NIL_ID;
array_slice_type.type_structure.array = &array_slice_desc;
tp_for_type_exp = &array_slice_type;
}
}
else
tp_for_type_exp = tp;
CSPELL_type_exp (fid, tp_for_type_exp, &tail, NULL, false, false, true);
if (tp->kind == AST_array_k)
fprintf (fid, "(*)");
CSPELL_type_tail (fid, &tail, false);
fprintf (fid, ")");
}
void CSPELL_midl_compatibility_allocators
(
FILE *fid
)
{
fprintf (fid,
"static inline idl_void_p_t IDL_midl_user_allocate(\n"
" idl_void_p_t context, idl_size_t nbytes)\n"
"{\n"
" (void)context;\n"
" return midl_user_allocate(nbytes);\n"
"}\n\n"
"static inline void IDL_midl_user_free(\n"
" idl_void_p_t context, idl_void_p_t ptr)\n"
"{\n"
" (void)context;\n"
" midl_user_free(ptr);\n"
"}\n\n");
}
void CSPELL_suppress_stub_warnings
(
FILE *fid
)
{
fprintf(fid, "#if __GNUC__\n");
fprintf(fid, "#pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n");
fprintf(fid, "#pragma GCC diagnostic ignored \"-Wmissing-braces\"\n");
fprintf(fid, "#endif\n");
}
void CSPELL_restore_stub_warnings
(
FILE *fid ATTRIBUTE_UNUSED
)
{
}