1 /*****************************************************************************
2  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
3  *                                                                           *
4  *   This program is free software; you can redistribute it and/or modify    *
5  *   it under the terms of the GNU Lesser General Public License as          *
6  *   published by the Free Software Foundation; either version 2.1 of the    *
7  *   License, or (at your option) version 3, or any later version accepted   *
8  *   by the membership of KDE e.V. (or its successor approved by the         *
9  *   membership of KDE e.V.), which shall act as a proxy defined in          *
10  *   Section 6 of version 3 of the license.                                  *
11  *                                                                           *
12  *   This program is distributed in the hope that it will be useful,         *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
15  *   Lesser General Public License for more details.                         *
16  *                                                                           *
17  *   You should have received a copy of the GNU Lesser General Public        *
18  *   License along with this library. If not,                                *
19  *   see <http://www.gnu.org/licenses/>.                                     *
20  *****************************************************************************/
21 
22 #include <qtcurve-utils/map.h>
23 #include <assert.h>
24 #include <ctype.h>
25 
26 #define STRINGS "jk", "yz", "OP", "LM", "XY", "FG", "MN", "st", "VW", "qr", \
27         "vw", "bc", "xy", "gh", "cd", "mn", "op", "ab", "[\\", "WX", "BC", \
28         "CD", "IJ", "QR", "Z[", "uv", "_`", "ij", "hi", "no", "HI", "DE", \
29         "YZ", "PQ", "ef", "de", "pq", "tu", "fg", "lm", "JK", "kl", "AB", \
30         "KL", "TU", "]^", "ST", "EF", "z{", "RS", "wx", "^_", "rs", "`a", \
31         "\\]", "UV", "GH", "NO"
32 
33 #define CASE_STRINGS "m_n", "tpu", "xty", "h`i", "\\l]", "_]`", "vnw", "_q`", \
34         "wyx", "oap", "ppq", "isj", "^v_", "k]l", "y_z", "]s^", "e[f", "w]x", \
35         "`pa", "^j_", "nro", "uwv", "[e\\", "cud", "cmd", "rns", "ugv", \
36         "fvg", "ewf", "rrs", "^b_", "ltm", "e_f", "cad", "t\\u", "vjw", \
37         "t`u", "cid", "q[r", "oqp", "gah", "lhm", "r^s", "ikj", "wex", "agb", \
38         "]w^", "p\\q", "awb", "acb", "_y`", "`da", "fjg", "qsr", "]g^", \
39         "usv", "kel", "p`q", "qcr", "icj", "tdu", "hpi", "^z_", "vvw", "kal", \
40         "ekf", "`ha", "akb", "dhe", "dte", "frg", "kul", "nno", "`\\a", \
41         "guh", "ffg", "omp", "qor", "hli", "igj", "oyp", "`ta", "ldm", "ywz", \
42         "jnk", "jrk", "\\`]", "njo", "mkn", "wix", "zb{", "ttu", "jzk", \
43         "oep", "zr{", "dle", "dpe", "xdy", "uov", "[y\\", "kyl", "zv{", \
44         "smt", "wax", "thu", "xpy", "d`e", "gih", "lpm", "h\\i", "x\\y", \
45         "[a\\", "fzg", "zz{", "sat", "eof", "[]\\", "hti", "v^w", "syt", \
46         "mgn", "y[z", "jfk", "s]t", "kil", "esf", "bnc", "oup", "set", "ycz", \
47         "aob", "wux", "pxq", "ygz", "mwn", "z^{", "xhy", "dxe", "i_j", "a[b", \
48         "q_r", "\\t]", "^^_", "n^o", "zn{", "sit", "bfc", "mcn", "rfs", \
49         "brc", "bjc", "\\d]", "ioj", "f^g", "\\h]", "iwj", "nzo", "u_v", \
50         "oip", "sqt", "vfw", "`la", "jbk", "hxi", "llm", "fbg", "phq", "jjk", \
51         "gyh", "qkr", "_m`", "nfo", "[i\\", "rvs", "bzc", "ukv", "u[v", \
52         "nvo", "_u`", "geh", "nbo", "bbc", "dde", "xly", "bvc", "qwr", "_a`", \
53         "ecf", "zj{", "tlu", "]k^", "a_b", "kql", "]c^", "][^", "wmx", "l`m", \
54         "^r_", "x`y", "rzs", "qgr", "_e`", "hdi", "\\x]", "\\p]", "ced", \
55         "sut", "[m\\", "cqd", "fng", "]_^", "d\\e", "kml", "txu", "m[n", \
56         "vzw", "gmh", "zf{", "vbw", "lxm", "rbs", "[q\\", "cyd", "rjs", \
57         "^n_", "j^k", "pdq", "vrw", "plq", "yoz", "mon", "b^c", "i[j", \
58         "l\\m", "\\\\]", "_i`", "egf", "hhi", "ysz", "gqh", "c]d", "xxy", \
59         "msn", "``a", "jvk", "asb", "ucv", "]o^", "ptq", "ykz", "o]p", "`xa", \
60         "[u\\", "g]h", "wqx", "^f_"
61 
62 static int
search_map(const char * str)63 search_map(const char *str)
64 {
65     static const QtCurve::StrMap<> auto_map(STRINGS);
66     return auto_map.search(str);
67 }
68 
69 #ifndef __clang__
70 // clang doesn't like template recursion deeper than 256 levels....
71 static int
search_case_map(const char * str)72 search_case_map(const char *str)
73 {
74     static const QtCurve::StrMap<int, false> auto_map(CASE_STRINGS);
75     return auto_map.search(str);
76 }
77 #endif
78 
79 int
main()80 main()
81 {
82     const char *real_order[] = {STRINGS};
83     char key[4];
84     key[3] = 0;
85     for (char i = 0;i < 127;i++) {
86         key[0] = i;
87         for (char j = 0;j < 127;j++) {
88             key[1] = j;
89             for (char k = 0;k < 127;k++) {
90                 key[2] = k;
91                 int res = search_map(key);
92                 if (i >= 'A' && i <= 'z' && j == i + 1 && k == 0) {
93                     assert(res != -1 && strcmp(real_order[res], key) == 0);
94                 } else {
95                     assert(res == -1);
96                 }
97             }
98         }
99     }
100 #ifndef __clang__
101     const char *case_real_order[] = {CASE_STRINGS};
102     for (char i = 0;i < 127;i++) {
103         key[0] = i;
104         for (char j = 0;j < 127;j++) {
105             key[1] = j;
106             for (char k = 0;k < 127;k++) {
107                 key[2] = k;
108                 int res = search_case_map(key);
109                 char _i = tolower(i);
110                 char _j = tolower(j);
111                 char _k = tolower(k);
112                 if (_i > 'Z' && _i <= 'z' && _j > 'Z' && _j <= 'z' &&
113                     _k == _i + 1 && (_i + _j) % 4 == 0) {
114                     assert(res != -1 &&
115                            strcasecmp(case_real_order[res], key) == 0);
116                 } else {
117                     assert(res == -1);
118                 }
119             }
120         }
121     }
122 #endif
123     return 0;
124 }
125