1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * c_keywords.c |
4 | * lexical token lookup for reserved words in postgres embedded SQL |
5 | * |
6 | * src/interfaces/ecpg/preproc/c_keywords.c |
7 | * |
8 | *------------------------------------------------------------------------- |
9 | */ |
10 | #include "postgres_fe.h" |
11 | |
12 | #include "preproc_extern.h" |
13 | #include "preproc.h" |
14 | |
15 | /* ScanKeywordList lookup data for C keywords */ |
16 | #include "c_kwlist_d.h" |
17 | |
18 | /* Token codes for C keywords */ |
19 | #define PG_KEYWORD(kwname, value) value, |
20 | |
21 | static const uint16 ScanCKeywordTokens[] = { |
22 | #include "c_kwlist.h" |
23 | }; |
24 | |
25 | #undef PG_KEYWORD |
26 | |
27 | |
28 | /* |
29 | * ScanCKeywordLookup - see if a given word is a keyword |
30 | * |
31 | * Returns the token value of the keyword, or -1 if no match. |
32 | * |
33 | * Do a hash search using plain strcmp() comparison. This is much like |
34 | * ScanKeywordLookup(), except we want case-sensitive matching. |
35 | */ |
36 | int |
37 | ScanCKeywordLookup(const char *str) |
38 | { |
39 | size_t len; |
40 | int h; |
41 | const char *kw; |
42 | |
43 | /* |
44 | * Reject immediately if too long to be any keyword. This saves useless |
45 | * hashing work on long strings. |
46 | */ |
47 | len = strlen(str); |
48 | if (len > ScanCKeywords.max_kw_len) |
49 | return -1; |
50 | |
51 | /* |
52 | * Compute the hash function. Since it's a perfect hash, we need only |
53 | * match to the specific keyword it identifies. |
54 | */ |
55 | h = ScanCKeywords_hash_func(str, len); |
56 | |
57 | /* An out-of-range result implies no match */ |
58 | if (h < 0 || h >= ScanCKeywords.num_keywords) |
59 | return -1; |
60 | |
61 | kw = GetScanKeyword(h, &ScanCKeywords); |
62 | |
63 | if (strcmp(kw, str) == 0) |
64 | return ScanCKeywordTokens[h]; |
65 | |
66 | return -1; |
67 | } |
68 | |