More cleaning up and removed some duplicates.
This commit is contained in:
parent
34dc9abd6b
commit
fefe7034e2
@ -2225,5 +2225,9 @@ Tue, 14 Aug 2007 11:46:51 +0200
|
||||
- Use '$n' for positional variables, '?' is still possible via ecpg
|
||||
option.
|
||||
- Cleaned up the sources a little bit.
|
||||
|
||||
Wed, 22 Aug 2007 08:41:33 +0200
|
||||
|
||||
- More cleaning up and removed some duplicates.
|
||||
- Set ecpg library version to 6.0.
|
||||
- Set ecpg version to 4.4.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.37 2007/08/14 10:01:53 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.38 2007/08/22 08:20:58 meskes Exp $ */
|
||||
|
||||
#ifndef DT_H
|
||||
#define DT_H
|
||||
@ -310,31 +310,24 @@ do { \
|
||||
#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
|
||||
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
|
||||
|
||||
int DecodeTimeOnly(char **field, int *ftype,
|
||||
int nf, int *dtype,
|
||||
struct tm * tm, fsec_t *fsec, int *tzp);
|
||||
|
||||
int DecodeInterval(char **field, int *ftype,
|
||||
int nf, int *dtype,
|
||||
struct tm * tm, fsec_t *fsec);
|
||||
|
||||
int EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str);
|
||||
int EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool);
|
||||
int EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str);
|
||||
|
||||
int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
|
||||
|
||||
int DecodeUnits(int field, char *lowtoken, int *val);
|
||||
|
||||
bool CheckDateTokenTables(void);
|
||||
|
||||
int EncodeDateOnly(struct tm *, int, char *, bool);
|
||||
void GetEpochTime(struct tm *);
|
||||
int ParseDateTime(char *, char *, char **, int *, int, int *, char **);
|
||||
int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
|
||||
void j2date(int, int *, int *, int *);
|
||||
void GetCurrentDateTime(struct tm *);
|
||||
int date2j(int, int, int);
|
||||
int DecodeTimeOnly(char **, int *, int, int *, struct tm *, fsec_t *, int *);
|
||||
int DecodeInterval(char **, int *, int, int *, struct tm *, fsec_t *);
|
||||
int DecodeTime(char *, int, int *, struct tm *, fsec_t *);
|
||||
int EncodeTimeOnly(struct tm *, fsec_t, int *, int, char *);
|
||||
int EncodeDateTime(struct tm *, fsec_t, int *, char **, int, char *, bool);
|
||||
int EncodeInterval(struct tm *, fsec_t, int, char *);
|
||||
int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
|
||||
int DecodeUnits(int field, char *lowtoken, int *val);
|
||||
bool CheckDateTokenTables(void);
|
||||
int EncodeDateOnly(struct tm *, int, char *, bool);
|
||||
void GetEpochTime(struct tm *);
|
||||
int ParseDateTime(char *, char *, char **, int *, int, int *, char **);
|
||||
int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
|
||||
void j2date(int, int *, int *, int *);
|
||||
void GetCurrentDateTime(struct tm *);
|
||||
int date2j(int, int, int);
|
||||
void TrimTrailingZeros(char *);
|
||||
void dt2time(double, int *, int *, int *, fsec_t *);
|
||||
|
||||
extern char *pgtypes_date_weekdays_short[];
|
||||
extern char *pgtypes_date_months[];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.41 2007/08/14 10:01:53 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.42 2007/08/22 08:20:58 meskes Exp $ */
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
@ -743,7 +743,7 @@ EncodeDateOnly(struct tm * tm, int style, char *str, bool EuroDates)
|
||||
return TRUE;
|
||||
} /* EncodeDateOnly() */
|
||||
|
||||
static void
|
||||
void
|
||||
TrimTrailingZeros(char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
@ -1090,7 +1090,7 @@ GetCurrentDateTime(struct tm * tm)
|
||||
abstime2tm(time(NULL), &tz, tm, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
dt2time(double jd, int *hour, int *min, int *sec, fsec_t *fsec)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
@ -1469,7 +1469,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm, bool EuroDates)
|
||||
* Only check the lower limit on hours, since this same code
|
||||
* can be used to represent time spans.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
|
||||
{
|
||||
char *cp;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.36 2006/10/04 00:30:11 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.37 2007/08/22 08:20:58 meskes Exp $ */
|
||||
|
||||
#include "postgres_fe.h"
|
||||
#include <time.h>
|
||||
@ -13,90 +13,6 @@
|
||||
#include "pgtypes_error.h"
|
||||
#include "pgtypes_interval.h"
|
||||
|
||||
/* TrimTrailingZeros()
|
||||
* ... resulting from printing numbers with full precision.
|
||||
*/
|
||||
static void
|
||||
TrimTrailingZeros(char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
|
||||
/* chop off trailing zeros... but leave at least 2 fractional digits */
|
||||
while (*(str + len - 1) == '0' && *(str + len - 3) != '.')
|
||||
{
|
||||
len--;
|
||||
*(str + len) = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* DecodeTime()
|
||||
* Decode time string which includes delimiters.
|
||||
* Only check the lower limit on hours, since this same code
|
||||
* can be used to represent time spans.
|
||||
*/
|
||||
static int
|
||||
DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
*tmask = DTK_TIME_M;
|
||||
|
||||
tm->tm_hour = strtol(str, &cp, 10);
|
||||
if (*cp != ':')
|
||||
return -1;
|
||||
str = cp + 1;
|
||||
tm->tm_min = strtol(str, &cp, 10);
|
||||
if (*cp == '\0')
|
||||
{
|
||||
tm->tm_sec = 0;
|
||||
*fsec = 0;
|
||||
}
|
||||
else if (*cp != ':')
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
str = cp + 1;
|
||||
tm->tm_sec = strtol(str, &cp, 10);
|
||||
if (*cp == '\0')
|
||||
*fsec = 0;
|
||||
else if (*cp == '.')
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
char fstr[MAXDATELEN + 1];
|
||||
|
||||
/*
|
||||
* OK, we have at most six digits to work with. Let's construct a
|
||||
* string and then do the conversion to an integer.
|
||||
*/
|
||||
strncpy(fstr, (cp + 1), 7);
|
||||
strcpy(fstr + strlen(fstr), "000000");
|
||||
*(fstr + 6) = '\0';
|
||||
*fsec = strtol(fstr, &cp, 10);
|
||||
#else
|
||||
str = cp;
|
||||
*fsec = strtod(str, &cp);
|
||||
#endif
|
||||
if (*cp != '\0')
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* do a sanity check */
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
|
||||
tm->tm_sec < 0 || tm->tm_sec > 59 || *fsec >= USECS_PER_SEC)
|
||||
return -1;
|
||||
#else
|
||||
if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
|
||||
tm->tm_sec < 0 || tm->tm_sec > 59 || *fsec >= 1)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} /* DecodeTime() */
|
||||
|
||||
/* DecodeInterval()
|
||||
* Interpret previously parsed fields for general time interval.
|
||||
* Return 0 if decoded and -1 if problems.
|
||||
|
@ -97,36 +97,6 @@ SetEpochTimestamp(void)
|
||||
return dt;
|
||||
} /* SetEpochTimestamp() */
|
||||
|
||||
static void
|
||||
dt2time(timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int64 time;
|
||||
#else
|
||||
double time;
|
||||
#endif
|
||||
|
||||
time = jd;
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
*hour = time / USECS_PER_HOUR;
|
||||
time -= (*hour) * USECS_PER_HOUR;
|
||||
*min = time / USECS_PER_MINUTE;
|
||||
time -= (*min) * USECS_PER_MINUTE;
|
||||
*sec = time / USECS_PER_SEC;
|
||||
*fsec = time - *sec * USECS_PER_SEC;
|
||||
*sec = time / USECS_PER_SEC;
|
||||
*fsec = time - *sec * USECS_PER_SEC;
|
||||
#else
|
||||
*hour = time / SECS_PER_HOUR;
|
||||
time -= (*hour) * SECS_PER_HOUR;
|
||||
*min = time / SECS_PER_MINUTE;
|
||||
time -= (*min) * SECS_PER_MINUTE;
|
||||
*sec = time;
|
||||
*fsec = time - *sec;
|
||||
#endif
|
||||
} /* dt2time() */
|
||||
|
||||
/* timestamp2tm()
|
||||
* Convert timestamp data type to POSIX time structure.
|
||||
* Note that year is _not_ 1900-based, but is an explicit full value.
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
||||
#
|
||||
# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.127 2007/08/14 10:01:53 meskes Exp $
|
||||
# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.128 2007/08/22 08:20:58 meskes Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -27,7 +27,7 @@ override CFLAGS += -Wno-error
|
||||
endif
|
||||
override CFLAGS += $(PTHREAD_CFLAGS)
|
||||
|
||||
OBJS= preproc.o type.o ecpg.o ecpg_keywords.o output.o parser.o \
|
||||
OBJS= preproc.o type.o ecpg.o output.o parser.o \
|
||||
keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
|
||||
$(WIN32RES)
|
||||
|
||||
@ -57,7 +57,7 @@ else
|
||||
@$(missing) flex $< $@
|
||||
endif
|
||||
|
||||
c_keywords.o ecpg_keywords.o keywords.o preproc.o parser.o: preproc.h
|
||||
c_keywords.o keywords.o preproc.o parser.o: preproc.h
|
||||
|
||||
parser.c: $(top_srcdir)/src/backend/parser/parser.c
|
||||
rm -f $@ && $(LN_S) $< .
|
||||
|
@ -3,7 +3,7 @@
|
||||
* keywords.c
|
||||
* lexical token lookup for reserved words in postgres embedded SQL
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.20 2007/05/10 09:53:16 meskes Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.21 2007/08/22 08:20:58 meskes Exp $
|
||||
* §
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -20,7 +20,7 @@
|
||||
* !!WARNING!!: This list must be sorted, because binary
|
||||
* search is used to locate entries.
|
||||
*/
|
||||
static ScanKeyword ScanKeywords[] = {
|
||||
static const ScanKeyword ScanCKeywords[] = {
|
||||
/* name value */
|
||||
{"VARCHAR", VARCHAR},
|
||||
{"auto", S_AUTO},
|
||||
@ -50,25 +50,8 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"year", YEAR_P},
|
||||
};
|
||||
|
||||
ScanKeyword *
|
||||
const ScanKeyword *
|
||||
ScanCKeywordLookup(char *text)
|
||||
{
|
||||
ScanKeyword *low = &ScanKeywords[0];
|
||||
ScanKeyword *high = endof(ScanKeywords) - 1;
|
||||
ScanKeyword *middle;
|
||||
int difference;
|
||||
|
||||
while (low <= high)
|
||||
{
|
||||
middle = low + (high - low) / 2;
|
||||
difference = strcmp(middle->name, text);
|
||||
if (difference == 0)
|
||||
return middle;
|
||||
else if (difference < 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return DoLookup(text, &ScanCKeywords[0], endof(ScanCKeywords) - 1);
|
||||
}
|
||||
|
@ -4,17 +4,10 @@
|
||||
* lexical token lookup for reserved words in postgres embedded SQL
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.35 2007/06/12 07:55:56 meskes Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.36 2007/08/22 08:20:58 meskes Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres_fe.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "extern.h"
|
||||
#include "preproc.h"
|
||||
|
||||
|
||||
/*
|
||||
* List of (keyword-name, keyword-token-value) pairs.
|
||||
@ -22,7 +15,7 @@
|
||||
* !!WARNING!!: This list must be sorted, because binary
|
||||
* search is used to locate entries.
|
||||
*/
|
||||
static ScanKeyword ScanKeywords[] = {
|
||||
static const ScanKeyword ScanECPGKeywords[] = {
|
||||
/* name value */
|
||||
{"allocate", SQL_ALLOCATE},
|
||||
{"autocommit", SQL_AUTOCOMMIT},
|
||||
@ -71,69 +64,3 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"whenever", SQL_WHENEVER},
|
||||
};
|
||||
|
||||
/*
|
||||
* ScanECPGKeywordLookup - see if a given word is a keyword
|
||||
*
|
||||
* Returns a pointer to the ScanKeyword table entry, or NULL if no match.
|
||||
*
|
||||
* The match is done case-insensitively. Note that we deliberately use a
|
||||
* dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
|
||||
* even if we are in a locale where tolower() would produce more or different
|
||||
* translations. This is to conform to the SQL99 spec, which says that
|
||||
* keywords are to be matched in this way even though non-keyword identifiers
|
||||
* receive a different case-normalization mapping.
|
||||
*/
|
||||
ScanKeyword *
|
||||
ScanECPGKeywordLookup(char *text)
|
||||
{
|
||||
int len,
|
||||
i;
|
||||
char word[NAMEDATALEN];
|
||||
ScanKeyword *low;
|
||||
ScanKeyword *high;
|
||||
|
||||
len = strlen(text);
|
||||
/* We assume all keywords are shorter than NAMEDATALEN. */
|
||||
if (len >= NAMEDATALEN)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since it may
|
||||
* produce the wrong translation in some locales (eg, Turkish), and we
|
||||
* don't trust isupper() very much either. In an ASCII-based encoding the
|
||||
* tests against A and Z are sufficient, but we also check isupper() so
|
||||
* that we will work correctly under EBCDIC. The actual case conversion
|
||||
* step should work for either ASCII or EBCDIC.
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char ch = text[i];
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z' && isupper((unsigned char) ch))
|
||||
ch += 'a' - 'A';
|
||||
word[i] = ch;
|
||||
}
|
||||
word[len] = '\0';
|
||||
|
||||
/*
|
||||
* Now do a binary search using plain strcmp() comparison.
|
||||
*/
|
||||
low = &ScanKeywords[0];
|
||||
high = endof(ScanKeywords) - 1;
|
||||
while (low <= high)
|
||||
{
|
||||
ScanKeyword *middle;
|
||||
int difference;
|
||||
|
||||
middle = low + (high - low) / 2;
|
||||
difference = strcmp(middle->name, word);
|
||||
if (difference == 0)
|
||||
return middle;
|
||||
else if (difference < 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.68 2007/08/14 10:54:57 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.69 2007/08/22 08:20:58 meskes Exp $ */
|
||||
|
||||
#ifndef _ECPG_PREPROC_EXTERN_H
|
||||
#define _ECPG_PREPROC_EXTERN_H
|
||||
@ -74,8 +74,7 @@ extern void base_yyerror(const char *);
|
||||
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
|
||||
extern char *mm_strdup(const char *);
|
||||
extern void mmerror(int, enum errortype, char *,...);
|
||||
extern ScanKeyword *ScanECPGKeywordLookup(char *);
|
||||
extern ScanKeyword *ScanCKeywordLookup(char *);
|
||||
extern const ScanKeyword *ScanCKeywordLookup(char *);
|
||||
extern void output_get_descr_header(char *);
|
||||
extern void output_get_descr(char *, char *);
|
||||
extern void output_set_descr_header(char *);
|
||||
@ -97,7 +96,8 @@ extern void check_indicator(struct ECPGtype *);
|
||||
extern void remove_typedefs(int);
|
||||
extern void remove_variables(int);
|
||||
extern struct variable *new_variable(const char *, struct ECPGtype *, int);
|
||||
extern ScanKeyword *ScanKeywordLookup(char *text);
|
||||
extern const ScanKeyword *ScanKeywordLookup(char *text);
|
||||
extern const ScanKeyword *DoLookup(char *, const ScanKeyword *,const ScanKeyword *);
|
||||
extern void scanner_init(const char *);
|
||||
extern void parser_init(void);
|
||||
extern void scanner_finish(void);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.80 2007/06/12 07:55:56 meskes Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.81 2007/08/22 08:20:58 meskes Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -19,6 +19,8 @@
|
||||
#include "extern.h"
|
||||
#include "preproc.h"
|
||||
|
||||
/* compile both keyword lists in one file because they are always scanned together */
|
||||
#include "ecpg_keywords.c"
|
||||
|
||||
/*
|
||||
* List of (keyword-name, keyword-token-value) pairs.
|
||||
@ -26,7 +28,7 @@
|
||||
* !!WARNING!!: This list must be sorted, because binary
|
||||
* search is used to locate entries.
|
||||
*/
|
||||
static ScanKeyword ScanKeywords[] = {
|
||||
static const ScanKeyword ScanPGSQLKeywords[] = {
|
||||
/* name, value */
|
||||
{"abort", ABORT_P},
|
||||
{"absolute", ABSOLUTE_P},
|
||||
@ -395,6 +397,31 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"zone", ZONE},
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Now do a binary search using plain strcmp() comparison.
|
||||
*/
|
||||
const ScanKeyword *
|
||||
DoLookup(char *word, const ScanKeyword *low, const ScanKeyword *high)
|
||||
{
|
||||
while (low <= high)
|
||||
{
|
||||
const ScanKeyword *middle;
|
||||
int difference;
|
||||
|
||||
middle = low + (high - low) / 2;
|
||||
difference = strcmp(middle->name, word);
|
||||
if (difference == 0)
|
||||
return middle;
|
||||
else if (difference < 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ScanKeywordLookup - see if a given word is a keyword
|
||||
*
|
||||
@ -407,14 +434,13 @@ static ScanKeyword ScanKeywords[] = {
|
||||
* keywords are to be matched in this way even though non-keyword identifiers
|
||||
* receive a different case-normalization mapping.
|
||||
*/
|
||||
ScanKeyword *
|
||||
const ScanKeyword *
|
||||
ScanKeywordLookup(char *text)
|
||||
{
|
||||
int len,
|
||||
i;
|
||||
char word[NAMEDATALEN];
|
||||
ScanKeyword *low;
|
||||
ScanKeyword *high;
|
||||
const ScanKeyword *res;
|
||||
|
||||
len = strlen(text);
|
||||
/* We assume all keywords are shorter than NAMEDATALEN. */
|
||||
@ -438,22 +464,10 @@ ScanKeywordLookup(char *text)
|
||||
/*
|
||||
* Now do a binary search using plain strcmp() comparison.
|
||||
*/
|
||||
low = &ScanKeywords[0];
|
||||
high = endof(ScanKeywords) - 1;
|
||||
while (low <= high)
|
||||
{
|
||||
ScanKeyword *middle;
|
||||
int difference;
|
||||
res = DoLookup(word, &ScanPGSQLKeywords[0], endof(ScanPGSQLKeywords) - 1);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
middle = low + (high - low) / 2;
|
||||
difference = strcmp(middle->name, word);
|
||||
if (difference == 0)
|
||||
return middle;
|
||||
else if (difference < 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return DoLookup(word, &ScanECPGKeywords[0], endof(ScanECPGKeywords) - 1);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.153 2007/08/14 10:01:53 meskes Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.154 2007/08/22 08:20:58 meskes Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -49,6 +49,7 @@ static void addlitchar (unsigned char);
|
||||
static void parse_include (void);
|
||||
static void check_escape_warning(void);
|
||||
static bool ecpg_isspace(char ch);
|
||||
static bool isdefine(void);
|
||||
|
||||
char *token_start;
|
||||
int state_before;
|
||||
@ -681,41 +682,15 @@ cppline {space}*#(.*\\{space})*.*{newline}
|
||||
return(CVARIABLE);
|
||||
}
|
||||
<SQL>{identifier} {
|
||||
ScanKeyword *keyword;
|
||||
struct _defines *ptr;
|
||||
const ScanKeyword *keyword;
|
||||
|
||||
/* How about a DEFINE? */
|
||||
for (ptr = defines; ptr; ptr = ptr->next)
|
||||
if (!isdefine())
|
||||
{
|
||||
if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL)
|
||||
{
|
||||
struct _yy_buffer *yb;
|
||||
|
||||
yb = mm_alloc(sizeof(struct _yy_buffer));
|
||||
|
||||
yb->buffer = YY_CURRENT_BUFFER;
|
||||
yb->lineno = yylineno;
|
||||
yb->filename = mm_strdup(input_filename);
|
||||
yb->next = yy_buffer;
|
||||
|
||||
ptr->used = yy_buffer = yb;
|
||||
|
||||
yy_scan_string(ptr->new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ptr == NULL)
|
||||
{
|
||||
/* Is it an SQL keyword? */
|
||||
/* Is it an SQL/ECPG keyword? */
|
||||
keyword = ScanKeywordLookup(yytext);
|
||||
if (keyword != NULL)
|
||||
return keyword->value;
|
||||
|
||||
/* Is it an ECPG keyword? */
|
||||
keyword = ScanECPGKeywordLookup( yytext);
|
||||
if (keyword != NULL)
|
||||
return keyword->value;
|
||||
|
||||
/* Is it a C keyword? */
|
||||
keyword = ScanCKeywordLookup(yytext);
|
||||
if (keyword != NULL)
|
||||
@ -775,39 +750,9 @@ cppline {space}*#(.*\\{space})*.*{newline}
|
||||
return(CPP_LINE);
|
||||
}
|
||||
<C>{identifier} {
|
||||
ScanKeyword *keyword;
|
||||
struct _defines *ptr;
|
||||
const ScanKeyword *keyword;
|
||||
|
||||
if (INFORMIX_MODE)
|
||||
{
|
||||
/* Informix uses SQL defines only in SQL space */
|
||||
ptr = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* is it a define? */
|
||||
for (ptr = defines; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL)
|
||||
{
|
||||
struct _yy_buffer *yb;
|
||||
|
||||
yb = mm_alloc(sizeof(struct _yy_buffer));
|
||||
|
||||
yb->buffer = YY_CURRENT_BUFFER;
|
||||
yb->lineno = yylineno;
|
||||
yb->filename = mm_strdup(input_filename);
|
||||
yb->next = yy_buffer;
|
||||
|
||||
ptr->used = yy_buffer = yb;
|
||||
|
||||
yy_scan_string(ptr->new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
if (INFORMIX_MODE || !isdefine())
|
||||
{
|
||||
keyword = ScanCKeywordLookup(yytext);
|
||||
if (keyword != NULL)
|
||||
@ -1359,6 +1304,33 @@ ecpg_isspace(char ch)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isdefine(void)
|
||||
{
|
||||
struct _defines *ptr;
|
||||
|
||||
/* is it a define? */
|
||||
for (ptr = defines; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL)
|
||||
{
|
||||
struct _yy_buffer *yb;
|
||||
|
||||
yb = mm_alloc(sizeof(struct _yy_buffer));
|
||||
|
||||
yb->buffer = YY_CURRENT_BUFFER;
|
||||
yb->lineno = yylineno;
|
||||
yb->filename = mm_strdup(input_filename);
|
||||
yb->next = yy_buffer;
|
||||
|
||||
ptr->used = yy_buffer = yb;
|
||||
|
||||
yy_scan_string(ptr->new);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called before any actual parsing is done
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.349 2007/08/14 10:01:53 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.350 2007/08/22 08:20:58 meskes Exp $ */
|
||||
|
||||
/* Copyright comment */
|
||||
%{
|
||||
@ -319,6 +319,51 @@ add_additional_variables(char *name, bool insert)
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
|
||||
{
|
||||
/* add entry to list */
|
||||
struct typedefs *ptr, *this;
|
||||
|
||||
if ((type_enum == ECPGt_struct ||
|
||||
type_enum == ECPGt_union) &&
|
||||
initializer == 1)
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
|
||||
else
|
||||
{
|
||||
for (ptr = types; ptr != NULL; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp(name, ptr->name) == 0)
|
||||
/* re-definition is a bug */
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", name);
|
||||
}
|
||||
adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
|
||||
|
||||
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
|
||||
|
||||
/* initial definition */
|
||||
this->next = types;
|
||||
this->name = name;
|
||||
this->brace_level = braces_open;
|
||||
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
|
||||
this->type->type_enum = type_enum;
|
||||
this->type->type_str = mm_strdup(name);
|
||||
this->type->type_dimension = dimension; /* dimension of array */
|
||||
this->type->type_index = length; /* length of string */
|
||||
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||
this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
|
||||
ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
|
||||
|
||||
if (type_enum != ECPGt_varchar &&
|
||||
type_enum != ECPGt_char &&
|
||||
type_enum != ECPGt_unsigned_char &&
|
||||
atoi(this->type->type_index) >= 0)
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
|
||||
|
||||
types = this;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
%name-prefix="base_yy"
|
||||
@ -597,7 +642,7 @@ add_additional_variables(char *name, bool insert)
|
||||
%type <str> var_declaration type_declaration single_vt_declaration
|
||||
%type <str> ECPGSetAutocommit on_off variable_declarations ECPGDescribe
|
||||
%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_output
|
||||
%type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
|
||||
%type <str> ECPGGetDescriptorHeader ECPGColLabel
|
||||
%type <str> reserved_keyword unreserved_keyword ecpg_interval opt_ecpg_using
|
||||
%type <str> col_name_keyword precision opt_scale ECPGExecuteImmediateStmt
|
||||
%type <str> ECPGTypeName using_list ECPGColLabelCommon UsingConst
|
||||
@ -5124,40 +5169,7 @@ ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
|
||||
ECPGVarDeclaration: single_vt_declaration;
|
||||
|
||||
single_vt_declaration: type_declaration { $$ = $1; }
|
||||
| single_var_declaration { $$ = $1; }
|
||||
;
|
||||
|
||||
single_var_declaration: storage_declaration
|
||||
var_type
|
||||
{
|
||||
actual_type[struct_level].type_enum = $2.type_enum;
|
||||
actual_type[struct_level].type_dimension = $2.type_dimension;
|
||||
actual_type[struct_level].type_index = $2.type_index;
|
||||
actual_type[struct_level].type_sizeof = $2.type_sizeof;
|
||||
|
||||
actual_startline[struct_level] = hashline_number();
|
||||
}
|
||||
variable_list ';'
|
||||
{
|
||||
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
|
||||
}
|
||||
| var_type
|
||||
{
|
||||
actual_type[struct_level].type_enum = $1.type_enum;
|
||||
actual_type[struct_level].type_dimension = $1.type_dimension;
|
||||
actual_type[struct_level].type_index = $1.type_index;
|
||||
actual_type[struct_level].type_sizeof = $1.type_sizeof;
|
||||
|
||||
actual_startline[struct_level] = hashline_number();
|
||||
}
|
||||
variable_list ';'
|
||||
{
|
||||
$$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
|
||||
}
|
||||
| struct_union_type_with_symbol ';'
|
||||
{
|
||||
$$ = cat2_str($1, make_str(";"));
|
||||
}
|
||||
| var_declaration { $$ = $1; }
|
||||
;
|
||||
|
||||
precision: NumConst { $$ = $1; };
|
||||
@ -5214,50 +5226,9 @@ type_declaration: S_TYPEDEF
|
||||
}
|
||||
var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
|
||||
{
|
||||
/* add entry to list */
|
||||
struct typedefs *ptr, *this;
|
||||
char * dimension = $6.index1;
|
||||
char * length = $6.index2;
|
||||
add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
|
||||
|
||||
if (($3.type_enum == ECPGt_struct ||
|
||||
$3.type_enum == ECPGt_union) &&
|
||||
initializer == 1)
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
|
||||
else
|
||||
{
|
||||
for (ptr = types; ptr != NULL; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp($5, ptr->name) == 0)
|
||||
/* re-definition is a bug */
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", $5);
|
||||
}
|
||||
adjust_array($3.type_enum, &dimension, &length, $3.type_dimension, $3.type_index, *$4?1:0, true);
|
||||
|
||||
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
|
||||
|
||||
/* initial definition */
|
||||
this->next = types;
|
||||
this->name = $5;
|
||||
this->brace_level = braces_open;
|
||||
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
|
||||
this->type->type_enum = $3.type_enum;
|
||||
this->type->type_str = mm_strdup($5);
|
||||
this->type->type_dimension = dimension; /* dimension of array */
|
||||
this->type->type_index = length; /* length of string */
|
||||
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||
this->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ?
|
||||
ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
|
||||
|
||||
if ($3.type_enum != ECPGt_varchar &&
|
||||
$3.type_enum != ECPGt_char &&
|
||||
$3.type_enum != ECPGt_unsigned_char &&
|
||||
atoi(this->type->type_index) >= 0)
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
|
||||
|
||||
types = this;
|
||||
}
|
||||
|
||||
fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4?"*":"", $5, $6.str);
|
||||
fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
|
||||
output_line_number();
|
||||
$$ = make_str("");
|
||||
};
|
||||
@ -6046,49 +6017,7 @@ ECPGTypedef: TYPE_P
|
||||
}
|
||||
ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
|
||||
{
|
||||
/* add entry to list */
|
||||
struct typedefs *ptr, *this;
|
||||
char *dimension = $6.index1;
|
||||
char *length = $6.index2;
|
||||
|
||||
if (($5.type_enum == ECPGt_struct ||
|
||||
$5.type_enum == ECPGt_union) &&
|
||||
initializer == 1)
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL TYPE command");
|
||||
else
|
||||
{
|
||||
for (ptr = types; ptr != NULL; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp($3, ptr->name) == 0)
|
||||
/* re-definition is a bug */
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", $3);
|
||||
}
|
||||
|
||||
adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
|
||||
|
||||
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
|
||||
|
||||
/* initial definition */
|
||||
this->next = types;
|
||||
this->name = $3;
|
||||
this->brace_level = braces_open;
|
||||
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
|
||||
this->type->type_enum = $5.type_enum;
|
||||
this->type->type_str = mm_strdup($3);
|
||||
this->type->type_dimension = dimension; /* dimension of array */
|
||||
this->type->type_index = length; /* length of string */
|
||||
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||
this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
|
||||
ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
|
||||
|
||||
if ($5.type_enum != ECPGt_varchar &&
|
||||
$5.type_enum != ECPGt_char &&
|
||||
$5.type_enum != ECPGt_unsigned_char &&
|
||||
atoi(this->type->type_index) >= 0)
|
||||
mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
|
||||
|
||||
types = this;
|
||||
}
|
||||
add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
|
||||
|
||||
if (auto_create_c == false)
|
||||
$$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.73 2007/08/14 10:01:53 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.74 2007/08/22 08:20:58 meskes Exp $ */
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
@ -80,7 +80,7 @@ ECPGmake_struct_member(char *name, struct ECPGtype * type, struct ECPGstruct_mem
|
||||
*ne =
|
||||
(struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
|
||||
|
||||
ne->name = strdup(name);
|
||||
ne->name = mm_strdup(name);
|
||||
ne->type = type;
|
||||
ne->next = NULL;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user