~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/interfaces/ecpg/preproc/ecpg_keywords.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * ecpg_keywords.c
 
4
 *        lexical token lookup for reserved words in postgres embedded SQL
 
5
 *
 
6
 * IDENTIFICATION
 
7
 *        $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.30 2004-09-27 09:59:17 meskes Exp $
 
8
 *
 
9
 *-------------------------------------------------------------------------
 
10
 */
 
11
#include "postgres_fe.h"
 
12
 
 
13
#include <ctype.h>
 
14
 
 
15
#include "extern.h"
 
16
#include "preproc.h"
 
17
 
 
18
 
 
19
/*
 
20
 * List of (keyword-name, keyword-token-value) pairs.
 
21
 *
 
22
 * !!WARNING!!: This list must be sorted, because binary
 
23
 *               search is used to locate entries.
 
24
 */
 
25
static ScanKeyword ScanKeywords[] = {
 
26
        /* name                                 value                   */
 
27
        {"allocate", SQL_ALLOCATE},
 
28
        {"autocommit", SQL_AUTOCOMMIT},
 
29
        {"bool", SQL_BOOL},
 
30
        {"break", SQL_BREAK},
 
31
        {"call", SQL_CALL},
 
32
        {"cardinality", SQL_CARDINALITY},
 
33
        {"connect", SQL_CONNECT},
 
34
        {"connection", SQL_CONNECTION},
 
35
        {"continue", SQL_CONTINUE},
 
36
        {"count", SQL_COUNT},
 
37
        {"current", SQL_CURRENT},
 
38
        {"data", SQL_DATA},
 
39
        {"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE},
 
40
        {"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION},
 
41
        {"describe", SQL_DESCRIBE},
 
42
        {"descriptor", SQL_DESCRIPTOR},
 
43
        {"disconnect", SQL_DISCONNECT},
 
44
        {"enum", SQL_ENUM},
 
45
        {"found", SQL_FOUND},
 
46
        {"free", SQL_FREE},
 
47
        {"go", SQL_GO},
 
48
        {"goto", SQL_GOTO},
 
49
        {"identified", SQL_IDENTIFIED},
 
50
        {"indicator", SQL_INDICATOR},
 
51
        {"key_member", SQL_KEY_MEMBER},
 
52
        {"length", SQL_LENGTH},
 
53
        {"long", SQL_LONG},
 
54
        {"name", SQL_NAME},
 
55
        {"nullable", SQL_NULLABLE},
 
56
        {"octet_length", SQL_OCTET_LENGTH},
 
57
        {"open", SQL_OPEN},
 
58
        {"output", SQL_OUTPUT},
 
59
        {"reference", SQL_REFERENCE},
 
60
        {"returned_length", SQL_RETURNED_LENGTH},
 
61
        {"returned_octet_length", SQL_RETURNED_OCTET_LENGTH},
 
62
        {"scale", SQL_SCALE},
 
63
        {"section", SQL_SECTION},
 
64
        {"short", SQL_SHORT},
 
65
        {"signed", SQL_SIGNED},
 
66
        {"sql", SQL_SQL},                       /* strange thing, used for into sql
 
67
                                                                 * descriptor MYDESC; */
 
68
        {"sqlerror", SQL_SQLERROR},
 
69
        {"sqlprint", SQL_SQLPRINT},
 
70
        {"sqlwarning", SQL_SQLWARNING},
 
71
        {"stop", SQL_STOP},
 
72
        {"struct", SQL_STRUCT},
 
73
        {"unsigned", SQL_UNSIGNED},
 
74
        {"value", SQL_VALUE},
 
75
        {"var", SQL_VAR},
 
76
        {"whenever", SQL_WHENEVER},
 
77
};
 
78
 
 
79
/*
 
80
 * ScanECPGKeywordLookup - see if a given word is a keyword
 
81
 *
 
82
 * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
 
83
 *
 
84
 * The match is done case-insensitively.  Note that we deliberately use a
 
85
 * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
 
86
 * even if we are in a locale where tolower() would produce more or different
 
87
 * translations.  This is to conform to the SQL99 spec, which says that
 
88
 * keywords are to be matched in this way even though non-keyword identifiers
 
89
 * receive a different case-normalization mapping.
 
90
 */
 
91
ScanKeyword *
 
92
ScanECPGKeywordLookup(char *text)
 
93
{
 
94
        int                     len,
 
95
                                i;
 
96
        char            word[NAMEDATALEN];
 
97
        ScanKeyword *low;
 
98
        ScanKeyword *high;
 
99
 
 
100
        len = strlen(text);
 
101
        /* We assume all keywords are shorter than NAMEDATALEN. */
 
102
        if (len >= NAMEDATALEN)
 
103
                return NULL;
 
104
 
 
105
        /*
 
106
         * Apply an ASCII-only downcasing.      We must not use tolower() since it
 
107
         * may produce the wrong translation in some locales (eg, Turkish),
 
108
         * and we don't trust isupper() very much either.  In an ASCII-based
 
109
         * encoding the tests against A and Z are sufficient, but we also
 
110
         * check isupper() so that we will work correctly under EBCDIC.  The
 
111
         * actual case conversion step should work for either ASCII or EBCDIC.
 
112
         */
 
113
        for (i = 0; i < len; i++)
 
114
        {
 
115
                char            ch = text[i];
 
116
 
 
117
                if (ch >= 'A' && ch <= 'Z' && isupper((unsigned char) ch))
 
118
                        ch += 'a' - 'A';
 
119
                word[i] = ch;
 
120
        }
 
121
        word[len] = '\0';
 
122
 
 
123
        /*
 
124
         * Now do a binary search using plain strcmp() comparison.
 
125
         */
 
126
        low = &ScanKeywords[0];
 
127
        high = endof(ScanKeywords) - 1;
 
128
        while (low <= high)
 
129
        {
 
130
                ScanKeyword *middle;
 
131
                int                     difference;
 
132
 
 
133
                middle = low + (high - low) / 2;
 
134
                difference = strcmp(middle->name, word);
 
135
                if (difference == 0)
 
136
                        return middle;
 
137
                else if (difference < 0)
 
138
                        low = middle + 1;
 
139
                else
 
140
                        high = middle - 1;
 
141
        }
 
142
 
 
143
        return NULL;
 
144
}