1 /* 2 * Copyright (c) 2016,2017,2019 Daichi GOTO 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #define VERSION "20190812" 29 #define CMDNAME "gyo_select" 30 #define ALIAS "gyosel row_select" 31 32 #include <limits.h> 33 #ifdef __linux__ 34 #include <db_185.h> 35 #else 36 #include <db.h> 37 #endif 38 39 #include "ttt.h" 40 41 void simple_comparison(int, char**); 42 43 #define TGT_RETU_PROCESS(BUF,BUFLEN,INDEX) \ 44 fp_no_output = 1; \ 45 b_key.data = BUF; \ 46 b_key.size = strlen(b_key.data) + 1; \ 47 b_val.data = "1"; \ 48 b_val.size = 2; \ 49 trees[i]->put(trees[i], &b_key, &b_val, 0); 50 51 #define NOTGT_RETU_PROCESS(BUF,BUFLEN,INDEX) \ 52 fp_no_output = 1; \ 53 54 #define END_OF_LINE_RETU_PROCESS 55 56 #define TGT_GYO_PROCESS(GYO_BUFFER,NF) \ 57 nf = NF; \ 58 if (FLAG_1 && first_line) { \ 59 first_line = 0; \ 60 goto gyo_not_match; \ 61 } \ 62 if (!FLAG_o) { \ 63 /* AND CONDITION */ \ 64 for (int i = 1; i <= match_count; i++) { \ 65 if (NF < R_ARGV[i]) \ 66 goto gyo_not_match; \ 67 if ('!' != R_ARGV_DELIM[i] && \ 68 '@' == GYO_BUFFER[R_ARGV[i]][0] && \ 69 '\0' == GYO_BUFFER[R_ARGV[i]][1] && \ 70 !('@' == R_ARGV_ARG1[i][0] && \ 71 '\0' == R_ARGV_ARG1[i][1])) \ 72 goto gyo_not_match; \ 73 if (NULL != trees[i]) { \ 74 b_key.data = GYO_BUFFER[R_ARGV[i]]; \ 75 b_key.size = strlen(b_key.data) + 1; \ 76 if (1 == trees[i]->get(trees[i], \ 77 &b_key, &b_val, 0)) \ 78 goto gyo_not_match; \ 79 } \ 80 else { \ 81 if (FLAG_N) { \ 82 errno = 0; \ 83 n1 = strtoll(GYO_BUFFER[R_ARGV[i]],\ 84 (char **)NULL, 10); \ 85 if (EINVAL == errno) \ 86 goto gyo_not_match; \ 87 cmpret = 0; \ 88 if (n1 > n2[i]) \ 89 cmpret = 1; \ 90 else if (n1 < n2[i]) \ 91 cmpret = -1; \ 92 } \ 93 else \ 94 cmpret = \ 95 strcmp(GYO_BUFFER[R_ARGV[i]], \ 96 R_ARGV_ARG1[i]); \ 97 switch (R_ARGV_DELIM[i]) { \ 98 case '>': \ 99 if (0 >= cmpret) \ 100 goto gyo_not_match; \ 101 break; \ 102 case '<': \ 103 if (0 <= cmpret) \ 104 goto gyo_not_match; \ 105 break; \ 106 case '!': \ 107 if (0 == cmpret) \ 108 goto gyo_not_match; \ 109 break; \ 110 default: \ 111 if (0 != cmpret) \ 112 goto gyo_not_match; \ 113 break; \ 114 } \ 115 } \ 116 } \ 117 goto gyo_match; \ 118 } \ 119 else { \ 120 /* OR CONDITION */ \ 121 for (int i = 1; i <= match_count; i++) { \ 122 if (NF < R_ARGV[i]) \ 123 goto gyo_not_match; \ 124 if ('!' != R_ARGV_DELIM[i] && \ 125 '@' == GYO_BUFFER[R_ARGV[i]][0] && \ 126 '\0' == GYO_BUFFER[R_ARGV[i]][1] && \ 127 !('@' == R_ARGV_ARG1[i][0] && \ 128 '\0' == R_ARGV_ARG1[i][1])) \ 129 continue; \ 130 if (NULL != trees[i]) { \ 131 b_key.data = GYO_BUFFER[R_ARGV[i]]; \ 132 b_key.size = strlen(b_key.data) + 1; \ 133 if (0 == trees[i]->get(trees[i], \ 134 &b_key, &b_val, 0)) \ 135 goto gyo_match; \ 136 } \ 137 else { \ 138 if (FLAG_N) { \ 139 errno = 0; \ 140 n1 = strtoll(GYO_BUFFER[R_ARGV[i]],\ 141 (char **)NULL, 10); \ 142 if (EINVAL == errno) \ 143 continue; \ 144 cmpret = 0; \ 145 if (n1 > n2[i]) \ 146 cmpret = 1; \ 147 else if (n1 < n2[i]) \ 148 cmpret = -1; \ 149 } \ 150 else \ 151 cmpret = \ 152 strcmp(GYO_BUFFER[R_ARGV[i]], \ 153 R_ARGV_ARG1[i]); \ 154 switch (R_ARGV_DELIM[i]) { \ 155 case '>': \ 156 if (0 < cmpret) \ 157 goto gyo_match; \ 158 break; \ 159 case '<': \ 160 if (0 > cmpret) \ 161 goto gyo_match; \ 162 break; \ 163 case '!': \ 164 if (0 != cmpret) \ 165 goto gyo_match; \ 166 break; \ 167 default: \ 168 if (0 == cmpret) \ 169 goto gyo_match; \ 170 break; \ 171 } \ 172 } \ 173 } \ 174 goto gyo_not_match; \ 175 } \ 176 gyo_match: \ 177 match_or_not = 0; \ 178 if (!FLAG_n) { \ 179 if (R_ARGC == match_count) { \ 180 for (int i = 1; i < NF; i++) \ 181 PRINT(GYO_BUFFER[i], " "); \ 182 PRINT(GYO_BUFFER[NF], "\n"); \ 183 } \ 184 else { \ 185 for (int i = match_count+1; i < R_ARGC; i++) \ 186 if (R_ARGV[i] > NF || \ 187 NULL == GYO_BUFFER[R_ARGV[i]]) { \ 188 PRINT("@", " "); \ 189 } \ 190 else { \ 191 PRINT(GYO_BUFFER[R_ARGV[i]], " "); \ 192 } \ 193 if (R_ARGV[R_ARGC] > NF || \ 194 NULL == GYO_BUFFER[R_ARGV[R_ARGC]]) { \ 195 PRINT("@", "\n"); \ 196 } \ 197 else \ 198 PRINT(GYO_BUFFER[R_ARGV[R_ARGC]], "\n"); \ 199 } \ 200 } \ 201 gyo_not_match: 202 203 #define PRINT(TARGET,DELIMITER) \ 204 if ('@' == TARGET[0] && '\0' == TARGET[1]) { \ 205 printf("%s%s", val, DELIMITER); \ 206 } \ 207 else \ 208 printf("%s%s", TARGET, DELIMITER); 209