Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f7563e9

Browse files
author
Michael Meskes
committed
Synced parser.
Made ecpg parser use backend provided keyword list. Changed whenever test so exit value is 0.
1 parent 1ac1bea commit f7563e9

File tree

13 files changed

+274
-629
lines changed

13 files changed

+274
-629
lines changed

src/interfaces/ecpg/ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,13 @@ Mon, 12 May 2008 18:19:08 +0200
23512351

23522352
- Check for non-existant connection in prepare statement handling.
23532353
- Do not close files that weren't opened.
2354+
2355+
Tue, 20 May 2008 17:31:01 +0200
2356+
2357+
- Synced parser.
2358+
- Made ecpg parser use backend provided keyword list. One less file to
2359+
sync manually.
2360+
- Changed whenever test so exit value is 0.
23542361
- Set pgtypes library version to 3.1.
23552362
- Set compat library version to 3.1.
23562363
- Set ecpg library version to 6.2.

src/interfaces/ecpg/preproc/Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# Copyright (c) 1998-2008, PostgreSQL Global Development Group
66
#
7-
# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.132 2008/03/18 17:46:23 petere Exp $
7+
# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.133 2008/05/20 23:17:32 meskes Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -25,7 +25,7 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \
2525
override CFLAGS += $(PTHREAD_CFLAGS)
2626

2727
OBJS= preproc.o type.o ecpg.o output.o parser.o \
28-
keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
28+
keywords.o c_keywords.o ecpg_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
2929
$(WIN32RES)
3030

3131
all: submake-libpgport ecpg
@@ -56,6 +56,11 @@ endif
5656

5757
c_keywords.o keywords.o preproc.o parser.o: preproc.h
5858

59+
# instead of maintaining our own list, take the one from the backend
60+
# we cannot just link it in, but must copy and make some minor changes
61+
keywords.c: % : $(top_srcdir)/src/backend/parser/%
62+
sed -e 's/#include "parser\/parse.h"/#include "preproc.h"/' $< > $@
63+
5964
distprep: $(srcdir)/preproc.c $(srcdir)/preproc.h $(srcdir)/pgc.c
6065

6166
install: all installdirs
@@ -68,7 +73,7 @@ uninstall:
6873
rm -f '$(DESTDIR)$(bindir)/ecpg$(X)'
6974

7075
clean distclean:
71-
rm -f *.o ecpg$(X)
76+
rm -f keywords.c *.o ecpg$(X)
7277
# garbage from partial builds
7378
@rm -f y.tab.c y.tab.h
7479
# garbage from development

