386BSD 0.1 development
[unix-history] / usr / othersrc / public / cvs-1.3 / src / myndbm.c
CommitLineData
fe37a9c9
WJ
1/*
2 * Copyright (c) 1992, Brian Berliner
3 *
4 * You may distribute under the terms of the GNU General Public License as
5 * specified in the README file that comes with the CVS 1.3 kit.
6 *
7 * A simple ndbm-emulator for CVS. It parses a text file of the format:
8 *
9 * key value
10 *
11 * at dbm_open time, and loads the entire file into memory. As such, it is
12 * probably only good for fairly small modules files. Ours is about 30K in
13 * size, and this code works fine.
14 */
15
16#include "cvs.h"
17
18#ifdef MY_NDBM
19
20#ifndef lint
21static char rcsid[] = "@(#)myndbm.c 1.5 92/03/31";
22#endif
23
24static void mydbm_load_file ();
25
26/* ARGSUSED */
27DBM *
28mydbm_open (file, flags, mode)
29 char *file;
30 int flags;
31 int mode;
32{
33 FILE *fp;
34 DBM *db;
35
36 if ((fp = fopen (file, "r")) == NULL)
37 return ((DBM *) 0);
38
39 db = (DBM *) xmalloc (sizeof (*db));
40 db->dbm_list = getlist ();
41
42 mydbm_load_file (fp, db->dbm_list);
43 (void) fclose (fp);
44 return (db);
45}
46
47void
48mydbm_close (db)
49 DBM *db;
50{
51 dellist (&db->dbm_list);
52 free ((char *) db);
53}
54
55datum
56mydbm_fetch (db, key)
57 DBM *db;
58 datum key;
59{
60 Node *p;
61 char *s;
62 datum val;
63
64 /* make sure it's null-terminated */
65 s = xmalloc (key.dsize + 1);
66 (void) strncpy (s, key.dptr, key.dsize);
67 s[key.dsize] = '\0';
68
69 p = findnode (db->dbm_list, s);
70 if (p)
71 {
72 val.dptr = p->data;
73 val.dsize = strlen (p->data);
74 }
75 else
76 {
77 val.dptr = (char *) NULL;
78 val.dsize = 0;
79 }
80 free (s);
81 return (val);
82}
83
84datum
85mydbm_firstkey (db)
86 DBM *db;
87{
88 Node *head, *p;
89 datum key;
90
91 head = db->dbm_list->list;
92 p = head->next;
93 if (p != head)
94 {
95 key.dptr = p->key;
96 key.dsize = strlen (p->key);
97 }
98 else
99 {
100 key.dptr = (char *) NULL;
101 key.dsize = 0;
102 }
103 db->dbm_next = p->next;
104 return (key);
105}
106
107datum
108mydbm_nextkey (db)
109 DBM *db;
110{
111 Node *head, *p;
112 datum key;
113
114 head = db->dbm_list->list;
115 p = db->dbm_next;
116 if (p != head)
117 {
118 key.dptr = p->key;
119 key.dsize = strlen (p->key);
120 }
121 else
122 {
123 key.dptr = (char *) NULL;
124 key.dsize = 0;
125 }
126 db->dbm_next = p->next;
127 return (key);
128}
129
130static void
131mydbm_load_file (fp, list)
132 FILE *fp;
133 List *list;
134{
135 char line[MAXLINELEN], value[MAXLINELEN];
136 char *cp, *vp;
137 int len, cont;
138
139 for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
140 {
141 if ((cp = rindex (line, '\n')) != NULL)
142 *cp = '\0'; /* strip the newline */
143
144 /*
145 * Add the line to the value, at the end if this is a continuation
146 * line; otherwise at the beginning, but only after any trailing
147 * backslash is removed.
148 */
149 vp = value;
150 if (cont)
151 vp += strlen (value);
152
153 /*
154 * See if the line we read is a continuation line, and strip the
155 * backslash if so.
156 */
157 len = strlen (line);
158 if (len > 0)
159 cp = &line[len - 1];
160 else
161 cp = line;
162 if (*cp == '\\')
163 {
164 cont = 1;
165 *cp = '\0';
166 }
167 else
168 {
169 cont = 0;
170 }
171 (void) strcpy (vp, line);
172 if (value[0] == '#')
173 continue; /* comment line */
174 vp = value;
175 while (*vp && isspace (*vp))
176 vp++;
177 if (*vp == '\0')
178 continue; /* empty line */
179
180 /*
181 * If this was not a continuation line, add the entry to the database
182 */
183 if (!cont)
184 {
185 Node *p = getnode ();
186 char *kp;
187
188 kp = vp;
189 while (*vp && !isspace (*vp))
190 vp++;
191 *vp++ = '\0'; /* NULL terminate the key */
192 p->type = NDBMNODE;
193 p->key = xstrdup (kp);
194 while (*vp && isspace (*vp))
195 vp++; /* skip whitespace to value */
196 if (*vp == '\0')
197 {
198 error (0, 0, "warning: NULL value for key `%s'", p->key);
199 freenode (p);
200 continue;
201 }
202 p->data = xstrdup (vp);
203 if (addnode (list, p) == -1)
204 {
205 error (0, 0, "duplicate key found for `%s'", p->key);
206 freenode (p);
207 }
208 }
209 }
210}
211
212#endif /* MY_NDBM */