comparison interps/c-intercal/src/uncommon.c @ 996:859f9b4339e6

<Gregor> tar xf egobot.tar.xz
author HackBot
date Sun, 09 Dec 2012 19:30:08 +0000
parents
children
comparison
equal deleted inserted replaced
995:6883f5911eb7 996:859f9b4339e6
1 /*
2 * uncommon.c -- functions used by ick, convickt, yuk and compiled programs
3 *
4 LICENSE TERMS
5 Copyright (C) 2007 Alex Smith
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <ick_lose.h>
26 #include "uncommon.h"
27
28 /* Options that might affect this */
29 int ick_printfopens=0;
30
31 /*@dependent@*/ /*@null@*/ FILE* ick_debfopen(/*@observer@*/ const char* fname,
32 /*@observer@*/ const char* mode)
33 {
34 FILE* t;
35 if(ick_printfopens) fprintf(stderr,"Trying to open '%s'...\n",fname);
36 t=fopen(fname,mode);
37 if(ick_printfopens && t != NULL) fprintf(stderr,"Success!\n");
38 if(ick_printfopens && t == NULL) fprintf(stderr,"Failed!\n");
39 return t;
40 }
41
42 /* This function looks for the skeleton and syslib, searching first the
43 path they should be in, then the current directory, then argv[0]'s
44 directory (if one was given). This function avoids possible buffer
45 overflows, instead truncating filenames (and if that manages to find them,
46 I'll be incredibly surprised). It also tries argv[0]/../lib and
47 argv[0]/../include (where they are when running without installing). */
48 /*@dependent@*/ /*@null@*/ FILE* ick_findandfopen(/*@observer@*/ const char* file,
49 /*@observer@*/ const char* guessdir,
50 /*@observer@*/ const char* mode,
51 /*@observer@*/ const char* argv0)
52 {
53 static char buf2[BUFSIZ];
54 /*@observer@*/ static const char *fileiter;
55 size_t i = 0, j;
56 FILE* ret;
57 while(*guessdir != '\0' && i<BUFSIZ-2) buf2[i++] = *guessdir++;
58 buf2[i++] = '/';
59 fileiter = file;
60 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
61 buf2[i] = '\0';
62 ret = ick_debfopen(buf2,mode); /* where it ought to be */
63 if(ret) return ret;
64 ret = ick_debfopen(file,mode); /* current dir */
65 if(ret) return ret;
66 if(!strchr(argv0,'/')&&
67 !strchr(argv0,'\\')) return NULL; /* argv[0] has no dir specified */
68 i = j = 0;
69 while(*argv0 != '\0' && i<BUFSIZ-2)
70 {
71 buf2[i++] = *argv0++;
72 if(*argv0=='/') j = i;
73 if(*argv0=='\\') j = i;
74 }
75 i = j + 1;
76 fileiter=file;
77 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
78 buf2[i] = '\0';
79 ret = ick_debfopen(buf2,mode); /* argv[0]'s dir */
80 if(ret) return ret;
81 i = j + 1;
82 fileiter="../lib/"; /* correct for POSIX and DJGPP */
83 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
84 fileiter=file;
85 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
86 buf2[i]='\0';
87 ret = ick_debfopen(buf2,mode); /* argv[0]/../lib/ */
88 if(ret) return ret;
89 i = j + 1;
90 fileiter="../include/"; /* correct for POSIX and DJGPP */
91 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
92 fileiter=file;
93 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
94 buf2[i]='\0';
95 ret = ick_debfopen(buf2,mode); /* argv[0]/../include/ */
96 if(ret) return ret;
97 return NULL; /* just return 0 if even this failed */
98 }
99
100 /* AIS: The same, looking for an executable */
101 /*@observer@*/ /*@null@*/ const char* ick_findandtestopen(/*@observer@*/ const char* file,
102 /*@observer@*/ const char* guessdir,
103 /*@observer@*/ const char* mode,
104 /*@observer@*/ const char* argv0)
105 {
106 static char buf2[BUFSIZ];
107 /*@observer@*/ static const char *fileiter;
108 size_t i = 0, j;
109 FILE* ret;
110 while(*guessdir != '\0' && i<BUFSIZ-2) buf2[i++] = *guessdir++;
111 buf2[i++] = '/';
112 fileiter = file;
113 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
114 buf2[i] = '\0';
115 ret = ick_debfopen(buf2,mode); /* where it ought to be */
116 if(ret) {(void) fclose(ret); return buf2;}
117 ret = ick_debfopen(file,mode); /* current dir */
118 if(ret) {(void) fclose(ret); return file;}
119 if(!strchr(argv0,'/')&&
120 !strchr(argv0,'\\')) return 0; /* argv[0] has no dir specified */
121 i = j = 0;
122 while(*argv0 != '\0' && i<BUFSIZ-2)
123 {
124 buf2[i++] = *argv0++;
125 if(*argv0=='/') j = i;
126 if(*argv0=='\\') j = i;
127 }
128 i = j + 1;
129 fileiter=file;
130 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
131 buf2[i] = '\0';
132 ret = ick_debfopen(buf2,mode); /* argv[0]'s dir */
133 if(ret) {(void) fclose(ret); return buf2;}
134 i = j + 1;
135 fileiter="../lib/"; /* correct for POSIX and DJGPP */
136 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
137 fileiter=file;
138 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
139 buf2[i]='\0';
140 ret = ick_debfopen(buf2,mode); /* argv[0]/../lib/ */
141 if(ret) {(void) fclose(ret); return buf2;}
142 i = j + 1;
143 fileiter="../include/"; /* correct for POSIX and DJGPP */
144 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
145 fileiter=file;
146 while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
147 buf2[i]='\0';
148 ret = ick_debfopen(buf2,mode); /* argv[0]/../include/ */
149 if(ret) {(void) fclose(ret); return buf2;}
150 return 0; /* just return 0 if even this failed */
151 }
152
153 /* AIS: The same thing, but with freopen */
154 /*@dependent@*/ /*@null@*/ FILE* ick_findandfreopen(/*@observer@*/ const char* file,
155 /*@observer@*/ const char* guessdir,
156 /*@observer@*/ const char* mode,
157 /*@observer@*/ const char* argv0,
158 FILE* over)
159 {
160 const char* s=ick_findandtestopen(file,guessdir,mode,argv0);
161 if(s != NULL)
162 return freopen(s,mode,over);
163 else
164 return NULL;
165 }
166
167 /**
168 * Invoke snprintf(), if supported. Otherwise invoke sprintf() and abort
169 * if we did overflow.
170 */
171 int ick_snprintf_or_die(/*@out@*/ char *str, size_t size, /*@observer@*/ const char *format, ...)
172 {
173 va_list ap;
174 int retval;
175 va_start(ap, format);
176 #ifdef HAVE_VSNPRINTF
177 retval = vsnprintf(str, size, format, ap);
178 #else
179 retval = vsprintf(str, format, ap);
180 if (retval >= size)
181 ick_lose(IE553, 0, (const char*)NULL);
182 #endif
183 va_end(ap);
184 return retval;
185 }