📄 type.c
字号:
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.77.2.1 2008/03/02 10:57:21 meskes Exp $ */#include "postgres_fe.h"#include "extern.h"#define indicator_set ind_type != NULL && ind_type->type != ECPGt_NO_INDICATORstatic struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};/* malloc + error check */void *mm_alloc(size_t size){ void *ptr = malloc(size); if (ptr == NULL) mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n"); return ptr;}/* strdup + error check */char *mm_strdup(const char *string){ char *new = strdup(string); if (new == NULL) mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n"); return new;}/* duplicate memberlist */struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member * rm){ struct ECPGstruct_member *new = NULL; while (rm) { struct ECPGtype *type; switch (rm->type->type) { case ECPGt_struct: case ECPGt_union: type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof); break; case ECPGt_array: /* * if this array does contain a struct again, we have to * create the struct too */ if (rm->type->u.element->type == ECPGt_struct) type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->struct_sizeof); else type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->lineno), rm->type->size); break; default: type = ECPGmake_simple_type(rm->type->type, rm->type->size, rm->type->lineno); break; } ECPGmake_struct_member(rm->name, type, &new); rm = rm->next; } return (new);}/* The NAME argument is copied. The type argument is preserved as a pointer. */voidECPGmake_struct_member(char *name, struct ECPGtype * type, struct ECPGstruct_member ** start){ struct ECPGstruct_member *ptr, *ne = (struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member)); ne->name = mm_strdup(name); ne->type = type; ne->next = NULL; for (ptr = *start; ptr && ptr->next; ptr = ptr->next); if (ptr) ptr->next = ne; else *start = ne;}struct ECPGtype *ECPGmake_simple_type(enum ECPGttype type, char *size, int lineno){ struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype)); ne->type = type; ne->size = size; ne->u.element = NULL; ne->struct_sizeof = NULL; ne->lineno = lineno; /* only needed for varchar */ return ne;}struct ECPGtype *ECPGmake_array_type(struct ECPGtype * type, char *size){ struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, size, 0); ne->u.element = type; return ne;}struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *struct_sizeof){ struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0); ne->u.members = ECPGstruct_member_dup(rm); ne->struct_sizeof = struct_sizeof; return ne;}static const char *get_type(enum ECPGttype type){ switch (type) { case ECPGt_char: return ("ECPGt_char"); break; case ECPGt_unsigned_char: return ("ECPGt_unsigned_char"); break; case ECPGt_short: return ("ECPGt_short"); break; case ECPGt_unsigned_short: return ("ECPGt_unsigned_short"); break; case ECPGt_int: return ("ECPGt_int"); break; case ECPGt_unsigned_int: return ("ECPGt_unsigned_int"); break; case ECPGt_long: return ("ECPGt_long"); break; case ECPGt_unsigned_long: return ("ECPGt_unsigned_long"); break; case ECPGt_long_long: return ("ECPGt_long_long"); break; case ECPGt_unsigned_long_long: return ("ECPGt_unsigned_long_long"); break; case ECPGt_float: return ("ECPGt_float"); break; case ECPGt_double: return ("ECPGt_double"); break; case ECPGt_bool: return ("ECPGt_bool"); break; case ECPGt_varchar: return ("ECPGt_varchar"); case ECPGt_NO_INDICATOR: /* no indicator */ return ("ECPGt_NO_INDICATOR"); break; case ECPGt_char_variable: /* string that should not be quoted */ return ("ECPGt_char_variable"); break; case ECPGt_const: /* constant string quoted */ return ("ECPGt_const"); break; case ECPGt_decimal: return ("ECPGt_decimal"); break; case ECPGt_numeric: return ("ECPGt_numeric"); break; case ECPGt_interval: return ("ECPGt_interval"); break; case ECPGt_descriptor: return ("ECPGt_descriptor"); break; case ECPGt_date: return ("ECPGt_date"); break; case ECPGt_timestamp: return ("ECPGt_timestamp"); break; default: mmerror(PARSE_ERROR, ET_ERROR, "illegal variable type %d\n", type); } return NULL;}/* Dump a type. The type is dumped as: type-tag <comma> - enum ECPGttype reference-to-variable <comma> - char * size <comma> - long size of this field (if varchar) arrsize <comma> - long number of elements in the arr offset <comma> - offset to the next element Where: type-tag is one of the simple types or varchar. reference-to-variable can be a reference to a struct element. arrsize is the size of the array in case of array fetches. Otherwise 0. size is the maxsize in case it is a varchar. Otherwise it is the size of the variable (required to do array fetches of structs). */static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, char *varcharsize, char *arrsiz, const char *siz, const char *prefix, int);static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsiz, struct ECPGtype * type, struct ECPGtype * ind_type, const char *offset, const char *prefix, const char *ind_prefix);voidECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type, const char *ind_name, struct ECPGtype * ind_type, const char *prefix, const char *ind_prefix, char *arr_str_siz, const char *struct_sizeof, const char *ind_struct_sizeof){ switch (type->type) { case ECPGt_array: if (indicator_set && ind_type->type != ECPGt_array) mmerror(INDICATOR_NOT_ARRAY, ET_FATAL, "Indicator for array/pointer has to be array/pointer.\n"); switch (type->u.element->type) { case ECPGt_array: mmerror(PARSE_ERROR, ET_ERROR, "No nested arrays allowed (except strings)"); /* array of array */ break; case ECPGt_struct: case ECPGt_union: ECPGdump_a_struct(o, name, ind_name, type->size, type->u.element, (ind_type == NULL) ? NULL : ((ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element), NULL, prefix, ind_prefix); break; default: if (!IS_SIMPLE_TYPE(type->u.element->type)) base_yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org"); ECPGdump_a_simple(o, name, type->u.element->type, type->u.element->size, type->size, NULL, prefix, type->u.element->lineno); if (ind_type != NULL) { if (ind_type->type == ECPGt_NO_INDICATOR) ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, make_str("-1"), NULL, ind_prefix, 0); else { ECPGdump_a_simple(o, ind_name, ind_type->u.element->type, ind_type->u.element->size, ind_type->size, NULL, ind_prefix, 0); } } } break; case ECPGt_struct: if (indicator_set && ind_type->type != ECPGt_struct) mmerror(INDICATOR_NOT_STRUCT, ET_FATAL, "Indicator for struct has to be struct.\n"); ECPGdump_a_struct(o, name, ind_name, make_str("1"), type, ind_type, NULL, prefix, ind_prefix); break; case ECPGt_union: /* cannot dump a complete union */ base_yyerror("Type of union has to be specified"); break; case ECPGt_char_variable: if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array)) mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n"); ECPGdump_a_simple(o, name, type->type, make_str("1"), (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("1"), struct_sizeof, prefix, 0); if (ind_type != NULL) ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("-1"), ind_struct_sizeof, ind_prefix, 0); break; case ECPGt_descriptor: if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array)) mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n"); ECPGdump_a_simple(o, name, type->type, NULL, make_str("-1"), NULL, prefix, 0); if (ind_type != NULL) ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, make_str("-1"), NULL, ind_prefix, 0); break; default: if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array)) mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n"); ECPGdump_a_simple(o, name, type->type, type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("-1"), struct_sizeof, prefix, type->lineno); if (ind_type != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -