Use side-by-side boards to display background game
[xboard.git] / filebrowser / dir.c
1 /*
2  * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
3  *
4  * Permission to use, copy, modify, and distribute this software and its
5  * documentation for any purpose and without fee is hereby granted, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Software Research Associates not be used
9  * in advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  Software Research Associates
11  * makes no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
16  * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
17  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
18  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
19  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Author: Erik M. van der Poel
23  *         Software Research Associates, Inc., Tokyo, Japan
24  *         erik@sra.co.jp
25  */
26
27 #include <stdio.h>
28
29 #ifdef SEL_FILE_IGNORE_CASE
30 #include <ctype.h>
31 #endif /* def SEL_FILE_IGNORE_CASE */
32
33 #include "selfile.h"
34
35 #if defined(SVR4) || defined(SYSV) || defined(USG) || defined(__osf__)
36 #include <dirent.h>
37 #else /* defined(SVR4) || defined(SYSV) || defined(USG) */
38 #include <sys/dir.h>
39 #define dirent direct
40 #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
41
42 #include <sys/stat.h>
43
44 #if defined(SVR4) || defined(SYSV) || defined(USG)
45 extern void qsort();
46 #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
47
48 #ifdef SEL_FILE_IGNORE_CASE
49 int
50 SFcompareEntries(p, q)
51         SFEntry *p;
52         SFEntry *q;
53 {
54         register char   *r, *s;
55         register char   c1, c2;
56
57         r = p->real;
58         s = q->real;
59
60         c1 = *r++;
61         if (islower(c1)) {
62                 c1 = toupper(c1);
63         }
64         c2 = *s++;
65         if (islower(c2)) {
66                 c2 = toupper(c2);
67         }
68
69         while (c1 == c2) {
70                 if (!c1) {
71                         return strcmp(p->real, q->real);
72                 }
73                 c1 = *r++;
74                 if (islower(c1)) {
75                         c1 = toupper(c1);
76                 }
77                 c2 = *s++;
78                 if (islower(c2)) {
79                         c2 = toupper(c2);
80                 }
81         }
82
83         return c1 - c2;
84 }
85 #else /* def SEL_FILE_IGNORE_CASE */
86 int
87 SFcompareEntries(p, q)
88         SFEntry *p;
89         SFEntry *q;
90 {
91         return strcmp(p->real, q->real);
92 }
93 #endif /* def SEL_FILE_IGNORE_CASE */
94
95 int
96 SFgetDir(dir)
97         SFDir   *dir;
98 {
99         SFEntry         *result = NULL;
100         int             alloc = 0;
101         int             i;
102         DIR             *dirp;
103         struct dirent   *dp;
104         char            *str;
105         int             len;
106         int             maxChars;
107         struct stat     statBuf;
108
109         maxChars = strlen(dir->dir) - 1;
110
111         dir->entries = NULL;
112         dir->nEntries = 0;
113         dir->nChars = 0;
114
115         result = NULL;
116         i = 0;
117
118         dirp = opendir(".");
119         if (!dirp) {
120                 return 1;
121         }
122
123         (void) stat(".", &statBuf);
124         dir->mtime = statBuf.st_mtime;
125
126         (void) readdir(dirp);   /* throw away "." */
127
128 #ifndef S_IFLNK
129         (void) readdir(dirp);   /* throw away ".." */
130 #endif /* ndef S_IFLNK */
131
132         while (dp = readdir(dirp)) {
133                 if (i >= alloc) {
134                         alloc = 2 * (alloc + 1);
135                         result = (SFEntry *) XtRealloc((char *) result,
136                                 (unsigned) (alloc * sizeof(SFEntry)));
137                 }
138                 result[i].statDone = 0;
139                 str = dp->d_name;
140                 len = strlen(str);
141                 result[i].real = XtMalloc((unsigned) (len + 2));
142                 (void) strcat(strcpy(result[i].real, str), " ");
143                 if (len > maxChars) {
144                         maxChars = len;
145                 }
146                 result[i].shown = result[i].real;
147                 i++;
148         }
149
150 #if defined(SVR4) || defined(SYSV) || defined(USG)
151         qsort((char *) result, (unsigned) i, sizeof(SFEntry), SFcompareEntries);
152 #else /* defined(SVR4) || defined(SYSV) || defined(USG) */
153         qsort((char *) result, i, sizeof(SFEntry), SFcompareEntries);
154 #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
155
156         dir->entries = result;
157         dir->nEntries = i;
158         dir->nChars = maxChars + 1;
159
160         closedir(dirp);
161
162         return 0;
163 }