📄 preproc.y
字号:
/* Copyright comment */%{#include <stdio.h>#include <string.h>#include <stdlib.h>#include "postgres.h"#include "access/htup.h"#include "catalog/catname.h"#include "utils/numeric.h"#include "extern.h"#ifdef MULTIBYTE#include "mb/pg_wchar.h"#endif#define STRUCT_DEPTH 128/* * Variables containing simple states. */int struct_level = 0;char errortext[128];static char *connection = NULL;static int QueryIsRule = 0, ForUpdateNotAllowed = 0;static struct this_type actual_type[STRUCT_DEPTH];static char *actual_storage[STRUCT_DEPTH];/* temporarily store struct members while creating the data structure */struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};/* * Handle the filename and line numbering. */char * input_filename = NULL;voidoutput_line_number(){ if (input_filename) fprintf(yyout, "\n#line %d \"%s\"\n", yylineno + 1, input_filename);}static voidoutput_simple_statement(char *cmd){ fputs(cmd, yyout); output_line_number(); free(cmd);}/* * store the whenever action here */static struct when when_error, when_nf, when_warn;static voidprint_action(struct when *w){ switch (w->code) { case W_SQLPRINT: fprintf(yyout, "sqlprint();"); break; case W_GOTO: fprintf(yyout, "goto %s;", w->command); break; case W_DO: fprintf(yyout, "%s;", w->command); break; case W_STOP: fprintf(yyout, "exit (1);"); break; case W_BREAK: fprintf(yyout, "break;"); break; default: fprintf(yyout, "{/* %d not implemented yet */}", w->code); break; }}static voidwhenever_action(int mode){ if ((mode&1) == 1 && when_nf.code != W_NOTHING) { output_line_number(); fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) "); print_action(&when_nf); } if (when_warn.code != W_NOTHING) { output_line_number(); fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') "); print_action(&when_warn); } if (when_error.code != W_NOTHING) { output_line_number(); fprintf(yyout, "\nif (sqlca.sqlcode < 0) "); print_action(&when_error); } if ((mode&2) == 2) fputc('}', yyout); output_line_number();}/* * Handling of variables. *//* * brace level counter */int braces_open;static struct variable * allvariables = NULL;static struct variable *new_variable(const char * name, struct ECPGtype * type){ struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable)); p->name = mm_strdup(name); p->type = type; p->brace_level = braces_open; p->next = allvariables; allvariables = p; return(p);}static struct variable * find_variable(char * name);static struct variable *find_struct_member(char *name, char *str, struct ECPGstruct_member *members){ char *next = strchr(++str, '.'), c = '\0'; if (next != NULL) { c = *next; *next = '\0'; } for (; members; members = members->next) { if (strcmp(members->name, str) == 0) { if (c == '\0') { /* found the end */ switch (members->typ->typ) { case ECPGt_array: return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size))); case ECPGt_struct: case ECPGt_union: return(new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ))); default: return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size))); } } else { *next = c; if (c == '-') { next++; return(find_struct_member(name, next, members->typ->u.element->u.members)); } else return(find_struct_member(name, next, members->typ->u.members)); } } } return(NULL);}static struct variable *find_struct(char * name, char *next){ struct variable * p; char c = *next; /* first get the mother structure entry */ *next = '\0'; p = find_variable(name); if (c == '-') { if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union) { sprintf(errortext, "variable %s is not a pointer", name); yyerror (errortext); } if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union) { sprintf(errortext, "variable %s is not a pointer to a structure or a union", name); yyerror (errortext); } /* restore the name, we will need it later on */ *next = c; next++; return find_struct_member(name, next, p->type->u.element->u.members); } else { if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union) { sprintf(errortext, "variable %s is neither a structure nor a union", name); yyerror (errortext); } /* restore the name, we will need it later on */ *next = c; return find_struct_member(name, next, p->type->u.members); }}static struct variable *find_simple(char * name){ struct variable * p; for (p = allvariables; p; p = p->next) { if (strcmp(p->name, name) == 0) return p; } return(NULL);}/* Note that this function will end the program in case of an unknown *//* variable */static struct variable *find_variable(char * name){ char * next; struct variable * p; if ((next = strchr(name, '.')) != NULL) p = find_struct(name, next); else if ((next = strstr(name, "->")) != NULL) p = find_struct(name, next); else p = find_simple(name); if (p == NULL) { sprintf(errortext, "The variable %s is not declared", name); yyerror(errortext); } return(p);}static voidremove_variables(int brace_level){ struct variable * p, *prev; for (p = prev = allvariables; p; p = p ? p->next : NULL) { if (p->brace_level >= brace_level) { /* remove it */ if (p == allvariables) prev = allvariables = p->next; else prev->next = p->next; ECPGfree_type(p->type); free(p->name); free(p); p = prev; } else prev = p; }}/* * Here are the variables that need to be handled on every request. * These are of two kinds: input and output. * I will make two lists for them. */struct arguments * argsinsert = NULL;struct arguments * argsresult = NULL;static voidreset_variables(void){ argsinsert = NULL; argsresult = NULL;}/* Add a variable to a request. */static voidadd_variable(struct arguments ** list, struct variable * var, struct variable * ind){ struct arguments * p = (struct arguments *)mm_alloc(sizeof(struct arguments)); p->variable = var; p->indicator = ind; p->next = *list; *list = p;}/* Dump out a list of all the variable on this list. This is a recursive function that works from the end of the list and deletes the list as we go on. */static voiddump_variables(struct arguments * list, int mode){ if (list == NULL) { return; } /* The list is build up from the beginning so lets first dump the end of the list: */ dump_variables(list->next, mode); /* Then the current element and its indicator */ ECPGdump_a_type(yyout, list->variable->name, list->variable->type, (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL, (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL); /* Then release the list element. */ if (mode != 0) free(list);}static voidcheck_indicator(struct ECPGtype *var){ /* make sure this is a valid indicator variable */ switch (var->typ) { struct ECPGstruct_member *p; case ECPGt_short: case ECPGt_int: case ECPGt_long: case ECPGt_unsigned_short: case ECPGt_unsigned_int: case ECPGt_unsigned_long: break; case ECPGt_struct: case ECPGt_union: for (p = var->u.members; p; p = p->next) check_indicator(p->typ); break; case ECPGt_array: check_indicator(var->u.element); break; default: yyerror ("indicator variable must be integer type"); break; }}static char *make1_str(const char *str){ char * res_str = (char *)mm_alloc(strlen(str) + 1); strcpy(res_str, str); return res_str;}static char *make2_str(char *str1, char *str2){ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1); strcpy(res_str, str1); strcat(res_str, str2); free(str1); free(str2); return(res_str);}static char *cat2_str(char *str1, char *str2){ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2); strcpy(res_str, str1); strcat(res_str, " "); strcat(res_str, str2); free(str1); free(str2); return(res_str);}static char *make3_str(char *str1, char *str2, char * str3){ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1); strcpy(res_str, str1); strcat(res_str, str2); strcat(res_str, str3); free(str1); free(str2); free(str3); return(res_str);} static char *cat3_str(char *str1, char *str2, char * str3){ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 3); strcpy(res_str, str1); strcat(res_str, " "); strcat(res_str, str2); strcat(res_str, " "); strcat(res_str, str3); free(str1); free(str2); free(str3); return(res_str);} static char *make4_str(char *str1, char *str2, char *str3, char *str4){ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1); strcpy(res_str, str1); strcat(res_str, str2); strcat(res_str, str3); strcat(res_str, str4); free(str1); free(str2); free(str3); free(str4); return(res_str);}static char *cat4_str(char *str1, char *str2, char *str3, char *str4){ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 4); strcpy(res_str, str1); strcat(res_str, " "); strcat(res_str, str2); strcat(res_str, " "); strcat(res_str, str3); strcat(res_str, " "); strcat(res_str, str4); free(str1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -