Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / backend / parser / kwlookup.c
blobf941837fb19355ea8c033755d116f9874794aaee
1 /*-------------------------------------------------------------------------
3 * kwlookup.c
4 * lexical token lookup for key words in PostgreSQL
6 * NB - this file is also used by ECPG and several frontend programs in
7 * src/bin/ including pg_dump and psql
9 * Note that this file expects that the ScanKeywords array is defined
10 * and that LastScanKeyword points to its element one past the last.
12 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
16 * IDENTIFICATION
17 * $PostgreSQL$
19 *-------------------------------------------------------------------------
22 /* use c.h so this can be built as either frontend or backend */
23 #include "c.h"
25 #include <ctype.h>
27 #include "parser/keywords.h"
30 * ScanKeywordLookup - see if a given word is a keyword
32 * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
34 * The match is done case-insensitively. Note that we deliberately use a
35 * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
36 * even if we are in a locale where tolower() would produce more or different
37 * translations. This is to conform to the SQL99 spec, which says that
38 * keywords are to be matched in this way even though non-keyword identifiers
39 * receive a different case-normalization mapping.
41 const ScanKeyword *
42 ScanKeywordLookup(const char *text)
44 int len,
46 char word[NAMEDATALEN];
47 const ScanKeyword *low;
48 const ScanKeyword *high;
50 len = strlen(text);
51 /* We assume all keywords are shorter than NAMEDATALEN. */
52 if (len >= NAMEDATALEN)
53 return NULL;
56 * Apply an ASCII-only downcasing. We must not use tolower() since it may
57 * produce the wrong translation in some locales (eg, Turkish).
59 for (i = 0; i < len; i++)
61 char ch = text[i];
63 if (ch >= 'A' && ch <= 'Z')
64 ch += 'a' - 'A';
65 word[i] = ch;
67 word[len] = '\0';
70 * Now do a binary search using plain strcmp() comparison.
72 low = &ScanKeywords[0];
73 high = LastScanKeyword - 1;
74 while (low <= high)
76 const ScanKeyword *middle;
77 int difference;
79 middle = low + (high - low) / 2;
80 difference = strcmp(middle->name, word);
81 if (difference == 0)
82 return middle;
83 else if (difference < 0)
84 low = middle + 1;
85 else
86 high = middle - 1;
89 return NULL;