00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "postgres_fe.h"
00011
00012 #include "extern.h"
00013
00014
00015
00016
00017
00018 static struct assignment *assignments;
00019
00020 void
00021 push_assignment(char *var, enum ECPGdtype value)
00022 {
00023 struct assignment *new = (struct assignment *) mm_alloc(sizeof(struct assignment));
00024
00025 new->next = assignments;
00026 new->variable = mm_alloc(strlen(var) + 1);
00027 strcpy(new->variable, var);
00028 new->value = value;
00029 assignments = new;
00030 }
00031
00032 static void
00033 drop_assignments(void)
00034 {
00035 while (assignments)
00036 {
00037 struct assignment *old_head = assignments;
00038
00039 assignments = old_head->next;
00040 free(old_head->variable);
00041 free(old_head);
00042 }
00043 }
00044
00045 static void
00046 ECPGnumeric_lvalue(char *name)
00047 {
00048 const struct variable *v = find_variable(name);
00049
00050 switch (v->type->type)
00051 {
00052 case ECPGt_short:
00053 case ECPGt_int:
00054 case ECPGt_long:
00055 case ECPGt_long_long:
00056 case ECPGt_unsigned_short:
00057 case ECPGt_unsigned_int:
00058 case ECPGt_unsigned_long:
00059 case ECPGt_unsigned_long_long:
00060 case ECPGt_const:
00061 fputs(name, yyout);
00062 break;
00063 default:
00064 mmerror(PARSE_ERROR, ET_ERROR, "variable \"%s\" must have a numeric type", name);
00065 break;
00066 }
00067 }
00068
00069
00070
00071
00072
00073 static struct descriptor *descriptors;
00074
00075 void
00076 add_descriptor(char *name, char *connection)
00077 {
00078 struct descriptor *new;
00079
00080 if (name[0] != '"')
00081 return;
00082
00083 new = (struct descriptor *) mm_alloc(sizeof(struct descriptor));
00084
00085 new->next = descriptors;
00086 new->name = mm_alloc(strlen(name) + 1);
00087 strcpy(new->name, name);
00088 if (connection)
00089 {
00090 new->connection = mm_alloc(strlen(connection) + 1);
00091 strcpy(new->connection, connection);
00092 }
00093 else
00094 new->connection = connection;
00095 descriptors = new;
00096 }
00097
00098 void
00099 drop_descriptor(char *name, char *connection)
00100 {
00101 struct descriptor *i;
00102 struct descriptor **lastptr = &descriptors;
00103
00104 if (name[0] != '"')
00105 return;
00106
00107 for (i = descriptors; i; lastptr = &i->next, i = i->next)
00108 {
00109 if (strcmp(name, i->name) == 0)
00110 {
00111 if ((!connection && !i->connection)
00112 || (connection && i->connection
00113 && strcmp(connection, i->connection) == 0))
00114 {
00115 *lastptr = i->next;
00116 if (i->connection)
00117 free(i->connection);
00118 free(i->name);
00119 free(i);
00120 return;
00121 }
00122 }
00123 }
00124 mmerror(PARSE_ERROR, ET_WARNING, "descriptor \"%s\" does not exist", name);
00125 }
00126
00127 struct descriptor
00128 *
00129 lookup_descriptor(char *name, char *connection)
00130 {
00131 struct descriptor *i;
00132
00133 if (name[0] != '"')
00134 return NULL;
00135
00136 for (i = descriptors; i; i = i->next)
00137 {
00138 if (strcmp(name, i->name) == 0)
00139 {
00140 if ((!connection && !i->connection)
00141 || (connection && i->connection
00142 && strcmp(connection, i->connection) == 0))
00143 return i;
00144 }
00145 }
00146 mmerror(PARSE_ERROR, ET_WARNING, "descriptor \"%s\" does not exist", name);
00147 return NULL;
00148 }
00149
00150 void
00151 output_get_descr_header(char *desc_name)
00152 {
00153 struct assignment *results;
00154
00155 fprintf(yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
00156 for (results = assignments; results != NULL; results = results->next)
00157 {
00158 if (results->value == ECPGd_count)
00159 ECPGnumeric_lvalue(results->variable);
00160 else
00161 mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
00162 }
00163
00164 drop_assignments();
00165 fprintf(yyout, "));\n");
00166 whenever_action(3);
00167 }
00168
00169 void
00170 output_get_descr(char *desc_name, char *index)
00171 {
00172 struct assignment *results;
00173
00174 fprintf(yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
00175 for (results = assignments; results != NULL; results = results->next)
00176 {
00177 const struct variable *v = find_variable(results->variable);
00178
00179 switch (results->value)
00180 {
00181 case ECPGd_nullable:
00182 mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
00183 break;
00184 case ECPGd_key_member:
00185 mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
00186 break;
00187 default:
00188 break;
00189 }
00190 fprintf(yyout, "%s,", get_dtype(results->value));
00191 ECPGdump_a_type(yyout, v->name, v->type, v->brace_level, NULL, NULL, -1, NULL, NULL, mm_strdup("0"), NULL, NULL);
00192 }
00193 drop_assignments();
00194 fputs("ECPGd_EODT);\n", yyout);
00195
00196 whenever_action(2 | 1);
00197 }
00198
00199 void
00200 output_set_descr_header(char *desc_name)
00201 {
00202 struct assignment *results;
00203
00204 fprintf(yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
00205 for (results = assignments; results != NULL; results = results->next)
00206 {
00207 if (results->value == ECPGd_count)
00208 ECPGnumeric_lvalue(results->variable);
00209 else
00210 mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
00211 }
00212
00213 drop_assignments();
00214 fprintf(yyout, "));\n");
00215 whenever_action(3);
00216 }
00217
00218 static const char *
00219 descriptor_item_name(enum ECPGdtype itemcode)
00220 {
00221 switch (itemcode)
00222 {
00223 case ECPGd_cardinality:
00224 return "CARDINALITY";
00225 case ECPGd_count:
00226 return "COUNT";
00227 case ECPGd_data:
00228 return "DATA";
00229 case ECPGd_di_code:
00230 return "DATETIME_INTERVAL_CODE";
00231 case ECPGd_di_precision:
00232 return "DATETIME_INTERVAL_PRECISION";
00233 case ECPGd_indicator:
00234 return "INDICATOR";
00235 case ECPGd_key_member:
00236 return "KEY_MEMBER";
00237 case ECPGd_length:
00238 return "LENGTH";
00239 case ECPGd_name:
00240 return "NAME";
00241 case ECPGd_nullable:
00242 return "NULLABLE";
00243 case ECPGd_octet:
00244 return "OCTET_LENGTH";
00245 case ECPGd_precision:
00246 return "PRECISION";
00247 case ECPGd_ret_length:
00248 return "RETURNED_LENGTH";
00249 case ECPGd_ret_octet:
00250 return "RETURNED_OCTET_LENGTH";
00251 case ECPGd_scale:
00252 return "SCALE";
00253 case ECPGd_type:
00254 return "TYPE";
00255 default:
00256 return NULL;
00257 }
00258 }
00259
00260 void
00261 output_set_descr(char *desc_name, char *index)
00262 {
00263 struct assignment *results;
00264
00265 fprintf(yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
00266 for (results = assignments; results != NULL; results = results->next)
00267 {
00268 const struct variable *v = find_variable(results->variable);
00269
00270 switch (results->value)
00271 {
00272 case ECPGd_cardinality:
00273 case ECPGd_di_code:
00274 case ECPGd_di_precision:
00275 case ECPGd_precision:
00276 case ECPGd_scale:
00277 mmerror(PARSE_ERROR, ET_FATAL, "descriptor item \"%s\" is not implemented",
00278 descriptor_item_name(results->value));
00279 break;
00280
00281 case ECPGd_key_member:
00282 case ECPGd_name:
00283 case ECPGd_nullable:
00284 case ECPGd_octet:
00285 case ECPGd_ret_length:
00286 case ECPGd_ret_octet:
00287 mmerror(PARSE_ERROR, ET_FATAL, "descriptor item \"%s\" cannot be set",
00288 descriptor_item_name(results->value));
00289 break;
00290
00291 case ECPGd_data:
00292 case ECPGd_indicator:
00293 case ECPGd_length:
00294 case ECPGd_type:
00295 fprintf(yyout, "%s,", get_dtype(results->value));
00296 ECPGdump_a_type(yyout, v->name, v->type, v->brace_level, NULL, NULL, -1, NULL, NULL, mm_strdup("0"), NULL, NULL);
00297 break;
00298
00299 default:
00300 ;
00301 }
00302 }
00303 drop_assignments();
00304 fputs("ECPGd_EODT);\n", yyout);
00305
00306 whenever_action(2 | 1);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315 #define MAX_DESCRIPTOR_NAMELEN 128
00316 struct variable *
00317 descriptor_variable(const char *name, int input)
00318 {
00319 static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
00320 static struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
00321 static struct variable varspace[2] = {
00322 {descriptor_names[0], &descriptor_type, 0, NULL},
00323 {descriptor_names[1], &descriptor_type, 0, NULL}
00324 };
00325
00326 strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
00327 return &varspace[input];
00328 }
00329
00330 struct variable *
00331 sqlda_variable(const char *name)
00332 {
00333 struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
00334
00335 p->name = mm_strdup(name);
00336 p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
00337 p->type->type = ECPGt_sqlda;
00338 p->type->size = NULL;
00339 p->type->struct_sizeof = NULL;
00340 p->type->u.element = NULL;
00341 p->type->counter = 0;
00342 p->brace_level = 0;
00343 p->next = NULL;
00344
00345 return p;
00346 }