diff options
Diffstat (limited to 'gnu/usr.bin/cvs/lib/myndbm.c')
-rw-r--r-- | gnu/usr.bin/cvs/lib/myndbm.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/gnu/usr.bin/cvs/lib/myndbm.c b/gnu/usr.bin/cvs/lib/myndbm.c new file mode 100644 index 0000000..8069698 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/myndbm.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 1992, Brian Berliner + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with the CVS 1.3 kit. + * + * A simple ndbm-emulator for CVS. It parses a text file of the format: + * + * key value + * + * at dbm_open time, and loads the entire file into memory. As such, it is + * probably only good for fairly small modules files. Ours is about 30K in + * size, and this code works fine. + */ + +#include "cvs.h" + +#ifdef MY_NDBM + +#ifndef lint +static char rcsid[] = "@(#)myndbm.c 1.5 92/03/31"; +#endif + +static void mydbm_load_file (); + +/* ARGSUSED */ +DBM * +mydbm_open (file, flags, mode) + char *file; + int flags; + int mode; +{ + FILE *fp; + DBM *db; + + if ((fp = fopen (file, "r")) == NULL) + return ((DBM *) 0); + + db = (DBM *) xmalloc (sizeof (*db)); + db->dbm_list = getlist (); + + mydbm_load_file (fp, db->dbm_list); + (void) fclose (fp); + return (db); +} + +void +mydbm_close (db) + DBM *db; +{ + dellist (&db->dbm_list); + free ((char *) db); +} + +datum +mydbm_fetch (db, key) + DBM *db; + datum key; +{ + Node *p; + char *s; + datum val; + + /* make sure it's null-terminated */ + s = xmalloc (key.dsize + 1); + (void) strncpy (s, key.dptr, key.dsize); + s[key.dsize] = '\0'; + + p = findnode (db->dbm_list, s); + if (p) + { + val.dptr = p->data; + val.dsize = strlen (p->data); + } + else + { + val.dptr = (char *) NULL; + val.dsize = 0; + } + free (s); + return (val); +} + +datum +mydbm_firstkey (db) + DBM *db; +{ + Node *head, *p; + datum key; + + head = db->dbm_list->list; + p = head->next; + if (p != head) + { + key.dptr = p->key; + key.dsize = strlen (p->key); + } + else + { + key.dptr = (char *) NULL; + key.dsize = 0; + } + db->dbm_next = p->next; + return (key); +} + +datum +mydbm_nextkey (db) + DBM *db; +{ + Node *head, *p; + datum key; + + head = db->dbm_list->list; + p = db->dbm_next; + if (p != head) + { + key.dptr = p->key; + key.dsize = strlen (p->key); + } + else + { + key.dptr = (char *) NULL; + key.dsize = 0; + } + db->dbm_next = p->next; + return (key); +} + +static void +mydbm_load_file (fp, list) + FILE *fp; + List *list; +{ + char line[MAXLINELEN], value[MAXLINELEN]; + char *cp, *vp; + int len, cont; + + for (cont = 0; fgets (line, sizeof (line), fp) != NULL;) + { + if ((cp = rindex (line, '\n')) != NULL) + *cp = '\0'; /* strip the newline */ + + /* + * Add the line to the value, at the end if this is a continuation + * line; otherwise at the beginning, but only after any trailing + * backslash is removed. + */ + vp = value; + if (cont) + vp += strlen (value); + + /* + * See if the line we read is a continuation line, and strip the + * backslash if so. + */ + len = strlen (line); + if (len > 0) + cp = &line[len - 1]; + else + cp = line; + if (*cp == '\\') + { + cont = 1; + *cp = '\0'; + } + else + { + cont = 0; + } + (void) strcpy (vp, line); + if (value[0] == '#') + continue; /* comment line */ + vp = value; + while (*vp && isspace (*vp)) + vp++; + if (*vp == '\0') + continue; /* empty line */ + + /* + * If this was not a continuation line, add the entry to the database + */ + if (!cont) + { + Node *p = getnode (); + char *kp; + + kp = vp; + while (*vp && !isspace (*vp)) + vp++; + *vp++ = '\0'; /* NULL terminate the key */ + p->type = NDBMNODE; + p->key = xstrdup (kp); + while (*vp && isspace (*vp)) + vp++; /* skip whitespace to value */ + if (*vp == '\0') + { + error (0, 0, "warning: NULL value for key `%s'", p->key); + freenode (p); + continue; + } + p->data = xstrdup (vp); + if (addnode (list, p) == -1) + { + error (0, 0, "duplicate key found for `%s'", p->key); + freenode (p); + } + } + } +} + +#endif /* MY_NDBM */ |