1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

From: Michael Meskes <meskes@topsystem.de>

Tue Apr 28 14:48:41 CEST 1998

      - Put operator "->" back into parser. Note that :foo->bar means the
        C term, but :foo ->bar means the operator "->".

Tue Apr 28 15:49:07 CEST 1998

      - Added exec sql disconnect command.
      - Allow varchar in C to be written in uppercase too.
      - Added whenever option "do break;"

Wed Apr 29 09:17:53 CEST 1998

      - Corrected parsing of C comments.
      - Also allow C++ style comments.
      - Make sure not found is only checked after commands that could
          return it.
      - Added error codes, see ecpgerror.h for details.
      - Added "exec sql <TransactionStmt> release" as disconnect statement
        for compatibility issues.

Thu Apr 30 10:42:10 CEST 1998

      - Added a -t option to disable automatic transaction start.
      - Added sqlerrd[] to sqlca struct.
      - Give back number of tuples affect in sqlca.sqlerrd[2].

Thu Apr 30 13:36:02 CEST 1998

      - Make the return code different in case of different errors.

Wed May  6 11:42:48 CEST 1998

      - Free memory if possible
      - Some bugfixes for bugs I found while changing the memory
          allocation code
      - Now able to fill complete array with one call (see test1.pgc for
          an example)
      - Set version to 2.3.0
      - Set library version to 2.1
This commit is contained in:
Marc G. Fournier
1998-05-06 13:03:47 +00:00
parent f9322c66d3
commit 6bccf64d7b
25 changed files with 1782 additions and 1634 deletions

View File

@@ -2,7 +2,7 @@ SRCDIR= ../../..
include $(SRCDIR)/Makefile.global
MAJOR_VERSION=2
MINOR_VERSION=2
MINOR_VERSION=3
PATCHLEVEL=0
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \

View File

@@ -21,6 +21,7 @@
*/
static ScanKeyword ScanKeywords[] = {
/* name value */
{"VARCHAR", S_VARCHAR},
{"auto", S_AUTO},
{"bool", S_BOOL},
{"char", S_CHAR},

View File

@@ -22,12 +22,13 @@ extern char *optarg;
#include "extern.h"
struct _include_path *include_paths;
static int no_auto_trans = 0;
static void
usage(char *progname)
{
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
fprintf(stderr, "Usage: %s: [-v] [-I include path] [ -o output file name] file1 [file2] ...\n", progname);
fprintf(stderr, "Usage: %s: [-v] [-t] [-I include path] [ -o output file name] file1 [file2] ...\n", progname);
}
static void
@@ -51,7 +52,7 @@ main(int argc, char *const argv[])
add_include_path("/usr/local/include");
add_include_path(".");
while ((c = getopt(argc, argv, "vo:I:")) != EOF)
while ((c = getopt(argc, argv, "vo:I:t")) != EOF)
{
switch (c)
{
@@ -65,23 +66,26 @@ main(int argc, char *const argv[])
case 'I':
add_include_path(optarg);
break;
case 't':
no_auto_trans = 1;
break;
case 'v':
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
fprintf(stderr, "exec sql include ... search starts here:\n");
for (ip = include_paths; ip != NULL; ip = ip->next)
fprintf(stderr, " %s\n", ip->path);
fprintf(stderr, "End of search list.\n");
return (0);
return (OK);
default:
usage(argv[0]);
return (1);
return (ILLEGAL_OPTION);
}
}
if (optind >= argc) /* no files specified */
{
usage(argv[0]);
return(1);
return(ILLEGAL_OPTION);
}
else
{
@@ -151,8 +155,8 @@ main(int argc, char *const argv[])
cur = NULL;
/* we need two includes */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
/* we need two includes and a constant */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\nconst int no_auto_trans = %d;\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, no_auto_trans);
/* and parse the source */
yyparse();
@@ -169,5 +173,5 @@ main(int argc, char *const argv[])
free(input_filename);
}
}
return (0);
return (OK);
}

View File

