1 /*-------------------------------------------------------------------------
2  *
3  * ecpg_keywords.c
4  *	  lexical token lookup for reserved words in postgres embedded SQL
5  *
6  * IDENTIFICATION
7  *	  src/interfaces/ecpg/preproc/ecpg_keywords.c
8  *
9  *-------------------------------------------------------------------------
10  */
11 
12 #include "postgres_fe.h"
13 
14 #include <ctype.h>
15 
16 #include "extern.h"
17 #include "preproc.h"
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 const ScanKeyword ECPGScanKeywords[] = {
26 	/* name, value, category */
27 
28 	/*
29 	 * category is not needed in ecpg, it is only here so we can share the
30 	 * data structure with the backend
31 	 */
32 	{"allocate", SQL_ALLOCATE, 0},
33 	{"autocommit", SQL_AUTOCOMMIT, 0},
34 	{"bool", SQL_BOOL, 0},
35 	{"break", SQL_BREAK, 0},
36 	{"call", SQL_CALL, 0},
37 	{"cardinality", SQL_CARDINALITY, 0},
38 	{"connect", SQL_CONNECT, 0},
39 	{"count", SQL_COUNT, 0},
40 	{"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE, 0},
41 	{"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION, 0},
42 	{"describe", SQL_DESCRIBE, 0},
43 	{"descriptor", SQL_DESCRIPTOR, 0},
44 	{"disconnect", SQL_DISCONNECT, 0},
45 	{"found", SQL_FOUND, 0},
46 	{"free", SQL_FREE, 0},
47 	{"get", SQL_GET, 0},
48 	{"go", SQL_GO, 0},
49 	{"goto", SQL_GOTO, 0},
50 	{"identified", SQL_IDENTIFIED, 0},
51 	{"indicator", SQL_INDICATOR, 0},
52 	{"key_member", SQL_KEY_MEMBER, 0},
53 	{"length", SQL_LENGTH, 0},
54 	{"long", SQL_LONG, 0},
55 	{"nullable", SQL_NULLABLE, 0},
56 	{"octet_length", SQL_OCTET_LENGTH, 0},
57 	{"open", SQL_OPEN, 0},
58 	{"output", SQL_OUTPUT, 0},
59 	{"reference", SQL_REFERENCE, 0},
60 	{"returned_length", SQL_RETURNED_LENGTH, 0},
61 	{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0},
62 	{"scale", SQL_SCALE, 0},
63 	{"section", SQL_SECTION, 0},
64 	{"short", SQL_SHORT, 0},
65 	{"signed", SQL_SIGNED, 0},
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},
74 };
75 
76 /*
77  * ScanECPGKeywordLookup - see if a given word is a keyword
78  *
79  * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
80  * Keywords are matched using the same case-folding rules as in the backend.
81  */
82 const ScanKeyword *
ScanECPGKeywordLookup(const char * text)83 ScanECPGKeywordLookup(const char *text)
84 {
85 	const ScanKeyword *res;
86 
87 	/* First check SQL symbols defined by the backend. */
88 	res = ScanKeywordLookup(text, SQLScanKeywords, NumSQLScanKeywords);
89 	if (res)
90 		return res;
91 
92 	/* Try ECPG-specific keywords. */
93 	res = ScanKeywordLookup(text, ECPGScanKeywords, lengthof(ECPGScanKeywords));
94 	if (res)
95 		return res;
96 
97 	return NULL;
98 }
99