src/interfaces/ecpg/preproc/c_keywords.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* keywords.c
44
* lexical token lookup for reserved words in postgres embedded SQL
55
*
6-
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.21 2007/08/22 08:20:58 meskes Exp $
6+
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.22 2008/05/20 23:17:32 meskes Exp $
77
* §
88
*-------------------------------------------------------------------------
99
*/
@@ -21,37 +21,39 @@
2121
* search is used to locate entries.
2222
*/
2323
static const ScanKeyword ScanCKeywords[] = {
24-
/* name value */
25-
{"VARCHAR", VARCHAR},
26-
{"auto", S_AUTO},
27-
{"bool", SQL_BOOL},
28-
{"char", CHAR_P},
29-
{"const", S_CONST},
30-
{"enum", ENUM_P},
31-
{"extern", S_EXTERN},
32-
{"float", FLOAT_P},
33-
{"hour", HOUR_P},
34-
{"int", INT_P},
35-
{"long", SQL_LONG},
36-
{"minute", MINUTE_P},
37-
{"month", MONTH_P},
38-
{"register", S_REGISTER},
39-
{"second", SECOND_P},
40-
{"short", SQL_SHORT},
41-
{"signed", SQL_SIGNED},
42-
{"static", S_STATIC},
43-
{"struct", SQL_STRUCT},
44-
{"to", TO},
45-
{"typedef", S_TYPEDEF},
46-
{"union", UNION},
47-
{"unsigned", SQL_UNSIGNED},
48-
{"varchar", VARCHAR},
49-
{"volatile", S_VOLATILE},
50-
{"year", YEAR_P},
24+
/* name, value, category */
25+
/* category is not needed in ecpg, it is only here so we can share
26+
* the data structure with the backend */
27+
{"VARCHAR", VARCHAR, 0},
28+
{"auto", S_AUTO, 0},
29+
{"bool", SQL_BOOL, 0},
30+
{"char", CHAR_P, 0},
31+
{"const", S_CONST, 0},
32+
{"enum", ENUM_P, 0},
33+
{"extern", S_EXTERN, 0},
34+
{"float", FLOAT_P, 0},
35+
{"hour", HOUR_P, 0},
36+
{"int", INT_P, 0},
37+
{"long", SQL_LONG, 0},
38+
{"minute", MINUTE_P, 0},
39+
{"month", MONTH_P, 0},
40+
{"register", S_REGISTER, 0},
41+
{"second", SECOND_P, 0},
42+
{"short", SQL_SHORT, 0},
43+
{"signed", SQL_SIGNED, 0},
44+
{"static", S_STATIC, 0},
45+
{"struct", SQL_STRUCT, 0},
46+
{"to", TO, 0},
47+
{"typedef", S_TYPEDEF, 0},
48+
{"union", UNION, 0},
49+
{"unsigned", SQL_UNSIGNED, 0},
50+
{"varchar", VARCHAR, 0},
51+
{"volatile", S_VOLATILE, 0},
52+
{"year", YEAR_P, 0},
5153
};
5254

5355
const ScanKeyword *
54-
ScanCKeywordLookup(char *text)
56+
ScanCKeywordLookup(const char *text)
5557
{
5658
return DoLookup(text, &ScanCKeywords[0], endof(ScanCKeywords) - 1);
5759
}

src/interfaces/ecpg/preproc/ecpg_keywords.c

Lines changed: 132 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,148 @@
44
* lexical token lookup for reserved words in postgres embedded SQL
55
*
66
* IDENTIFICATION
7-
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.37 2007/11/15 21:14:45 momjian Exp $
7+
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.38 2008/05/20 23:17:32 meskes Exp $
88
*
99
*-------------------------------------------------------------------------
1010
*/
1111