@@ -21,15 +21,18 @@
*/
static ScanKeyword ScanKeywords[] = {
/* name value */
{"break", SQL_BREAK},
{"call", SQL_CALL},
{"connect", SQL_CONNECT},
{"continue", SQL_CONTINUE},
{"disconnect", SQL_DISCONNECT},
{"found", SQL_FOUND},
{"go", SQL_GO},
{"goto", SQL_GOTO},
{"immediate", SQL_IMMEDIATE},
{"indicator", SQL_INDICATOR},
{"open", SQL_OPEN},
{"release", SQL_RELEASE},
{"section", SQL_SECTION},
{"sqlerror", SQL_SQLERROR},
{"sqlprint", SQL_SQLPRINT},

View File

@@ -43,3 +43,11 @@ extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
ScanKeyword * ScanECPGKeywordLookup(char *);
ScanKeyword * ScanCKeywordLookup(char *);
extern void yyerror(char *);
/* return codes */
#define OK 0
#define NO_INCLUDE_FILE 1
#define PARSE_ERROR 2
#define OUT_OF_MEMORY 3
#define ILLEGAL_OPTION 4

View File

@@ -39,6 +39,7 @@ int debugging = 0;
extern YYSTYPE yylval;
int llen;
char literal[MAX_PARSE_BUFFER];
int before_comment;
struct _yy_buffer { YY_BUFFER_STATE buffer;
long lineno;
@@ -153,7 +154,7 @@ space [ \t\n\f]
other .
/* some stuff needed for ecpg */
ccomment \/\*([^*]|\*[^/]|\*\*[^/])*\*\/
ccomment "//".*\n
exec [eE][xX][eE][cC]
include [iI][nN][cC][lL][uU][dD][eE]
sql [sS][qQ][lL]
@@ -174,12 +175,18 @@ sql [sS][qQ][lL]
%%
<SQL>{comment} { /* ignore */ }
<SQL>{xcline} { /* ignore */ }
{xcline} { /* ignore */ }
<xc>{xcstar} |
<SQL>{xcstart} { BEGIN(xc); }
<xc>{xcstar} { /* ignore */ }
{xcstart} {
fprintf(stderr,"ys = %d %d\n", YYSTATE, before_comment);
before_comment = YYSTATE;
BEGIN(xc);
fprintf(stderr,"ys = %d %d\n", YYSTATE,
before_comment);
}
<xc>{xcstop} { BEGIN(SQL); }
<xc>{xcstop} { fprintf(stderr,"ys = %d %d\n", YYSTATE, before_comment);BEGIN(before_comment); }
<xc>{xcinside} { /* ignore */ }
@@ -306,7 +313,6 @@ sql [sS][qQ][lL]
return (yytext[0]);
}
<SQL>{self} { return (yytext[0]); }
<SQL>"->" { return S_STRUCTPOINTER; }
<SQL>{operator}/-[\.0-9] {
yylval.str = strdup((char*)yytext);
return (Op);
@@ -402,7 +408,7 @@ sql [sS][qQ][lL]
return (FCONST);
}
<SQL>:{identifier} {
<SQL>:{identifier}(("->"|\.){identifier})* {
yylval.str = strdup((char*)yytext+1);
return(CVARIABLE);
}
@@ -436,6 +442,7 @@ sql [sS][qQ][lL]
<SQL>{other} { return (yytext[0]); }
<C>{exec}{space}{sql} { BEGIN SQL; return SQL_START; }
<C>{ccomment} { /* ignore */ }
<C>{identifier} {
ScanKeyword *keyword;
@@ -501,7 +508,7 @@ sql [sS][qQ][lL]
if (!yyin)
{
fprintf(stderr, "Error: Cannot open include file %s in line %d\n", yytext, yylineno);
exit(1);
exit(NO_INCLUDE_FILE);
}
input_filename = strdup(inc_file);

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ mm_alloc(size_t size)
if (ptr == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(1);
exit(OUT_OF_MEMORY);
}
return (ptr);
@@ -29,15 +29,27 @@ mm_realloc(void *ptr, size_t size)
if (ptr == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(1);
exit(OUT_OF_MEMORY);
}
return (ptr);
}
/* Constructors
Yes, I mostly write c++-code
*/
/* duplicate memberlist */
static struct ECPGstruct_member *
struct_member_dup(struct ECPGstruct_member * rm)
{
struct ECPGstruct_member *new = NULL;
while (rm)
{
ECPGmake_struct_member(rm->name, rm->typ, &new);
rm = rm->next;
}
return(new);
}
/* The NAME argument is copied. The type argument is preserved as a pointer. */
struct ECPGstruct_member *
@@ -72,22 +84,11 @@ ECPGmake_simple_type(enum ECPGttype typ, long siz)
return ne;
}
struct ECPGtype *
ECPGmake_varchar_type(enum ECPGttype typ, long siz)
{
struct ECPGtype *ne = ECPGmake_simple_type(typ, 1);
ne->size = siz;
return ne;
}
struct ECPGtype *
ECPGmake_array_type(struct ECPGtype * typ, long siz)
{
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, siz);
ne->size = siz;
ne->u.element = typ;
return ne;
@@ -98,11 +99,57 @@ ECPGmake_struct_type(struct ECPGstruct_member * rm)
{
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_struct, 1);
ne->u.members = rm;
ne->u.members = struct_member_dup(rm);
return ne;
}
static const char *get_type(enum ECPGttype typ)
{
switch (typ)
{
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_int");
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;
default:
abort();
}
}
/* Dump a type.
The type is dumped as:
@@ -136,41 +183,40 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
ind_name = "no_indicator";
}
if (IS_SIMPLE_TYPE(typ->typ))
{
ECPGdump_a_simple(o, name, typ->typ, typ->size, 0, 0, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, 0, 0, ind_prefix);
}
else if (typ->typ == ECPGt_array)
{
if (IS_SIMPLE_TYPE(typ->u.element->typ))
{
ECPGdump_a_simple(o, name, typ->u.element->typ,
typ->u.element->size, typ->size, 0, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
ind_typ->u.element->size, ind_typ->size, 0, prefix);
}
else if (typ->u.element->typ == ECPGt_array)
{
abort(); /* Array of array, */
}
else if (typ->u.element->typ == ECPGt_struct)
{
/* Array of structs. */
ECPGdump_a_struct(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, 0, prefix, ind_prefix);
}
else
{
abort();
}
}
else if (typ->typ == ECPGt_struct)
{
ECPGdump_a_struct(o, name, ind_name, 0, typ, ind_typ, 0, prefix, ind_prefix);
}
else
{
abort();
switch(typ->typ)
{
case ECPGt_array:
if (IS_SIMPLE_TYPE(typ->u.element->typ))
{
ECPGdump_a_simple(o, name, typ->u.element->typ,
typ->u.element->size, typ->size, NULL, prefix);
if (ind_typ == &ecpg_no_indicator)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
else
ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
ind_typ->u.element->size, ind_typ->size, NULL, prefix);
}
else if (typ->u.element->typ == ECPGt_array)
{
yyerror("No nested arrays allowed (except strings)"); /* Array of array, */
}
else if (typ->u.element->typ == ECPGt_struct)
{
/* Array of structs. */
ECPGdump_a_struct(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, NULL, prefix, ind_prefix);
}
else
{
yyerror("Internal error: unknown datatype, pleqase inform pgsql-bugs@postgresql.org");
}
break;
case ECPGt_struct:
ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
break;
default:
ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break;
}
}
@@ -180,86 +226,48 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
void
ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
long varcharsize,
long arrsiz,
long arrsize,
const char *siz,
const char *prefix
)
{
switch (typ)
{
case ECPGt_char:
if (varcharsize == 0) /* pointer */
fprintf(o, "\n\tECPGt_char,(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
else
fprintf(o, "\n\tECPGt_char,&(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
break;
case ECPGt_unsigned_char:
if (varcharsize == 0) /* pointer */
fprintf(o, "\n\tECPGt_unsigned_char,(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
else
fprintf(o, "\n\tECPGt_unsigned_char,&(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(unsigned char)" : siz);
break;
case ECPGt_short:
fprintf(o, "\n\tECPGt_short,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(short)" : siz);
break;
case ECPGt_unsigned_short:
fprintf(o,
"\n\tECPGt_unsigned_short,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned short)" : siz);
break;
case ECPGt_int:
fprintf(o, "\n\tECPGt_int,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(int)" : siz);
break;
case ECPGt_unsigned_int:
fprintf(o, "\n\tECPGt_unsigned_int,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_long:
fprintf(o, "\n\tECPGt_long,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(long)" : siz);
break;
case ECPGt_unsigned_long:
fprintf(o, "\n\tECPGt_unsigned_int,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_float:
fprintf(o, "\n\tECPGt_float,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(float)" : siz);
break;
case ECPGt_double:
fprintf(o, "\n\tECPGt_double,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(double)" : siz);
break;
case ECPGt_bool:
fprintf(o, "\n\tECPGt_bool,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(bool)" : siz);
break;
case ECPGt_varchar:
case ECPGt_varchar2:
if (siz == NULL)
fprintf(o, "\n\tECPGt_varchar,&(%s%s),%ldL,%ldL,sizeof(struct varchar_%s), ",
prefix ? prefix : "", name,
varcharsize,
arrsiz, name);
else
fprintf(o, "\n\tECPGt_varchar,&(%s%s),%ldL,%ldL,%s, ",
prefix ? prefix : "", name,
varcharsize,
arrsiz, siz);
break;
case ECPGt_NO_INDICATOR: /* no indicator */
fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
break;
default:
abort();
if (typ == ECPGt_NO_INDICATOR)
fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
else
{
char *variable = (char *)mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
char *offset = (char *)mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1);
if (varcharsize == 0 || arrsize >= 0)
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
else
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
switch (typ)
{
case ECPGt_varchar:
sprintf(offset, "sizeof(struct varchar_%s)", name);
break;
case ECPGt_char:
case ECPGt_unsigned_char:
sprintf(offset, "%ld*sizeof(char)", varcharsize);
break;
default:
sprintf(offset, "sizeof(%s)", ECPGtype_name(typ));
break;
}
if (arrsize < 0)
arrsize = 1;
if (siz == NULL)
fprintf(o, "\n\t%s,%s,%ldL,%ldL,%s, ", get_type(typ), variable, varcharsize, arrsize, offset);
else
fprintf(o, "\n\t%s,%s,%ldL,%ldL,%s, ", get_type(typ), variable, varcharsize, arrsize, siz);
free(variable);
free(offset);
}
}
@@ -302,23 +310,18 @@ ECPGdump_a_struct(FILE *o, const char *name, const char * ind_name, long arrsiz,
}
}
/* Freeing is not really that important. Since we throw away the process
anyway. Lets implement that last! */
/* won't work anymore because a list of members may appear in several locations */
/*void
void
ECPGfree_struct_member(struct ECPGstruct_member * rm)
{
while (rm)
{
struct ECPGstruct_member *p = rm;
rm = rm->next;
free(p->name);
free(p);
}
}*/
while (rm)
{
struct ECPGstruct_member *p = rm;
rm = rm->next;
free(p->name);
free(p);
}
}
void
ECPGfree_type(struct ECPGtype * typ)
@@ -332,16 +335,18 @@ ECPGfree_type(struct ECPGtype * typ)
else if (typ->u.element->typ == ECPGt_array)
abort(); /* Array of array, */
else if (typ->u.element->typ == ECPGt_struct)
{
/* Array of structs. */
ECPGfree_struct_member(typ->u.members);
free(typ->u.members);
/* ECPGfree_struct_member(typ->u.members);*/
}
else
abort();
}
else if (typ->typ == ECPGt_struct)
{
ECPGfree_struct_member(typ->u.members);
free(typ->u.members);
/* ECPGfree_struct_member(typ->u.members);*/
}
else
{

View File

@@ -77,6 +77,7 @@ struct when
struct index
{
int ival;
char *str;
int index1;
int index2;
char *str;
};