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