This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Replace repetitive code in lib/File/stat.t with a data driven loop.
[perl5.git] / ext / SDBM_File / sdbm / dbe.c
CommitLineData
463ee0b2
LW
1#include <stdio.h>
2#ifndef VMS
3#include <sys/file.h>
4#include <ndbm.h>
5#else
6#include "file.h"
7#include "ndbm.h"
8#endif
9#include <ctype.h>
10
11/***************************************************************************\
12** **
13** Function name: getopt() **
14** Author: Henry Spencer, UofT **
15** Coding date: 84/04/28 **
16** **
17** Description: **
18** **
19** Parses argv[] for arguments. **
20** Works with Whitesmith's C compiler. **
21** **
22** Inputs - The number of arguments **
23** - The base address of the array of arguments **
24** - A string listing the valid options (':' indicates an **
25** argument to the preceding option is required, a ';' **
26** indicates an argument to the preceding option is optional) **
27** **
28** Outputs - Returns the next option character, **
29** '?' for non '-' arguments **
30** or ':' when there is no more arguments. **
31** **
32** Side Effects + The argument to an option is pointed to by 'optarg' **
33** **
34*****************************************************************************
35** **
36** REVISION HISTORY: **
37** **
38** DATE NAME DESCRIPTION **
39** YY/MM/DD ------------------ ------------------------------------ **
40** 88/10/20 Janick Bergeron Returns '?' on unamed arguments **
41** returns '!' on unknown options **
42** and 'EOF' only when exhausted. **
43** 88/11/18 Janick Bergeron Return ':' when no more arguments **
44** 89/08/11 Janick Bergeron Optional optarg when ';' in optstring **
45** **
46\***************************************************************************/
47
48char *optarg; /* Global argument pointer. */
49
50#ifdef VMS
51#define index strchr
52#endif
53
54char
ba106d47 55getopt(int argc, char **argv, char *optstring)
463ee0b2
LW
56{
57 register int c;
58 register char *place;
59 extern char *index();
60 static int optind = 0;
61 static char *scan = NULL;
62
63 optarg = NULL;
64
65 if (scan == NULL || *scan == '\0') {
66
67 if (optind == 0)
68 optind++;
69 if (optind >= argc)
70 return ':';
71
72 optarg = place = argv[optind++];
73 if (place[0] != '-' || place[1] == '\0')
74 return '?';
75 if (place[1] == '-' && place[2] == '\0')
76 return '?';
77 scan = place + 1;
78 }
79
80 c = *scan++;
81 place = index(optstring, c);
82 if (place == NULL || c == ':' || c == ';') {
83
84 (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
85 scan = NULL;
86 return '!';
87 }
88 if (*++place == ':') {
89
90 if (*scan != '\0') {
91
92 optarg = scan;
93 scan = NULL;
94
95 }
96 else {
97
98 if (optind >= argc) {
99
100 (void) fprintf(stderr, "%s: %c requires an argument\n",
101 argv[0], c);
102 return '!';
103 }
104 optarg = argv[optind];
105 optind++;
106 }
107 }
108 else if (*place == ';') {
109
110 if (*scan != '\0') {
111
112 optarg = scan;
113 scan = NULL;
114
115 }
116 else {
117
118 if (optind >= argc || *argv[optind] == '-')
119 optarg = NULL;
120 else {
121 optarg = argv[optind];
122 optind++;
123 }
124 }
125 }
126 return c;
127}
128
129
130void
ba106d47 131print_datum(datum db)
463ee0b2
LW
132{
133 int i;
134
135 putchar('"');
136 for (i = 0; i < db.dsize; i++) {
de030af3 137 if (isprint((unsigned char)db.dptr[i]))
463ee0b2
LW
138 putchar(db.dptr[i]);
139 else {
140 putchar('\\');
141 putchar('0' + ((db.dptr[i] >> 6) & 0x07));
142 putchar('0' + ((db.dptr[i] >> 3) & 0x07));
143 putchar('0' + (db.dptr[i] & 0x07));
144 }
145 }
146 putchar('"');
147}
148
149
150datum
ba106d47 151read_datum(char *s)
463ee0b2
LW
152{
153 datum db;
154 char *p;
155 int i;
156
157 db.dsize = 0;
158 db.dptr = (char *) malloc(strlen(s) * sizeof(char));
db7c17d7
GS
159 if (!db.dptr)
160 oops("cannot get memory");
161
463ee0b2
LW
162 for (p = db.dptr; *s != '\0'; p++, db.dsize++, s++) {
163 if (*s == '\\') {
164 if (*++s == 'n')
165 *p = '\n';
166 else if (*s == 'r')
167 *p = '\r';
168 else if (*s == 'f')
169 *p = '\f';
170 else if (*s == 't')
171 *p = '\t';
de030af3
GS
172 else if (isdigit((unsigned char)*s)
173 && isdigit((unsigned char)*(s + 1))
174 && isdigit((unsigned char)*(s + 2)))
175 {
463ee0b2
LW
176 i = (*s++ - '0') << 6;
177 i |= (*s++ - '0') << 3;
178 i |= *s - '0';
179 *p = i;
180 }
181 else if (*s == '0')
182 *p = '\0';
183 else
184 *p = *s;
185 }
186 else
187 *p = *s;
188 }
189
190 return db;
191}
192
193
194char *
ba106d47 195key2s(datum db)
463ee0b2
LW
196{
197 char *buf;
198 char *p1, *p2;
199
200 buf = (char *) malloc((db.dsize + 1) * sizeof(char));
db7c17d7
GS
201 if (!buf)
202 oops("cannot get memory");
463ee0b2
LW
203 for (p1 = buf, p2 = db.dptr; *p2 != '\0'; *p1++ = *p2++);
204 *p1 = '\0';
205 return buf;
206}
207
ba106d47
GS
208int
209main(int argc, char **argv)
463ee0b2
LW
210{
211 typedef enum {
212 YOW, FETCH, STORE, DELETE, SCAN, REGEXP
213 } commands;
214 char opt;
215 int flags;
216 int giveusage = 0;
217 int verbose = 0;
218 commands what = YOW;
219 char *comarg[3];
220 int st_flag = DBM_INSERT;
221 int argn;
222 DBM *db;
223 datum key;
224 datum content;
225
226 flags = O_RDWR;
227 argn = 0;
228
229 while ((opt = getopt(argc, argv, "acdfFm:rstvx")) != ':') {
230 switch (opt) {
231 case 'a':
232 what = SCAN;
233 break;
234 case 'c':
235 flags |= O_CREAT;
236 break;
237 case 'd':
238 what = DELETE;
239 break;
240 case 'f':
241 what = FETCH;
242 break;
243 case 'F':
244 what = REGEXP;
245 break;
246 case 'm':
247 flags &= ~(000007);
248 if (strcmp(optarg, "r") == 0)
249 flags |= O_RDONLY;
250 else if (strcmp(optarg, "w") == 0)
251 flags |= O_WRONLY;
252 else if (strcmp(optarg, "rw") == 0)
253 flags |= O_RDWR;
254 else {
255 fprintf(stderr, "Invalid mode: \"%s\"\n", optarg);
256 giveusage = 1;
257 }
258 break;
259 case 'r':
260 st_flag = DBM_REPLACE;
261 break;
262 case 's':
263 what = STORE;
264 break;
265 case 't':
266 flags |= O_TRUNC;
267 break;
268 case 'v':
269 verbose = 1;
270 break;
271 case 'x':
272 flags |= O_EXCL;
273 break;
274 case '!':
275 giveusage = 1;
276 break;
277 case '?':
278 if (argn < 3)
279 comarg[argn++] = optarg;
280 else {
281 fprintf(stderr, "Too many arguments.\n");
282 giveusage = 1;
283 }
284 break;
285 }
286 }
287
db7c17d7 288 if (giveusage || what == YOW || argn < 1) {
b7b1e41b 289 fprintf(stderr, "Usage: %s database [-m r|w|rw] [-crtx] -a|-d|-f|-F|-s [key [content]]\n", argv[0]);
463ee0b2
LW
290 exit(-1);
291 }
292
293 if ((db = dbm_open(comarg[0], flags, 0777)) == NULL) {
294 fprintf(stderr, "Error opening database \"%s\"\n", comarg[0]);
295 exit(-1);
296 }
297
298 if (argn > 1)
299 key = read_datum(comarg[1]);
300 if (argn > 2)
301 content = read_datum(comarg[2]);
302
303 switch (what) {
304
305 case SCAN:
306 key = dbm_firstkey(db);
307 if (dbm_error(db)) {
308 fprintf(stderr, "Error when fetching first key\n");
309 goto db_exit;
310 }
311 while (key.dptr != NULL) {
312 content = dbm_fetch(db, key);
313 if (dbm_error(db)) {
314 fprintf(stderr, "Error when fetching ");
315 print_datum(key);
316 printf("\n");
317 goto db_exit;
318 }
319 print_datum(key);
320 printf(": ");
321 print_datum(content);
322 printf("\n");
323 if (dbm_error(db)) {
324 fprintf(stderr, "Error when fetching next key\n");
325 goto db_exit;
326 }
327 key = dbm_nextkey(db);
328 }
329 break;
330
331 case REGEXP:
332 if (argn < 2) {
333 fprintf(stderr, "Missing regular expression.\n");
334 goto db_exit;
335 }
336 if (re_comp(comarg[1])) {
337 fprintf(stderr, "Invalid regular expression\n");
338 goto db_exit;
339 }
340 key = dbm_firstkey(db);
341 if (dbm_error(db)) {
342 fprintf(stderr, "Error when fetching first key\n");
343 goto db_exit;
344 }
345 while (key.dptr != NULL) {
346 if (re_exec(key2s(key))) {
347 content = dbm_fetch(db, key);
348 if (dbm_error(db)) {
349 fprintf(stderr, "Error when fetching ");
350 print_datum(key);
351 printf("\n");
352 goto db_exit;
353 }
354 print_datum(key);
355 printf(": ");
356 print_datum(content);
357 printf("\n");
358 if (dbm_error(db)) {
359 fprintf(stderr, "Error when fetching next key\n");
360 goto db_exit;
361 }
362 }
363 key = dbm_nextkey(db);
364 }
365 break;
366
367 case FETCH:
368 if (argn < 2) {
369 fprintf(stderr, "Missing fetch key.\n");
370 goto db_exit;
371 }
372 content = dbm_fetch(db, key);
373 if (dbm_error(db)) {
374 fprintf(stderr, "Error when fetching ");
375 print_datum(key);
376 printf("\n");
377 goto db_exit;
378 }
379 if (content.dptr == NULL) {
380 fprintf(stderr, "Cannot find ");
381 print_datum(key);
382 printf("\n");
383 goto db_exit;
384 }
385 print_datum(key);
386 printf(": ");
387 print_datum(content);
388 printf("\n");
389 break;
390
391 case DELETE:
392 if (argn < 2) {
393 fprintf(stderr, "Missing delete key.\n");
394 goto db_exit;
395 }
396 if (dbm_delete(db, key) || dbm_error(db)) {
397 fprintf(stderr, "Error when deleting ");
398 print_datum(key);
399 printf("\n");
400 goto db_exit;
401 }
402 if (verbose) {
403 print_datum(key);
404 printf(": DELETED\n");
405 }
406 break;
407
408 case STORE:
409 if (argn < 3) {
410 fprintf(stderr, "Missing key and/or content.\n");
411 goto db_exit;
412 }
413 if (dbm_store(db, key, content, st_flag) || dbm_error(db)) {
414 fprintf(stderr, "Error when storing ");
415 print_datum(key);
416 printf("\n");
417 goto db_exit;
418 }
419 if (verbose) {
420 print_datum(key);
421 printf(": ");
422 print_datum(content);
423 printf(" STORED\n");
424 }
425 break;
426 }
427
428db_exit:
429 dbm_clearerr(db);
430 dbm_close(db);
431 if (dbm_error(db)) {
432 fprintf(stderr, "Error closing database \"%s\"\n", comarg[0]);
433 exit(-1);
434 }
435}