Mercurial > repo
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 } |