1 /***************************************************************************
2 SCED - Schematic Capture Editor
3 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
4 Copyright 1990 Regents of the University of California. All rights reserved.
5 Authors: 1981 Giles C. Billingsley (parts of KIC layout editor)
6 1992 Stephen R. Whiteley
7 ****************************************************************************/
8
9 #include "spice.h"
10 #include "sced.h"
11 #include "scedmacs.h"
12 #include <time.h>
13
14 #include <sys/types.h>
15 #ifdef HAVE_DIRENT_H
16 #include <dirent.h>
17 #ifndef direct
18 #define direct dirent
19 #endif
20 #else
21 #ifdef HAVE_SYS_DIR_H
22 #include <sys/dir.h>
23 #endif
24 #endif
25
26
27 /***********************************************************************
28 *
29 * Dir command.
30 * Show a directory listing of symbol files.
31 *
32 ***********************************************************************/
33
34
35 char *
CopyString(s)36 CopyString(s)
37
38 char *s;
39 {
40 char *t;
41
42 if (s) {
43 t = tmalloc(strlen(s)+1);
44 if (t == NULL) MallocFailed();
45 strcpy(t,s);
46 return (t);
47 }
48 return (s);
49 }
50
51 extern char *MenuDIR;
52
53 struct list {
54 char *l_word;
55 struct list *l_next;
56 };
57
58 #ifdef __STDC__
59 static void format_lines(struct list*);
60 static void display_lines(struct list*);
61 static void list_free(struct list*);
62 static void list_sort(struct list*);
63 static int lcomp(char**,char**);
64 static struct list *symfiles(char*);
65 #else
66 static void format_lines();
67 static void display_lines();
68 static void list_free();
69 static void list_sort();
70 static int lcomp();
71 static struct list *symfiles();
72 #endif
73
74
75 void
Dir()76 Dir()
77
78 {
79 char *path;
80 char *c,*s;
81 struct list *wl,*wx,*wx0 = NULL;
82 char buf[BSIZE_SP];
83
84
85 MenuSelect(MenuDIR);
86 path = PGetPath();
87
88 for (s = path;;) {
89
90 while (isspace(*s)) s++;
91 if (*s == '\0')
92 break;
93
94 c = buf;
95 while (!isspace(*s) && *s != '\0')
96 *c++ = *s++;
97 *c = '\0';
98 /* buf contains the directory path */
99
100 wl = symfiles(buf);
101
102 list_sort(wl);
103 format_lines(wl);
104 if (wx0 == NULL)
105 wx = wx0 = alloc(list);
106 else {
107 wx->l_next = alloc(list);
108 wx = wx->l_next;
109 }
110 if (wx == NULL) MallocFailed();
111 strcat(buf," :");
112 if (!wl)
113 strcat(buf, "\n no symbol files found\n ");
114 wx->l_word = CopyString(buf);
115 wx->l_next = wl;
116 while (wx->l_next) wx = wx->l_next;
117 }
118 display_lines(wx0);
119 list_free(wx0);
120 if (!dispdev->windows)
121 RedisplaySCED(currentgraph);
122 MenuDeselect(MenuDIR);
123 }
124
125
126 static void
format_lines(li)127 format_lines(li)
128
129 /* combine the words into columns */
130 struct list *li;
131 {
132 struct list *wl;
133 int width, colw, nfiles = 0;
134 int i, j, k, fpc;
135 char *buf, *b, **ptr;
136
137 if (li == NULL) return;
138 if (!dispdev->windows) {
139 width = View->kvLargeCoarseViewport->kaWidth - 8;
140 width /= gi_fntwidth;
141 }
142 else
143 width = 70;
144 buf = tmalloc(width+1);
145
146 colw = 0;
147 for (wl = li; wl; wl = wl->l_next) {
148 i = strlen(wl->l_word);
149 if (i > colw) colw = i;
150 nfiles++;
151 }
152 colw += 2;
153 width /= colw; /* width = number of columns */
154 fpc = nfiles/width + 1; /* fpc = max number files/column */
155 ptr = (char**)tmalloc(nfiles*sizeof(char*));
156 for (i = 0, wl = li; wl; i++, wl = wl->l_next) {
157 *(ptr+i) = wl->l_word;
158 }
159
160 wl = li;
161 for (i = 0; i < fpc; i++) {
162 b = buf;
163 for (j = 0; j < width; j++) {
164 k = j*fpc + i;
165 if (k >= nfiles)
166 break;
167 sprintf(b,"%-*s", colw, *(ptr+k));
168 b = buf + strlen(buf);
169 }
170 free(wl->l_word);
171 wl->l_word = CopyString(buf);
172 if (!wl->l_next) {
173 wl->l_next = alloc(list);
174 if (!wl->l_next)
175 MallocFailed();
176 wl->l_next->l_next = NULL;
177 }
178 wl = wl->l_next;
179 }
180 wl->l_word = CopyString(" ");
181 if (wl->l_next)
182 list_free(wl->l_next);
183 wl->l_next = NULL;
184
185 free((char*)ptr);
186 free(buf);
187 }
188
189
190 static void
display_lines(wl)191 display_lines(wl)
192
193 /* print the list, using MORE mode */
194 struct list *wl;
195 {
196 (void)EnableMore(True);
197 for (; wl; wl = wl->l_next)
198 if (MoreLine(wl->l_word)) break;
199
200 (void)EnableMore(False);
201 if (!dispdev->windows) {
202 ShowPrompt("Hit any key to continue.");
203 (void)FBGetchar(ERASE);
204 ErasePrompt();
205 }
206 }
207
208
209 static void
list_free(wl)210 list_free(wl)
211
212 struct list *wl;
213 {
214 struct list *nw;
215
216 for (; wl; wl = nw) {
217 nw = wl->l_next;
218 free(wl->l_word);
219 tfree(wl);
220 }
221 return;
222 }
223
224
225 static void
list_sort(wl)226 list_sort(wl)
227
228 /* alphabetically sort the list */
229 struct list *wl;
230 {
231 int i = 0;
232 struct list *ww;
233 char **stuff;
234
235 for (i = 0, ww = wl; ww; i++, ww = ww->l_next) ;
236 if (i < 2)
237 return;
238 stuff = (char **) tmalloc(i * sizeof (char *));
239 if (stuff == NULL) MallocFailed();
240 for (i = 0, ww = wl; ww; i++, ww = ww->l_next)
241 stuff[i] = ww->l_word;
242 qsort((char *) stuff, i, sizeof (char *),
243 #if __STDC__
244 (int(*)(const void*,const void*))lcomp);
245 #else
246 lcomp);
247 #endif
248 for (i = 0, ww = wl; ww; i++, ww = ww->l_next)
249 ww->l_word = stuff[i];
250 free(stuff);
251 return;
252 }
253
254
255 static int
lcomp(s,t)256 lcomp(s, t)
257
258 char **s, **t;
259 {
260 return (strcmp(*s,*t));
261 }
262
263
264 static struct list *
symfiles(dir)265 symfiles(dir)
266
267 char *dir;
268 {
269 DIR *wdir;
270 struct direct *de;
271 struct list *wl, *wl0 = NULL;
272 char buf[BSIZE_SP];
273 FILE *fp;
274 int i;
275
276 if (!(wdir = opendir(dir)))
277 return (NULL);
278
279 while ((de = readdir(wdir)) != NULL) {
280
281 sprintf(buf,"%s%c%s",dir,DIR_TERM,de->d_name);
282 fp = fopen(buf,"r");
283 if (fp == NULL)
284 continue;
285
286 /* is it a symbol file? */
287
288 for (i = 0; i <7; i++)
289 buf[i] = getc(fp);
290 buf[i] = '\0';
291 fclose(fp);
292
293 if (strcmp(buf,"(Symbol"))
294 continue;
295
296 if (wl0 == NULL) {
297 wl = wl0 = alloc(list);
298 }
299 else {
300 wl->l_next = alloc(list);
301 wl = wl->l_next;
302 }
303 wl->l_word = CopyString(de->d_name);
304 wl->l_next = NULL;
305 }
306 closedir(wdir);
307 return (wl0);
308 }
309