12+
#include "postgres_fe.h"
13+
14+
#include <ctype.h>
15+
16+
#include "extern.h"
17+
#include "preproc.h"
18+
1219
/*
1320
* List of (keyword-name, keyword-token-value) pairs.
1421
*
1522
* !!WARNING!!: This list must be sorted, because binary
1623
* search is used to locate entries.
1724
*/
1825
static const ScanKeyword ScanECPGKeywords[] = {
19-
/* name value */
20-
{"allocate", SQL_ALLOCATE},
21-
{"autocommit", SQL_AUTOCOMMIT},
22-
{"bool", SQL_BOOL},
23-
{"break", SQL_BREAK},
24-
{"call", SQL_CALL},
25-
{"cardinality", SQL_CARDINALITY},
26-
{"connect", SQL_CONNECT},
27-
{"continue", SQL_CONTINUE},
28-
{"count", SQL_COUNT},
29-
{"data", SQL_DATA},
30-
{"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE},
31-
{"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION},
32-
{"describe", SQL_DESCRIBE},
33-
{"descriptor", SQL_DESCRIPTOR},
34-
{"disconnect", SQL_DISCONNECT},
35-
{"found", SQL_FOUND},
36-
{"free", SQL_FREE},
37-
{"go", SQL_GO},
38-
{"goto", SQL_GOTO},
39-
{"identified", SQL_IDENTIFIED},
40-
{"indicator", SQL_INDICATOR},
41-
{"key_member", SQL_KEY_MEMBER},
42-
{"length", SQL_LENGTH},
43-
{"long", SQL_LONG},
44-
{"nullable", SQL_NULLABLE},
45-
{"octet_length", SQL_OCTET_LENGTH},
46-
{"open", SQL_OPEN},
47-
{"output", SQL_OUTPUT},
48-
{"reference", SQL_REFERENCE},
49-
{"returned_length", SQL_RETURNED_LENGTH},
50-
{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH},
51-
{"scale", SQL_SCALE},
52-
{"section", SQL_SECTION},
53-
{"short", SQL_SHORT},
54-
{"signed", SQL_SIGNED},
55-
{"sql", SQL_SQL}, /* strange thing, used for into sql descriptor
26+
/* name, value, category */
27+
/* category is not needed in ecpg, it is only here so we can share
28+
* the data structure with the backend */
29+
{"allocate", SQL_ALLOCATE, 0},
30+
{"autocommit", SQL_AUTOCOMMIT, 0},
31+
{"bool", SQL_BOOL, 0},
32+
{"break", SQL_BREAK, 0},
33+
{"call", SQL_CALL, 0},
34+
{"cardinality", SQL_CARDINALITY, 0},
35+
{"connect", SQL_CONNECT, 0},
36+
{"count", SQL_COUNT, 0},
37+
{"data", SQL_DATA, 0},
38+
{"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE, 0},
39+
{"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION, 0},
40+
{"describe", SQL_DESCRIBE, 0},
41+
{"descriptor", SQL_DESCRIPTOR, 0},
42+
{"disconnect", SQL_DISCONNECT, 0},
43+
{"found", SQL_FOUND, 0},
44+
{"free", SQL_FREE, 0},
45+
{"get", SQL_GET, 0},
46+
{"go", SQL_GO, 0},
47+
{"goto", SQL_GOTO, 0},
48+
{"identified", SQL_IDENTIFIED, 0},
49+
{"indicator", SQL_INDICATOR, 0},
50+
{"key_member", SQL_KEY_MEMBER, 0},
51+
{"length", SQL_LENGTH, 0},
52+
{"long", SQL_LONG, 0},
53+
{"nullable", SQL_NULLABLE, 0},
54+
{"octet_length", SQL_OCTET_LENGTH, 0},
55+
{"open", SQL_OPEN, 0},
56+
{"output", SQL_OUTPUT, 0},
57+
{"reference", SQL_REFERENCE, 0},
58+
{"returned_length", SQL_RETURNED_LENGTH, 0},
59+
{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0},
60+
{"scale", SQL_SCALE, 0},
61+
{"section", SQL_SECTION, 0},
62+
{"short", SQL_SHORT, 0},
63+
{"signed", SQL_SIGNED, 0},
64+
{"sql", SQL_SQL, 0}, /* strange thing, used for into sql descriptor
5665
* MYDESC; */
57-
{"sqlerror", SQL_SQLERROR},
58-
{"sqlprint", SQL_SQLPRINT},
59-
{"sqlwarning", SQL_SQLWARNING},
60-
{"stop", SQL_STOP},
61-
{"struct", SQL_STRUCT},
62-
{"unsigned", SQL_UNSIGNED},
63-
{"var", SQL_VAR},
64-
{"whenever", SQL_WHENEVER},
66+
{"sqlerror", SQL_SQLERROR, 0},
67+
{"sqlprint", SQL_SQLPRINT, 0},
68+
{"sqlwarning", SQL_SQLWARNING, 0},
69+
{"stop", SQL_STOP, 0},
70+
{"struct", SQL_STRUCT, 0},
71+
{"unsigned", SQL_UNSIGNED, 0},
72+
{"var", SQL_VAR, 0},
73+
{"whenever", SQL_WHENEVER, 0},
6574
};
75+
76+
/* This is all taken from src/backend/parser/keyword.c and adjusted for our needs. */
77+
/*
78+
* Do a binary search using plain strcmp() comparison.
79+
*/
80+
const ScanKeyword *
81+
DoLookup(const char *word, const ScanKeyword *low, const ScanKeyword *high)
82+
{
83+
while (low <= high)
84+
{
85+
const ScanKeyword *middle;
86+
int difference;
87+
88+
middle = low + (high - low) / 2;
89+
difference = strcmp(middle->name, word);
90+
if (difference == 0)
91+
return middle;
92+
else if (difference < 0)
93+
low = middle + 1;
94+
else
95+
high = middle - 1;
96+
}
97+
98+
return NULL;
99+
}
100+
101+
/*
102+
* ScanECPGKeywordLookup - see if a given word is a keyword
103+
*
104+
* Returns a pointer to the ScanKeyword table entry, or NULL if no match.
105+
*
106+
* The match is done case-insensitively. Note that we deliberately use a
107+
* dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
108+
* even if we are in a locale where tolower() would produce more or different
109+
* translations. This is to conform to the SQL99 spec, which says that
110+
* keywords are to be matched in this way even though non-keyword identifiers
111+
* receive a different case-normalization mapping.
112+
*/
113+
const ScanKeyword *
114+
ScanECPGKeywordLookup(const char *text)
115+
{
116+
int len,
117+
i;
118+
char word[NAMEDATALEN];
119+
const ScanKeyword *res;
120+
121+
/* First check SQL symbols defined by the backend. */
122+
123+
res = ScanKeywordLookup(text);
124+
if (res)
125+
return res;
126+
127+
len = strlen(text);
128+
/* We assume all keywords are shorter than NAMEDATALEN. */
129+
if (len >= NAMEDATALEN)
130+
return NULL;
131+
132+
/*
133+
* Apply an ASCII-only downcasing. We must not use tolower() since it may
134+
* produce the wrong translation in some locales (eg, Turkish).
135+
*/
136+
for (i = 0; i < len; i++)
137+
{
138+
char ch = text[i];
139+
140+
if (ch >= 'A' && ch <= 'Z')
141+
ch += 'a' - 'A';
142+
word[i] = ch;
143+
}
144+
word[len] = '\0';
145+
146+
/*
147+
* Now do a binary search using plain strcmp() comparison.
148+
*/
149+
150+
return DoLookup(word, &ScanECPGKeywords[0], endof(ScanECPGKeywords) - 1);
151+
}

src/interfaces/ecpg/preproc/extern.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.70 2007/11/15 21:14:45 momjian Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.71 2008/05/20 23:17:32 meskes Exp $ */
22

33
#ifndef _ECPG_PREPROC_EXTERN_H
44
#define _ECPG_PREPROC_EXTERN_H
55

66
#include "type.h"
7+
#include "parser/keywords.h"
78

89
#include <errno.h>
910
#ifndef CHAR_BIT
@@ -74,7 +75,6 @@ extern void base_yyerror(const char *);
7475
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
7576
extern char *mm_strdup(const char *);
7677
extern void mmerror(int, enum errortype, char *,...);
77-
extern const ScanKeyword *ScanCKeywordLookup(char *);
7878
extern void output_get_descr_header(char *);
7979
extern void output_get_descr(char *, char *);
8080
extern void output_set_descr_header(char *);
@@ -96,8 +96,9 @@ extern void check_indicator(struct ECPGtype *);
9696
extern void remove_typedefs(int);
9797
extern void remove_variables(int);
9898
extern struct variable *new_variable(const char *, struct ECPGtype *, int);
99-
extern const ScanKeyword *ScanKeywordLookup(char *text);
100-
extern const ScanKeyword *DoLookup(char *, const ScanKeyword *, const ScanKeyword *);
99+
extern const ScanKeyword *ScanCKeywordLookup(const char *);
100+
extern const ScanKeyword *ScanECPGKeywordLookup(const char *text);
101+
extern const ScanKeyword *DoLookup(const char *, const ScanKeyword *, const ScanKeyword *);
101102
extern void scanner_init(const char *);
102103
extern void parser_init(void);
103104
extern void scanner_finish(void);

0 commit comments

Comments
 (0)