2 * gEDA - GNU Electronic Design Automation
3 * This file is a part of gerbv.
5 * Copyright (C) 2000-2002 Stefan Petersen (spe@stacken.kth.se)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
25 \brief File parsing support functions
37 #include <sys/types.h>
42 #ifdef HAVE_SYS_MMAN_H
48 #include "unzip/unzip.h"
50 #include "gerb_file.h"
52 #define GERB_FILE_ZFILENAME_LEN_MAX 255
54 /* DEBUG printing. #define DEBUG 1 in config.h to use this fcn. */
55 #define dprintf if(DEBUG) printf
58 gerb_fopen(char const * filename
)
63 dprintf("---> Entering gerb_fopen, filename = %s\n", filename
);
64 #ifdef HAVE_SYS_MMAN_H
65 fd
= (gerb_file_t
*)g_malloc(sizeof(gerb_file_t
));
70 dprintf(" Doing fopen\n");
71 fd
->fd
= fopen(filename
, "r");
77 dprintf(" Doing fstat\n");
79 fd
->fileno
= fileno(fd
->fd
);
80 if (fstat(fd
->fileno
, &statinfo
) < 0) {
86 dprintf(" Checking S_ISREG\n");
87 if (!S_ISREG(statinfo
.st_mode
)) {
94 dprintf(" Checking statinfo.st_size\n");
95 if ((int)statinfo
.st_size
== 0) {
98 errno
= EIO
; /* More compatible with the world outside Linux */
102 dprintf(" Doing mmap\n");
103 fd
->datalen
= (int)statinfo
.st_size
;
104 fd
->data
= (char *)mmap(0, statinfo
.st_size
, PROT_READ
, MAP_PRIVATE
,
106 if(fd
->data
== MAP_FAILED
) {
112 /* all systems without mmap, not only MINGW32 */
113 fd
= (gerb_file_t
*)g_malloc(sizeof(gerb_file_t
));
118 if (stat(filename
, &statinfo
) < 0) {
124 fd
->fd
= fopen(filename
, "rb");
126 fd
->fileno
= fileno(fd
->fd
);
127 if (fstat(fd
->fileno
, &statinfo
) < 0) {
132 if (!S_ISREG(statinfo
.st_mode
)) {
138 if ((int)statinfo
.st_size
== 0) {
141 errno
= EIO
; /* More compatible with the world outside Linux */
144 fd
->datalen
= (int)statinfo
.st_size
;
145 fd
->data
= calloc(1, statinfo
.st_size
+ 1);
146 if (fd
->data
== NULL
) {
151 if (fread((void*)fd
->data
, 1, statinfo
.st_size
, fd
->fd
) != statinfo
.st_size
) {
160 dprintf("<--- Leaving gerb_fopen\n");
166 gerb_fgetc(gerb_file_t
*fd
)
169 if (fd
->ptr
>= fd
->datalen
)
172 return (int) fd
->data
[fd
->ptr
++];
177 gerb_fgetint(gerb_file_t
*fd
, int *len
)
183 result
= strtol(fd
->data
+ fd
->ptr
, &end
, 10);
185 GERB_COMPILE_ERROR("Failed to read integer");
190 *len
= end
- (fd
->data
+ fd
->ptr
);
193 fd
->ptr
= end
- fd
->data
;
195 if (len
&& (result
< 0))
203 gerb_fgetdouble(gerb_file_t
*fd
)
209 result
= strtod(fd
->data
+ fd
->ptr
, &end
);
211 GERB_COMPILE_ERROR("Failed to read double");
215 fd
->ptr
= end
- fd
->data
;
218 } /* gerb_fgetdouble */
222 gerb_fgetstring(gerb_file_t
*fd
, char term
)
229 iend
= fd
->data
+ fd
->datalen
;
230 for (i
= fd
->data
+ fd
->ptr
; i
< iend
; i
++) {
240 len
= strend
- (fd
->data
+ fd
->ptr
);
242 newstr
= (char *)g_malloc(len
+ 1);
245 strncpy(newstr
, fd
->data
+ fd
->ptr
, len
);
250 } /* gerb_fgetstring */
254 gerb_ungetc(gerb_file_t
*fd
)
264 gerb_fclose(gerb_file_t
*fd
)
267 #ifdef HAVE_SYS_MMAN_H
268 if (munmap(fd
->data
, fd
->datalen
) < 0)
269 GERB_FATAL_ERROR("munmap:%s", strerror(errno
));
273 if (fclose(fd
->fd
) == EOF
)
274 GERB_FATAL_ERROR("fclose:%s", strerror(errno
));
283 gerb_find_file(char const * filename
, char **paths
)
285 char *curr_path
= NULL
;
286 char *complete_path
= NULL
;
291 for (i
= 0; paths
[i
] != NULL
; i
++) {
292 printf("%s(): paths[%d] = \"%s\"\n", __FUNCTION__
, i
, paths
[i
]);
297 for (i
= 0; paths
[i
] != NULL
; i
++) {
298 dprintf("%s(): Try paths[%d] = \"%s\"\n", __FUNCTION__
, i
, paths
[i
]);
301 * Environment variables start with a $ sign
303 if (paths
[i
][0] == '$') {
304 char *env_name
, *env_value
, *tmp
;
307 /* Extract environment name. Remember we start with a $ */
309 tmp
= strchr(paths
[i
], G_DIR_SEPARATOR
);
311 len
= strlen(paths
[i
]) - 1;
313 len
= tmp
- paths
[i
] - 1;
314 env_name
= (char *)g_malloc(len
+ 1);
315 if (env_name
== NULL
)
317 strncpy(env_name
, (char *)(paths
[i
] + 1), len
);
318 env_name
[len
] = '\0';
320 env_value
= getenv(env_name
);
321 dprintf("%s(): Trying \"%s\" = \"%s\" from the environment\n",
322 __FUNCTION__
, env_name
,
323 env_value
== NULL
? "(null)" : env_value
);
325 if (env_value
== NULL
) {
328 curr_path
= (char *)g_malloc(strlen(env_value
) + strlen(&paths
[i
][len
+ 1]) + 1);
329 if (curr_path
== NULL
)
331 strcpy(curr_path
, env_value
);
332 strcat(curr_path
, &paths
[i
][len
+ 1]);
336 curr_path
= paths
[i
];
339 if (curr_path
!= NULL
) {
341 * Build complete path (inc. filename) and check if file exists.
343 complete_path
= (char *)g_malloc(strlen(curr_path
) + strlen(filename
) + 2);
344 if (complete_path
== NULL
)
346 strcpy(complete_path
, curr_path
);
347 complete_path
[strlen(curr_path
)] = G_DIR_SEPARATOR
;
348 complete_path
[strlen(curr_path
) + 1] = '\0';
349 strncat(complete_path
, filename
, strlen(filename
));
351 if (paths
[i
][0] == '$') {
356 dprintf("%s(): Tring to access \"%s\"\n", __FUNCTION__
,
359 if (access(complete_path
, R_OK
) != -1)
362 g_free(complete_path
);
363 complete_path
= NULL
;
367 if (complete_path
== NULL
)
370 dprintf("%s(): returning complete_path = \"%s\"\n", __FUNCTION__
,
371 complete_path
== NULL
? "(null)" : complete_path
);
373 return complete_path
;
374 } /* gerb_find_file */
380 * Extract the file names in a zip archive and return them in a GSList.
383 gerb_filenames_in_zip(char *zipname
, GSList
**filenames
)
391 /* Now try to open the zip file given and determine which files are in it*/
392 zfd
= unzOpen(zipname
);
394 GERB_FATAL_ERROR("unzOpen failed on %s\n", zipname
);
398 if (unzGoToFirstFile(zfd
) != UNZ_OK
) {
399 GERB_FATAL_ERROR("Failed to go to first file in %s\n", zipname
);
404 /* Insert all filenames in zip to a GSList */
405 zfilename
= g_malloc(GERB_FILE_ZFILENAME_LEN_MAX
);
407 memset(zfilename
, 0, GERB_FILE_ZFILENAME_LEN_MAX
);
408 unzGetCurrentFileInfo(zfd
,
416 fn
= g_slist_append(fn
, (gpointer
)g_strdup(zfilename
));
418 dprintf("%s(): Found file \"%s\" in the zip file\n",
419 __FUNCTION__
, zfilename
);
421 status
= unzGoToNextFile(zfd
);
422 if (status
== UNZ_END_OF_LIST_OF_FILE
) {
425 if (status
!= UNZ_OK
) {
426 GERB_FATAL_ERROR("Failed to go to next file.\n");
439 } /* gerb_filenames_in_zip */