New upstream version 1.0.1
Bdale Garbee
4 years ago
0 | libmawk author is Tibor 'Igor2' Palinkas | |
1 | contact: http://igor2.repo.hu/contact.html | |
2 | ||
3 | Original mawk, from which libmawk forked: | |
4 | Mike Brennan, brennan@whidbey.com. |
0 | 0 | Changelog for libmawk |
1 | 1 | ~~~~~~~~~~~~~~~~~~~~~ |
2 | libmawk 1.0.1 (released: 2019-02-26, r1307) | |
3 | [build] -Fix: don't daisy-chain so symlinks (debian patch applied) | |
4 | [build] -Add: install (3) and (7) manual pages | |
5 | [build] -Add: scconfig --libarchdir, for /usr/lib64 | |
6 | [build] -Add: install awklib in non-arch-dependent lib dir | |
7 | [doc] -Add: AUTHORS file | |
8 | [doc] -Update: COPYING: fsf address and formatting | |
9 | [libmawk] -Add: handle --help and --version | |
10 | [da_bin] -Fix: don't depend on sizeof(long) == 4 | |
11 | [math] -Fix: if the result of non-NaN arithmetics is nan in emulated nan, rather make it DBL_MAX so it doesn't look like NaN | |
12 | [math] -Fix: protect all basic math functions from nan input in emulated nan setup | |
13 | [math] -Fix: for systems with unsafe NaN: manual atan2 arg validation | |
14 | [math] -Fix: print and printf treats nan specially to make sure "nan" is printed on all platforms (including emulated NaN) | |
15 | [math] -Fix: emulated nan strtonum: set endptr propery on nan | |
16 | [math] -Fix: when there's no safe nan support, manual convert "nan" to nan on str->num conversion | |
17 | -Cleanup: replace #warning with portable macro | |
18 | ||
2 | 19 | libmawk 1.0.0 (released: 2018-11-11, r1276) |
3 | 20 | [API] -Change: resume capable function call entries |
4 | 21 | [build] -Fix: make clean should remove custom C test objects and executables |
22 | 22 | will use symlinks instead of actual copying of files which is useful if |
23 | 23 | you develop libmawk, the library itself. |
24 | 24 | |
25 | Debian package can be installed from http://repo.hu/debian. | |
26 | ||
27 | 25 | 4. Compatibility with mawk |
28 | 26 | |
29 | 27 | Compatibility with mawk is maintained to some degree. Currently libmawk |
0 | Release notes for libmawk 1.0.0 | |
0 | Release notes for libmawk 1.0.1 | |
1 | 1 | |
2 | This release introduces runlimits, better floating point handling on | |
3 | corner cases (i.e. NaN) and memory leak cleanups. | |
2 | Minor bugfix release; main focus is on fixing all packaging | |
3 | related bugs learned in 1.0.0 and NaN related bugs on less common | |
4 | architectures. | |
4 | 5 |
6 | 6 | |
7 | 7 | #define VER1 "1" |
8 | 8 | #define VER2 "0" |
9 | #define VER3 "0" | |
9 | #define VER3 "1" | |
10 | 10 | |
11 | 11 | static void help(void) |
12 | 12 | { |
20 | 20 | printf(" --profile build profiling version if available (-pg)\n"); |
21 | 21 | printf(" --symbols include symbols (add -g, but no -O0 or extra asserts)\n"); |
22 | 22 | printf(" --numeric=int change the internal numeric type (default is double)\n"); |
23 | printf(" --libarchdir=relpath relative path under prefix for arch-lib-dir (e.g. lib64)\n"); | |
23 | 24 | printf("\n"); |
24 | 25 | } |
25 | 26 | |
41 | 42 | } |
42 | 43 | if (strcmp(key, "profile") == 0) { |
43 | 44 | put("/local/profile", strue); |
45 | return 1; | |
46 | } | |
47 | if (strcmp(key, "libarchdir") == 0) { | |
48 | put("/local/libarchdir", value); | |
44 | 49 | return 1; |
45 | 50 | } |
46 | 51 | if (strcmp(key, "numeric") == 0) { |
77 | 82 | put("/local/debug", sfalse); |
78 | 83 | put("/local/symbols", sfalse); |
79 | 84 | put("/local/profile", sfalse); |
85 | put("/local/libarchdir", "lib"); | |
80 | 86 | |
81 | 87 | report("Configuring libmawk.\n"); |
82 | 88 | logprintf(0, "Configuring libmawk.\n"); |
104 | 110 | put("/local/version/1", VER1); |
105 | 111 | put("/local/version/2", VER2); |
106 | 112 | put("/local/version/3", VER3); |
113 | ||
107 | 114 | |
108 | 115 | /* if there was no custom requirement from the command line, run all requirements in non-fatal mode */ |
109 | 116 | if (num_custom_reqs < 1) { |
136 | 143 | require("cc/fpic", 0, 1); |
137 | 144 | require("cc/soname", 0, 0); |
138 | 145 | require("cc/rdynamic", 0, 0); |
146 | require("cc/pragma_message", 0, 0); | |
139 | 147 | require("fstools/chmodx", 0, 1); |
140 | 148 | require("fstools/cp", 0, 1); |
141 | 149 | require("fstools/rm", 0, 1); |
128 | 128 | int export(const char *fn, int export_empty, const char *root) |
129 | 129 | { |
130 | 130 | FILE *f; |
131 | int ret; | |
131 | int ret = 0; | |
132 | 132 | /* ht_t *table; */ |
133 | 133 | ht_entry_t *h; |
134 | 134 |
51 | 51 | dep_add("cc/declspec/dllimport/*", find_declspec_dllimport); |
52 | 52 | dep_add("cc/declspec/dllexport/*", find_declspec_dllexport); |
53 | 53 | dep_add("cc/argmachine/*", find_cc_argmachine); |
54 | dep_add("cc/pragma_message/*", find_cc_pragma_message); | |
55 | dep_add("cc/static_libgcc/*", find_cc_static_libgcc); | |
56 | ||
54 | 57 | dep_add("libs/ldl", find_lib_ldl); |
55 | 58 | dep_add("libs/LoadLibrary/*", find_lib_LoadLibrary); |
56 | 59 | dep_add("libs/lpthread", find_lib_lpthread); |
70 | 73 | dep_add("libs/proc/_spawnvp/*", find_proc__spawnvp); |
71 | 74 | dep_add("libs/proc/fork/*", find_proc_fork); |
72 | 75 | dep_add("libs/proc/wait/*", find_proc_wait); |
76 | dep_add("libs/proc/_getpid/*", find_proc__getpid); | |
77 | dep_add("libs/proc/CreateProcessA/*",find_proc_CreateProcessA); | |
78 | dep_add("libs/proc/getexecname/*", find_proc_getexecname); | |
79 | dep_add("libs/proc/GetModuleFileNameA/*",find_proc_GetModuleFileNameA); | |
80 | dep_add("libs/proc/shmget/*", find_proc_shmget); | |
81 | dep_add("libs/proc/CreateFileMappingA/*",find_proc_CreateFileMappingA); | |
73 | 82 | dep_add("libs/fs/realpath/*", find_fs_realpath); |
74 | 83 | dep_add("libs/fs/_fullpath/*", find_fs__fullpath); |
75 | 84 | dep_add("libs/fs/readdir/*", find_fs_readdir); |
111 | 120 | dep_add("libs/time/_mkgmtime/*", find_time_mkgmtime); |
112 | 121 | dep_add("libs/time/gmtime_r/*", find_time_gmtime_r); |
113 | 122 | dep_add("libs/time/gmtime_s/*", find_time_gmtime_s); |
123 | dep_add("libs/time/localtime_r/*", find_time_localtime_r); | |
124 | dep_add("libs/time/localtime_s/*", find_time_localtime_s); | |
114 | 125 | dep_add("libs/env/main_3arg/*", find_main_arg3); |
115 | 126 | dep_add("libs/env/putenv/*", find_putenv); |
116 | 127 | dep_add("libs/env/setenv/*", find_setenv); |
160 | 171 | dep_add("sys/types/void_ptr/*", find_types_void_ptr); |
161 | 172 | dep_add("str/strcasecmp/*", find_strcasecmp); |
162 | 173 | dep_add("str/strncasecmp/*", find_strncasecmp); |
174 | dep_add("str/stricmp/*", find_stricmp); | |
175 | dep_add("str/strnicmp/*", find_strnicmp); | |
163 | 176 | |
164 | 177 | dep_add("/internal/filelist/cmd", find_filelist); |
165 | 178 | dep_add("/internal/filelist/method", find_filelist); |
23 | 23 | int find_ldflags_so(const char *name, int logdepth, int fatal); |
24 | 24 | int find_alloca(const char *name, int logdepth, int fatal); |
25 | 25 | int find__exit(const char *name, int logdepth, int fatal); |
26 | int find_cc_pragma_message(const char *name, int logdepth, int fatal); | |
27 | int find_cc_static_libgcc(const char *name, int logdepth, int fatal); | |
26 | 28 | |
27 | 29 | /* libs */ |
28 | 30 | int find_lib_ldl(const char *name, int logdepth, int fatal); |
75 | 77 | int find_proc__spawnvp(const char *name, int logdepth, int fatal); |
76 | 78 | int find_proc_fork(const char *name, int logdepth, int fatal); |
77 | 79 | int find_proc_wait(const char *name, int logdepth, int fatal); |
80 | int find_proc__getpid(const char *name, int logdepth, int fatal); | |
81 | int find_proc_CreateProcessA(const char *name, int logdepth, int fatal); | |
82 | int find_proc_getexecname(const char *name, int logdepth, int fatal); | |
83 | int find_proc_GetModuleFileNameA(const char *name, int logdepth, int fatal); | |
84 | int find_proc_shmget(const char *name, int logdepth, int fatal); | |
85 | int find_proc_CreateFileMappingA(const char *name, int logdepth, int fatal); | |
78 | 86 | |
79 | 87 | /* fstools */ |
80 | 88 | int find_fstools_cp(const char *name, int logdepth, int fatal); |
105 | 113 | /* find_str.c */ |
106 | 114 | int find_strcasecmp(const char *name, int logdepth, int fatal); |
107 | 115 | int find_strncasecmp(const char *name, int logdepth, int fatal); |
116 | int find_stricmp(const char *name, int logdepth, int fatal); | |
117 | int find_strnicmp(const char *name, int logdepth, int fatal); | |
108 | 118 | |
109 | 119 | /* find_sys.c */ |
110 | 120 | int find_sys_ptrwidth(const char *name, int logdepth, int fatal); |
128 | 138 | int find_time_mkgmtime(const char *name, int logdepth, int fatal); |
129 | 139 | int find_time_gmtime_s(const char *name, int logdepth, int fatal); |
130 | 140 | int find_time_gmtime_r(const char *name, int logdepth, int fatal); |
141 | int find_time_localtime_s(const char *name, int logdepth, int fatal); | |
142 | int find_time_localtime_r(const char *name, int logdepth, int fatal); | |
131 | 143 | |
132 | 144 | /* find_types.c */ |
133 | 145 | int find_types_stdint(const char *name, int logdepth, int fatal); |
1034 | 1034 | return 1; |
1035 | 1035 | } |
1036 | 1036 | |
1037 | int find_cc_pragma_message(const char *name, int logdepth, int fatal) | |
1038 | { | |
1039 | const char *test_c = | |
1040 | NL "#include <stdio.h>" | |
1041 | NL "#define DO_PRAGMA(arg) _Pragma(#arg)" | |
1042 | NL "#define TODO(x) DO_PRAGMA(message(\"TODO: \" #x))" | |
1043 | NL "TODO(test)" | |
1044 | NL "int main()" | |
1045 | NL "{" | |
1046 | NL " puts(\"OK\");" | |
1047 | NL "}" | |
1048 | NL; | |
1049 | ||
1050 | require("cc/cc", logdepth, fatal); | |
1051 | ||
1052 | report("Checking for _Pragma(message)... "); | |
1053 | logprintf(logdepth, "find_cc_pragma_message: trying to find pragma_message...\n"); | |
1054 | logdepth++; | |
1055 | if (try(logdepth, NULL, test_c, "OK")) { | |
1056 | put("cc/pragma_message", strue); | |
1057 | report("Found.\n"); | |
1058 | return 0; | |
1059 | } | |
1060 | put("cc/pragma_message", sfalse); | |
1061 | report("Not found.\n"); | |
1062 | return 1; | |
1063 | } | |
1064 | ||
1065 | int find_cc_static_libgcc(const char *name, int logdepth, int fatal) | |
1066 | { | |
1067 | const char *test_c = test_hello_world; | |
1068 | const char *key = "cc/static_libgcc"; | |
1069 | ||
1070 | require("cc/cc", logdepth, fatal); | |
1071 | ||
1072 | report("Checking for -static-libgcc... "); | |
1073 | logprintf(logdepth, "find_cc_static_libgcc: trying to find -static-libgcc...\n"); | |
1074 | logdepth++; | |
1075 | ||
1076 | if (try_icl(logdepth, key, test_c, NULL, NULL, "-static-libgcc")) return 0; | |
1077 | return try_fail(logdepth, key); | |
1078 | } |
104 | 104 | NL " if (found == 1)" |
105 | 105 | NL " puts(\"OK\");" |
106 | 106 | NL " return 0;" |
107 | NL "}"; | |
107 | NL "}" | |
108 | NL; | |
108 | 109 | char *includes[] = { |
109 | 110 | "#include <dirent.h>", |
110 | 111 | "#include <sys/dir.h>", /* 4.2BSD */ |
144 | 145 | NL " if (found > 0)" |
145 | 146 | NL " puts(\"OK\");" |
146 | 147 | NL " return 0;" |
147 | NL "}"; | |
148 | NL "}" | |
149 | NL; | |
148 | 150 | |
149 | 151 | require("cc/cc", logdepth, fatal); |
150 | 152 |
47 | 47 | if (try_icl(logdepth, "libs/proc/_spawnvp", test_c, "#include <process.h>", NULL, NULL)) return 0; |
48 | 48 | |
49 | 49 | return try_fail(logdepth, "libs/proc/_spawnvp"); |
50 | } | |
51 | ||
52 | int find_proc_CreateProcessA(const char *name, int logdepth, int fatal) | |
53 | { | |
54 | const char *key = "libs/proc/CreateProcessA"; | |
55 | char *test_c = | |
56 | NL "#include <stdlib.h>" | |
57 | NL "char buf[2000];" | |
58 | NL "int main() {" | |
59 | NL " const char *cmd;" | |
60 | NL " STARTUPINFOA si;" | |
61 | NL " PROCESS_INFORMATION pi;" | |
62 | NL " cmd = getenv(\"COMSPEC\");" | |
63 | NL " if (cmd == NULL) { /* fallback to guessing */" | |
64 | NL " UINT len = GetWindowsDirectoryA(buf, sizeof(buf));" | |
65 | NL " strcpy(buf+len, \"\\\\system32\\\\cmd.exe\");" | |
66 | NL " cmd = buf;" | |
67 | NL " }" | |
68 | NL " memset(&si, 0, sizeof(si)); si.cb = sizeof(si);" | |
69 | NL " if (!CreateProcessA(cmd, \"/c \\\"echo OK\\\"\"," | |
70 | NL " NULL, NULL, TRUE," | |
71 | NL " 0, NULL, NULL, &si, &pi))" | |
72 | NL " return 1;" | |
73 | NL " if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)" | |
74 | NL " abort();" | |
75 | NL " return 0;" | |
76 | NL "}" | |
77 | NL ; | |
78 | ||
79 | require("cc/cc", logdepth, fatal); | |
80 | ||
81 | report("Checking for CreateProcessA... "); | |
82 | logprintf(logdepth, "find_proc_CreateProcessA: trying to find CreateProcessA...\n"); | |
83 | logdepth++; | |
84 | ||
85 | if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, NULL)) return 0; | |
86 | ||
87 | return try_fail(logdepth, key); | |
50 | 88 | } |
51 | 89 | |
52 | 90 | |
134 | 172 | |
135 | 173 | return try_fail(logdepth, "libs/proc/wait"); |
136 | 174 | } |
175 | ||
176 | int find_proc__getpid(const char *name, int logdepth, int fatal) | |
177 | { | |
178 | const char *key = "libs/proc/_getpid"; | |
179 | const char *test_c = | |
180 | NL "#include <stdio.h>" | |
181 | NL "int main()" | |
182 | NL "{" | |
183 | NL no_implicit(int, "_getpid", "_getpid") | |
184 | NL " if (_getpid() != (-1))" | |
185 | NL " puts(\"OK\");" | |
186 | NL " return 0;" | |
187 | NL "}" | |
188 | NL; | |
189 | ||
190 | require("cc/cc", logdepth, fatal); | |
191 | ||
192 | report("Checking for _getpid()... "); | |
193 | logprintf(logdepth, "find_proc__getpid: trying to find _getpid()...\n"); | |
194 | logdepth++; | |
195 | ||
196 | if (try_icl(logdepth, key, test_c, "#include <process.h>", NULL, NULL)) | |
197 | return 0; | |
198 | ||
199 | return try_fail(logdepth, key); | |
200 | } | |
201 | ||
202 | int find_proc_getexecname(const char *name, int logdepth, int fatal) | |
203 | { | |
204 | const char *key = "libs/proc/getexecname"; | |
205 | const char *test_c = | |
206 | NL "void my_puts(const char *s);" | |
207 | NL "int main()" | |
208 | NL "{" | |
209 | NL no_implicit(const char*, "getexecname", "getexecname") | |
210 | NL " getexecname();" | |
211 | NL " my_puts(\"OK\");" | |
212 | NL " return 0;" | |
213 | NL "}" | |
214 | NL "#include <stdio.h>" | |
215 | NL "void my_puts(const char *s)" | |
216 | NL "{" | |
217 | NL " puts(s);" | |
218 | NL "}" | |
219 | NL; | |
220 | ||
221 | require("cc/cc", logdepth, fatal); | |
222 | ||
223 | report("Checking for getexecname()... "); | |
224 | logprintf(logdepth, "find_proc_getexecname: trying to find getexecname()...\n"); | |
225 | logdepth++; | |
226 | ||
227 | if (try_icl(logdepth, key, test_c, "#include <stdlib.h>", NULL, NULL)) | |
228 | return 0; | |
229 | ||
230 | return try_fail(logdepth, key); | |
231 | } | |
232 | ||
233 | int find_proc_GetModuleFileNameA(const char *name, int logdepth, int fatal) | |
234 | { | |
235 | const char *key = "libs/proc/GetModuleFileNameA"; | |
236 | const char *test_c = | |
237 | NL "void my_puts(const char *s);" | |
238 | NL "char path_buffer[5000];" | |
239 | NL "int main()" | |
240 | NL "{" | |
241 | NL " HMODULE hModule = GetModuleHandleA(NULL);" | |
242 | NL " if (GetModuleFileNameA(hModule, path_buffer, sizeof(path_buffer)) != 0)" | |
243 | NL " my_puts(\"OK\");" | |
244 | NL " return 0;" | |
245 | NL "}" | |
246 | NL "#include <stdio.h>" | |
247 | NL "void my_puts(const char *s)" | |
248 | NL "{" | |
249 | NL " puts(s);" | |
250 | NL "}" | |
251 | NL; | |
252 | ||
253 | require("cc/cc", logdepth, fatal); | |
254 | ||
255 | report("Checking for GetModuleFileNameA()... "); | |
256 | logprintf(logdepth, "find_proc_GetModuleFileNameA: trying to find GetModuleFileNameA()...\n"); | |
257 | logdepth++; | |
258 | ||
259 | if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, NULL)) | |
260 | return 0; | |
261 | if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, "-lkernel32")) | |
262 | return 0; | |
263 | ||
264 | return try_fail(logdepth, key); | |
265 | } | |
266 | ||
267 | int find_proc_shmget(const char *name, int logdepth, int fatal) | |
268 | { | |
269 | const char *key = "libs/proc/shmget"; | |
270 | const char *test_c = | |
271 | NL "void my_puts(const char *s);" | |
272 | NL "int main()" | |
273 | NL "{" | |
274 | NL " int shmid;" | |
275 | NL " char *addr;" | |
276 | NL " shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT|IPC_EXCL|0600);" | |
277 | NL " if (shmid < 0)" | |
278 | NL " return 1;" | |
279 | NL " addr = (char *)shmat(shmid, (void *)0, 0);" | |
280 | NL " if (addr == (char *)0) {" | |
281 | NL " shmctl(shmid, IPC_RMID, (void *)0);" | |
282 | NL " return 1;" | |
283 | NL " }" | |
284 | NL " if (shmctl(shmid, IPC_RMID, (void *)0) != 0)" | |
285 | NL " return 1;" | |
286 | NL " if (addr[2] != 0)" | |
287 | NL " return 1;" | |
288 | NL " addr[0] = 'O'; addr[1] = 'K';" | |
289 | NL " my_puts(addr);" | |
290 | NL " return 0;" | |
291 | NL "}" | |
292 | NL "#include <stdio.h>" | |
293 | NL "void my_puts(const char *s)" | |
294 | NL "{" | |
295 | NL " puts(s);" | |
296 | NL "}" | |
297 | NL; | |
298 | ||
299 | require("cc/cc", logdepth, fatal); | |
300 | ||
301 | report("Checking for shmget()... "); | |
302 | logprintf(logdepth, "find_proc_shmget: trying to find shmget()...\n"); | |
303 | logdepth++; | |
304 | ||
305 | if (try_icl(logdepth, key, test_c, "#include <sys/ipc.h>\n#include <sys/shm.h>", NULL, NULL)) | |
306 | return 0; | |
307 | ||
308 | return try_fail(logdepth, key); | |
309 | } | |
310 | ||
311 | int find_proc_CreateFileMappingA(const char *name, int logdepth, int fatal) | |
312 | { | |
313 | const char *key = "libs/proc/CreateFileMappingA"; | |
314 | const char *test_c = | |
315 | NL "void my_puts(const char *s);" | |
316 | NL "#define MAP_BUF_SIZE 4096" | |
317 | NL "int main()" | |
318 | NL "{" | |
319 | NL " char *addr;" | |
320 | NL " HANDLE hMap = CreateFileMappingA(" | |
321 | NL " INVALID_HANDLE_VALUE," | |
322 | NL " NULL," | |
323 | NL " PAGE_READWRITE," | |
324 | NL " 0," | |
325 | NL " MAP_BUF_SIZE," | |
326 | NL " NULL);" | |
327 | NL " if (hMap == NULL)" | |
328 | NL " return 1;" | |
329 | NL " addr = (char *)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS," | |
330 | NL " 0, 0, MAP_BUF_SIZE);" | |
331 | NL " if (addr == NULL) {" | |
332 | NL " CloseHandle(hMap);" | |
333 | NL " return 1;" | |
334 | NL " }" | |
335 | NL " if (addr[2] != 0) {" | |
336 | NL " UnmapViewOfFile(addr);" | |
337 | NL " CloseHandle(hMap);" | |
338 | NL " return 1;" | |
339 | NL " }" | |
340 | NL " addr[0] = 'O'; addr[1] = 'K';" | |
341 | NL " my_puts(addr);" | |
342 | NL " UnmapViewOfFile(addr);" | |
343 | NL " CloseHandle(hMap);" | |
344 | NL " return 0;" | |
345 | NL "}" | |
346 | NL "#include <stdio.h>" | |
347 | NL "void my_puts(const char *s)" | |
348 | NL "{" | |
349 | NL " puts(s);" | |
350 | NL "}" | |
351 | NL; | |
352 | ||
353 | require("cc/cc", logdepth, fatal); | |
354 | ||
355 | report("Checking for CreateFileMappingA()... "); | |
356 | logprintf(logdepth, "find_proc_CreateFileMappingA: trying to find CreateFileMappingA()...\n"); | |
357 | logdepth++; | |
358 | ||
359 | if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, NULL)) | |
360 | return 0; | |
361 | if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, "-lkernel32")) | |
362 | return 0; | |
363 | ||
364 | return try_fail(logdepth, key); | |
365 | } |
73 | 73 | return try_fail(logdepth, "str/strncasecmp"); |
74 | 74 | } |
75 | 75 | |
76 | ||
77 | int find_stricmp(const char *name, int logdepth, int fatal) | |
78 | { | |
79 | const char *test_c = | |
80 | NL "#include <string.h>" | |
81 | NL "#include <stdio.h>" | |
82 | NL "int main() {" | |
83 | NL " if ((stricmp(\"foo\", \"FoO\") == 0) && (stricmp(\"foo\", \"bar\") != 0))" | |
84 | NL " puts(\"OK\");" | |
85 | NL " return 0;" | |
86 | NL "}" | |
87 | NL; | |
88 | ||
89 | require("cc/cc", logdepth, fatal); | |
90 | ||
91 | report("Checking for stricmp()... "); | |
92 | logprintf(logdepth, "find_fs_stricmp: trying to find stricmp...\n"); | |
93 | logdepth++; | |
94 | ||
95 | if (try_icl(logdepth, "str/stricmp", test_c, NULL, NULL, NULL)) return 0; | |
96 | return try_fail(logdepth, "str/stricmp"); | |
97 | } | |
98 | ||
99 | ||
100 | int find_strnicmp(const char *name, int logdepth, int fatal) | |
101 | { | |
102 | const char *test_c = | |
103 | NL "#include <string.h>" | |
104 | NL "#include <stdio.h>" | |
105 | NL "int main() {" | |
106 | NL " if ((strnicmp(\"foo1\", \"FoO2\", 3) == 0) && (strnicmp(\"foo1\", \"bar2\", 3) != 0))" | |
107 | NL " puts(\"OK\");" | |
108 | NL " return 0;" | |
109 | NL "}" | |
110 | NL; | |
111 | ||
112 | require("cc/cc", logdepth, fatal); | |
113 | ||
114 | report("Checking for strnicmp()... "); | |
115 | logprintf(logdepth, "find_fs_strnicmp: trying to find strnicmp...\n"); | |
116 | logdepth++; | |
117 | ||
118 | if (try_icl(logdepth, "str/strnicmp", test_c, NULL, NULL, NULL)) return 0; | |
119 | return try_fail(logdepth, "str/strnicmp"); | |
120 | } | |
121 |
244 | 244 | return 0; |
245 | 245 | return try_fail(logdepth, "libs/time/gmtime_s"); |
246 | 246 | } |
247 | ||
248 | int find_time_localtime_r(const char *name, int logdepth, int fatal) | |
249 | { | |
250 | const char *key = "libs/time/localtime_r"; | |
251 | const char test_c[] = | |
252 | NL "void my_puts(const char *s);" | |
253 | NL "int main() {" | |
254 | NL " time_t tim = 1543645850;" | |
255 | NL " struct tm tm;" | |
256 | NL " if (localtime_r(&tim, &tm)" /* returns '&tm' */ | |
257 | NL " && 0!=tm.tm_sec" /* depends on TZ: sadly we can't sure in anything */ | |
258 | NL " && 0!=tm.tm_min" | |
259 | NL " && 0!=tm.tm_hour)" | |
260 | NL " my_puts(\"OK\");" | |
261 | NL " return 0;" | |
262 | NL "}" | |
263 | NL "#include <stdio.h>" | |
264 | NL "void my_puts(const char *s)" | |
265 | NL "{" | |
266 | NL " puts(s);" | |
267 | NL "}" | |
268 | NL; | |
269 | ||
270 | require("cc/cc", logdepth, fatal); | |
271 | ||
272 | report("Checking for localtime_r()... "); | |
273 | logprintf(logdepth, "find_time_localtime_r: trying to find localtime_r...\n"); | |
274 | logdepth++; | |
275 | ||
276 | if (try_icl(logdepth, key, test_c, "#include <time.h>", NULL, NULL)) | |
277 | return 0; | |
278 | return try_fail(logdepth, key); | |
279 | } | |
280 | ||
281 | int find_time_localtime_s(const char *name, int logdepth, int fatal) | |
282 | { | |
283 | const char *key = "libs/time/localtime_s"; | |
284 | const char test_c[] = | |
285 | NL "void my_puts(const char *s);" | |
286 | NL "int main() {" | |
287 | NL " time_t tim = 1543645850;" | |
288 | NL " struct tm tm;" | |
289 | NL " if (0==localtime_s(&tm, &tim)" /* returns errno */ | |
290 | NL " && 0!=tm.tm_sec" /* depends on TZ: sadly we can't sure in anything */ | |
291 | NL " && 0!=tm.tm_min" | |
292 | NL " && 0!=tm.tm_hour)" | |
293 | NL " my_puts(\"OK\");" | |
294 | NL " return 0;" | |
295 | NL "}" | |
296 | NL "#include <stdio.h>" | |
297 | NL "void my_puts(const char *s)" | |
298 | NL "{" | |
299 | NL " puts(s);" | |
300 | NL "}" | |
301 | NL; | |
302 | ||
303 | require("cc/cc", logdepth, fatal); | |
304 | ||
305 | report("Checking for localtime_s()... "); | |
306 | logprintf(logdepth, "find_time_localtime_s: trying to find localtime_s...\n"); | |
307 | logdepth++; | |
308 | ||
309 | if (try_icl(logdepth, key, test_c, "#include <time.h>", NULL, NULL)) | |
310 | return 0; | |
311 | return try_fail(logdepth, key); | |
312 | } |
291 | 291 | { |
292 | 292 | char **pkg_ver, **s; |
293 | 293 | int num_pkg_ver; |
294 | int res; | |
294 | int res = 0; | |
295 | 295 | (void) includes; /* not used */ |
296 | 296 | |
297 | 297 | run_pkg_config_lst(logdepth, pkgpat, &num_pkg_ver, &pkg_ver); |
129 | 129 | sum += len[v]; |
130 | 130 | } |
131 | 131 | |
132 | /* first string is NULL; return a new allocation that is a simple \0, empty string to avoid a nasty corner case */ | |
133 | if (sum == 0) | |
134 | return calloc(1, 1); | |
135 | ||
132 | 136 | sl = strlen(sep); |
133 | 137 | sum += (v-1) * sl + 1; /* + a sep between each two strings and a terminator at the end */ |
134 | 138 | o = out = malloc(sum); |
182 | 182 | put(addr, val); |
183 | 183 | free(addr); |
184 | 184 | free(val); |
185 | } | |
186 | ||
187 | static void instr_resolve(tmpasm_t *ctx, char *iname, int argc, tmpasm_arg_t *argv[]) | |
188 | { | |
189 | char *dst, *srca; | |
190 | const char *src; | |
191 | (void) iname; /* not used */ | |
192 | if (argc != 2) { | |
193 | char str[16]; | |
194 | sprintf(str, "%d", argc); | |
195 | tmpasm_runtime_error(ctx, -1, str); | |
196 | return; | |
197 | } | |
198 | ||
199 | dst = tmpasm_arg2str(ctx, argv[0], 1); | |
200 | srca = tmpasm_arg2str(ctx, argv[1], 0); | |
201 | src = scc_get(ctx, srca); | |
202 | if (*dst != '\0') | |
203 | put(dst, src); | |
204 | free(dst); | |
205 | free(srca); | |
185 | 206 | } |
186 | 207 | |
187 | 208 | |
521 | 542 | /* TODO: make this a hash */ |
522 | 543 | if (strcmp(name, "put") == 0) |
523 | 544 | return instr_put; |
545 | if (strcmp(name, "resolve") == 0) | |
546 | return instr_resolve; | |
524 | 547 | if (strcmp(name, "append") == 0) |
525 | 548 | return instr_append; |
526 | 549 | if (strcmp(name, "print") == 0) |
0 | 0 | all: |
1 | 1 | cd libmawk && $(MAKE) |
2 | cd awklib && $(MAKE) | |
2 | 3 | # cd example_apps && $(MAKE) all |
3 | 4 | |
4 | 5 | test: |
6 | 7 | |
7 | 8 | install: |
8 | 9 | cd libmawk && $(MAKE) install |
10 | cd awklib && $(MAKE) install | |
9 | 11 | # cd example_apps && $(MAKE) install |
10 | 12 | |
11 | 13 | uninstall: |
12 | 14 | cd libmawk && $(MAKE) uninstall |
15 | cd awklib && $(MAKE) uninstall | |
13 | 16 | # cd example_apps && $(MAKE) uninstall |
14 | 17 | |
15 | 18 | linstall: |
16 | 19 | cd libmawk && $(MAKE) linstall |
20 | cd awklib && $(MAKE) linstall | |
17 | 21 | # cd example_apps && $(MAKE) linstall |
18 | 22 | |
19 | 23 | clean: |
2 | 2 | |
3 | 3 | print [@ |
4 | 4 | # Generated by scconfig from Makefile.in |
5 | LIBPATH=$(install_root)/usr/lib/libmawk | |
5 | PREFIX=@/local/prefix@ | |
6 | LIBPATH=$(DESTDIR)$(install_root)$(PREFIX)/lib/libmawk | |
6 | 7 | |
7 | 8 | all: |
8 | 9 |
0 | GNU GENERAL PUBLIC LICENSE | |
1 | Version 2, June 1991 | |
2 | ||
3 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |
4 | 675 Mass Ave, Cambridge, MA 02139, USA | |
0 | GNU GENERAL PUBLIC LICENSE | |
1 | Version 2, June 1991 | |
2 | ||
3 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., | |
4 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
5 | 5 | Everyone is permitted to copy and distribute verbatim copies |
6 | 6 | of this license document, but changing it is not allowed. |
7 | 7 | |
8 | Preamble | |
8 | Preamble | |
9 | 9 | |
10 | 10 | The licenses for most software are designed to take away your |
11 | 11 | freedom to share and change it. By contrast, the GNU General Public |
14 | 14 | General Public License applies to most of the Free Software |
15 | 15 | Foundation's software and to any other program whose authors commit to |
16 | 16 | using it. (Some other Free Software Foundation software is covered by |
17 | the GNU Library General Public License instead.) You can apply it to | |
17 | the GNU Lesser General Public License instead.) You can apply it to | |
18 | 18 | your programs, too. |
19 | 19 | |
20 | 20 | When we speak of free software, we are referring to freedom, not |
54 | 54 | |
55 | 55 | The precise terms and conditions for copying, distribution and |
56 | 56 | modification follow. |
57 | ||
58 | GNU GENERAL PUBLIC LICENSE | |
57 | ||
58 | GNU GENERAL PUBLIC LICENSE | |
59 | 59 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
60 | 60 | |
61 | 61 | 0. This License applies to any program or other work which contains |
109 | 109 | License. (Exception: if the Program itself is interactive but |
110 | 110 | does not normally print such an announcement, your work based on |
111 | 111 | the Program is not required to print an announcement.) |
112 | ||
112 | ||
113 | 113 | These requirements apply to the modified work as a whole. If |
114 | 114 | identifiable sections of that work are not derived from the Program, |
115 | 115 | and can be reasonably considered independent and separate works in |
167 | 167 | access to copy the source code from the same place counts as |
168 | 168 | distribution of the source code, even though third parties are not |
169 | 169 | compelled to copy the source along with the object code. |
170 | ||
170 | ||
171 | 171 | 4. You may not copy, modify, sublicense, or distribute the Program |
172 | 172 | except as expressly provided under this License. Any attempt |
173 | 173 | otherwise to copy, modify, sublicense or distribute the Program is |
224 | 224 | |
225 | 225 | This section is intended to make thoroughly clear what is believed to |
226 | 226 | be a consequence of the rest of this License. |
227 | ||
227 | ||
228 | 228 | 8. If the distribution and/or use of the Program is restricted in |
229 | 229 | certain countries either by patents or by copyrighted interfaces, the |
230 | 230 | original copyright holder who places the Program under this License |
254 | 254 | of preserving the free status of all derivatives of our free software and |
255 | 255 | of promoting the sharing and reuse of software generally. |
256 | 256 | |
257 | NO WARRANTY | |
257 | NO WARRANTY | |
258 | 258 | |
259 | 259 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
260 | 260 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
276 | 276 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
277 | 277 | POSSIBILITY OF SUCH DAMAGES. |
278 | 278 | |
279 | END OF TERMS AND CONDITIONS | |
280 | ||
281 | Appendix: How to Apply These Terms to Your New Programs | |
279 | END OF TERMS AND CONDITIONS | |
280 | ||
281 | How to Apply These Terms to Your New Programs | |
282 | 282 | |
283 | 283 | If you develop a new program, and you want it to be of the greatest |
284 | 284 | possible use to the public, the best way to achieve this is to make it |
290 | 290 | the "copyright" line and a pointer to where the full notice is found. |
291 | 291 | |
292 | 292 | <one line to give the program's name and a brief idea of what it does.> |
293 | Copyright (C) 19yy <name of author> | |
293 | Copyright (C) <year> <name of author> | |
294 | 294 | |
295 | 295 | This program is free software; you can redistribute it and/or modify |
296 | 296 | it under the terms of the GNU General Public License as published by |
302 | 302 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
303 | 303 | GNU General Public License for more details. |
304 | 304 | |
305 | You should have received a copy of the GNU General Public License | |
306 | along with this program; if not, write to the Free Software | |
307 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
305 | You should have received a copy of the GNU General Public License along | |
306 | with this program; if not, write to the Free Software Foundation, Inc., | |
307 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
308 | 308 | |
309 | 309 | Also add information on how to contact you by electronic and paper mail. |
310 | 310 | |
311 | 311 | If the program is interactive, make it output a short notice like this |
312 | 312 | when it starts in an interactive mode: |
313 | 313 | |
314 | Gnomovision version 69, Copyright (C) 19yy name of author | |
314 | Gnomovision version 69, Copyright (C) year name of author | |
315 | 315 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
316 | 316 | This is free software, and you are welcome to redistribute it |
317 | 317 | under certain conditions; type `show c' for details. |
334 | 334 | This General Public License does not permit incorporating your program into |
335 | 335 | proprietary programs. If your program is a subroutine library, you may |
336 | 336 | consider it more useful to permit linking proprietary applications with the |
337 | library. If this is what you want to do, use the GNU Library General | |
337 | library. If this is what you want to do, use the GNU Lesser General | |
338 | 338 | Public License instead of this License. |
0 | Look at the file config.user and edit to set user defines. | |
1 | ||
2 | if your system is one of | |
3 | apollo | |
4 | convex | |
5 | mips | |
6 | sgi | |
7 | ultrix-mips | |
8 | cray | |
9 | hpux (read below) | |
10 | unixware (read below) | |
11 | ||
12 | and you don't have gcc or prefer to use cc, then you may want to | |
13 | copy config-user/your_system to config.user and edit that. | |
14 | ||
15 | run | |
16 | ||
17 | configure | |
18 | make | |
19 | ||
20 | ||
21 | If you have problems, please report it. If you can fix the problem, by | |
22 | changing config.user, please send the results. Else send output from | |
23 | configure, make and config.h. Send to brennan@whidbey.com. | |
24 | ||
25 | ||
26 | ||
27 | DOS: | |
28 | Look at the file msdos/INSTALL | |
29 | ||
30 | ||
31 | HPUX: | |
32 | Evidently there is more than one compiler and/or math library. Some | |
33 | configurations work out of the box (configure/make). Others need | |
34 | CFLAGS='+O2 +FPZO'. On HPUX 9.05 with the ansi compiler HP92453-01 | |
35 | A.09.77 set CFLAGS='-Ae +O2 +FPZO'. Thanks to Dr. Rafael R. | |
36 | Pappalardo<rafapa@mozart.us.es> for this info. | |
37 | ||
38 | ||
39 | ||
40 | UNIXWARE: | |
41 | On some but not all versions, configure might decide you don't have | |
42 | memcpy. Remove #define NO_MEMCPY 1 from config.h. | |
43 | If the fpe_test check fails, change the definition of TURN_ON_FPE_TRAPS | |
44 | to | |
45 | ||
46 | #define TURN_ON_FPE_TRAPS() fpsetmask(fpgetmask()|FP_X_DZ|FP_X_OFL|FP_X_INV) |
121 | 121 | install_ : lmawk libmawk.so |
122 | 122 | $(MKDIR) $(BINDIR) |
123 | 123 | $(MKDIR) $(MANDIR) |
124 | $(MKDIR) $(MAN3DIR) | |
125 | $(MKDIR) $(MAN7DIR) | |
124 | 126 | $(MKDIR) $(INCDIR) |
125 | $(MKDIR) $(LIBDIR) | |
127 | $(MKDIR) $(LIBARCHDIR) | |
126 | 128 | $(CP) $(PWD)/lmawk $(BINDIR) |
127 | 129 | $(CHMODX) $(BINDIR)/lmawk |
128 | 130 | $(CP) $(PWD)/man/lmawk.1 $(MAWKMAN) |
131 | $(CP) $(PWD)/man/libmawk_append_input.3libmawk $(MAN3DIR)/libmawk_append_input.3libmawk | |
132 | $(CP) $(PWD)/man/libmawk_call_function.3libmawk $(MAN3DIR)/libmawk_call_function.3libmawk | |
133 | $(CP) $(PWD)/man/libmawk_cell_destroy.3libmawk $(MAN3DIR)/libmawk_cell_destroy.3libmawk | |
134 | $(CP) $(PWD)/man/libmawk_get_var.3libmawk $(MAN3DIR)/libmawk_get_var.3libmawk | |
135 | $(CP) $(PWD)/man/libmawk_initialize.3libmawk $(MAN3DIR)/libmawk_initialize.3libmawk | |
136 | $(CP) $(PWD)/man/libmawk_initialize_stage.3libmawk $(MAN3DIR)/libmawk_initialize_stage.3libmawk | |
137 | $(CP) $(PWD)/man/libmawk_register_function.3libmawk $(MAN3DIR)/libmawk_register_function.3libmawk | |
138 | $(CP) $(PWD)/man/libmawk_run_main.3libmawk $(MAN3DIR)/libmawk_run_main.3libmawk | |
139 | $(CP) $(PWD)/man/libmawk_set_cell.3libmawk $(MAN3DIR)/libmawk_set_cell.3libmawk | |
140 | $(CP) $(PWD)/man/libmawk_uninitialize.3libmawk $(MAN3DIR)/libmawk_uninitialize.3libmawk | |
141 | $(CP) $(PWD)/man/example.7libmawk $(MAN7DIR)/example.7libmawk | |
129 | 142 | $(CHMOD) 0644 $(MAWKMAN) |
130 | $(CP) $(PWD)/libmawk.so $(LIBDIR)/libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) | |
131 | rm $(LIBDIR)/libmawk.so.$(SOVER1).$(SOVER2) $(LIBDIR)/libmawk.so.$(SOVER1) 2>/dev/null ; true | |
132 | ln -s libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) $(LIBDIR)/libmawk.so.$(SOVER1).$(SOVER2) | |
133 | ln -s libmawk.so.$(SOVER1).$(SOVER2) $(LIBDIR)/libmawk.so.$(SOVER1) | |
134 | ln -s libmawk.so.$(SOVER1) $(LIBDIR)/libmawk.so | |
143 | $(CP) $(PWD)/libmawk.so $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) | |
144 | rm $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2) $(LIBARCHDIR)/libmawk.so.$(SOVER1) 2>/dev/null ; true | |
145 | ln -s libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2) | |
146 | ln -s libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) $(LIBARCHDIR)/libmawk.so.$(SOVER1) | |
147 | ln -s libmawk.so.$(SOVER1) $(LIBARCHDIR)/libmawk.so | |
135 | 148 | for h in $(IHEADERS); do $(CP) $(PWD)/$$h $(INCDIR)/$$h; done |
136 | 149 | $(CP) $(PWD)/../libmawk.h $(INCDIR)/../libmawk.h |
137 | 150 |
21 | 21 | # where to put mawk |
22 | 22 | BINDIR = $(DESTDIR)$(install_root)$(PREFIX)/bin |
23 | 23 | # where to put libraries |
24 | LIBARCHDIR = $(DESTDIR)$(install_root)$(PREFIX)/@/local/libarchdir@ | |
24 | 25 | LIBDIR = $(DESTDIR)$(install_root)$(PREFIX)/lib |
25 | 26 | # where to put include files |
26 | 27 | INCDIR = $(DESTDIR)$(install_root)$(PREFIX)/include/libmawk |
27 | 28 | # where to put the man pages |
28 | 29 | MANDIR = $(DESTDIR)$(install_root)$(PREFIX)/share/man/man1 |
30 | MAN3DIR = $(DESTDIR)$(install_root)$(PREFIX)/share/man/man3 | |
31 | MAN7DIR = $(DESTDIR)$(install_root)$(PREFIX)/share/man/man7 | |
29 | 32 | # where to put the doc |
30 | 33 | DOCDIR = $(DESTDIR)$(install_root)$(PREFIX)/share/doc/libmawk |
31 | 34 | MANEXT = 1 |
268 | 268 | } |
269 | 269 | |
270 | 270 | #ifndef MAWK_NO_FLOAT |
271 | ||
272 | #ifndef MAWK_HAVE_SAFE_NAN | |
273 | # define handle_nan_1arg() \ | |
274 | if (P_isnan((sp)->d.dval)) { \ | |
275 | sp->d.dval = P_nan(); \ | |
276 | return sp; \ | |
277 | } | |
278 | #else | |
279 | # define handle_nan_1arg() | |
280 | #endif | |
281 | ||
282 | ||
271 | 283 | mawk_cell_t *mawk_bi_sin(mawk_state_t *MAWK, mawk_cell_t *sp) |
272 | 284 | { |
273 | 285 | #if ! STDC_MATHERR |
274 | 286 | if (sp->type != C_NUM) |
275 | 287 | mawk_cast1_to_num(MAWK, sp); |
288 | handle_nan_1arg(); | |
276 | 289 | sp->d.dval = sin(sp->d.dval); |
277 | 290 | return sp; |
278 | 291 | #else |
281 | 294 | errno = 0; |
282 | 295 | if (sp->type != C_NUM) |
283 | 296 | mawk_cast1_to_num(MAWK, sp); |
297 | ||
298 | handle_nan_1arg(); | |
299 | ||
284 | 300 | x = sp->d.dval; |
285 | 301 | sp->d.dval = sin(sp->d.dval); |
286 | 302 | if (errno) |
294 | 310 | #if ! STDC_MATHERR |
295 | 311 | if (sp->type != C_NUM) |
296 | 312 | mawk_cast1_to_num(MAWK, sp); |
313 | handle_nan_1arg(); | |
297 | 314 | sp->d.dval = cos(sp->d.dval); |
298 | 315 | return sp; |
299 | 316 | #else |
302 | 319 | errno = 0; |
303 | 320 | if (sp->type != C_NUM) |
304 | 321 | mawk_cast1_to_num(MAWK, sp); |
322 | handle_nan_1arg(); | |
305 | 323 | x = sp->d.dval; |
306 | 324 | sp->d.dval = cos(sp->d.dval); |
307 | 325 | if (errno) |
312 | 330 | |
313 | 331 | mawk_cell_t *mawk_bi_atan2(mawk_state_t *MAWK, mawk_cell_t *sp) |
314 | 332 | { |
333 | ||
315 | 334 | #if ! STDC_MATHERR |
316 | 335 | sp--; |
317 | 336 | if (TEST2(sp) != TWO_NUMS) |
318 | 337 | mawk_cast2_to_num(MAWK, sp); |
338 | ||
339 | #ifndef MAWK_HAVE_SAFE_NAN | |
340 | if (P_isnan(sp->d.dval) || P_isnan((sp+1)->d.dval)) { | |
341 | sp->d.dval = P_nan(); | |
342 | return sp; | |
343 | } | |
344 | #endif | |
345 | ||
319 | 346 | sp->d.dval = atan2(sp->d.dval, (sp + 1)->d.dval); |
320 | 347 | return sp; |
321 | 348 | #else |
324 | 351 | sp--; |
325 | 352 | if (TEST2(sp) != TWO_NUMS) |
326 | 353 | mawk_cast2_to_num(MAWK, sp); |
354 | ||
355 | ||
356 | #ifndef MAWK_HAVE_SAFE_NAN | |
357 | if (P_isnan(sp->d.dval) || P_isnan((sp+1)->d.dval)) { | |
358 | sp->d.dval = P_nan(); | |
359 | return sp; | |
360 | } | |
361 | #endif | |
362 | ||
327 | 363 | sp->d.dval = atan2(sp->d.dval, (sp + 1)->d.dval); |
328 | 364 | if (errno) |
329 | 365 | mawk_rt_error(MAWK, "atan2(0,0) : domain error"); |
338 | 374 | errno = 0; |
339 | 375 | if (sp->type != C_NUM) |
340 | 376 | mawk_cast1_to_num(MAWK, sp); |
377 | ||
378 | handle_nan_1arg(); | |
379 | ||
341 | 380 | x = sp->d.dval; |
342 | 381 | PM_BEGIN |
343 | 382 | sp->d.dval = P_log(sp->d.dval); |
351 | 390 | |
352 | 391 | mawk_cell_t *mawk_bi_exp(mawk_state_t *MAWK, mawk_cell_t *sp) |
353 | 392 | { |
393 | ||
354 | 394 | #if ! STDC_MATHERR |
355 | 395 | if (sp->type != C_NUM) |
356 | 396 | mawk_cast1_to_num(MAWK, sp); |
397 | handle_nan_1arg(); | |
357 | 398 | sp->d.dval = exp(sp->d.dval); |
358 | 399 | return sp; |
359 | 400 | #else |
362 | 403 | errno = 0; |
363 | 404 | if (sp->type != C_NUM) |
364 | 405 | mawk_cast1_to_num(MAWK, sp); |
406 | handle_nan_1arg(); | |
365 | 407 | x = sp->d.dval; |
366 | 408 | sp->d.dval = exp(sp->d.dval); |
367 | 409 | if (errno && sp->d.dval) |
376 | 418 | { |
377 | 419 | if (sp->type != C_NUM) |
378 | 420 | mawk_cast1_to_num(MAWK, sp); |
421 | handle_nan_1arg(); | |
379 | 422 | sp->d.dval = mawk_num_int(sp->d.dval); |
380 | 423 | return sp; |
381 | 424 | } |
386 | 429 | |
387 | 430 | if (sp->type != C_NUM) |
388 | 431 | mawk_cast1_to_num(MAWK, sp); |
432 | ||
433 | handle_nan_1arg(); | |
389 | 434 | |
390 | 435 | x = sp->d.dval; |
391 | 436 | |
918 | 963 | else |
919 | 964 | mawk_set_errno(MAWK, "2 object is not a function"); |
920 | 965 | |
921 | #warning this should be some common code in execute.c? | |
966 | TODO("this should be some common code in execute.c?") | |
922 | 967 | for (i = 0; i < numargs; i++) { |
923 | 968 | mawk_cell_destroy(MAWK, &sp[i]); |
924 | 969 | sp[i].type = C_NOINIT; |
1015 | 1060 | |
1016 | 1061 | sp -= numargs; |
1017 | 1062 | sp--; |
1018 | #warning TODO: cell destroy all the allocated but unused args? | |
1063 | TODO(": cell destroy all the allocated but unused args?") | |
1019 | 1064 | return sp; |
1020 | 1065 | |
1021 | 1066 | error:; |
69 | 69 | cons: zmalloc's uninit will throw them out in less cpu cycles. |
70 | 70 | */ |
71 | 71 | /* #define MAWK_MEM_PEDANTIC */ |
72 | @] | |
73 | ||
74 | print {\n/* Code warnings for TODO, portable (unlike #warning) */} | |
75 | if ?cc/pragma_message | |
76 | then | |
77 | print [@ | |
78 | #define DO_PRAGMA(arg) _Pragma(#arg) | |
79 | #define TODO(x) DO_PRAGMA(message("TODO: " #x)) | |
80 | @] | |
81 | else | |
82 | print {\n/* Not available */\n#define TODO(x)\n} | |
83 | end | |
84 | ||
85 | print [@ | |
72 | 86 | #endif |
73 | 87 | |
74 | 88 | @] |
24 | 24 | #include "vars.h" |
25 | 25 | #include "f2d.h" |
26 | 26 | #include <string.h> |
27 | ||
28 | typedef long int da_word; | |
27 | 29 | |
28 | 30 | /* for load sanity checks declare large maximums; without these a malformed |
29 | 31 | binary may cause libmawk to allocate a lot of memory */ |
534 | 536 | return 0; |
535 | 537 | } |
536 | 538 | |
537 | static int save_bin_sect(mawk_state_t * MAWK, void *fd, int (*write)(void *fd, const void *buff, size_t len), INST *b, int len) | |
538 | { | |
539 | if (write(fd, &len, 4) != 4) | |
539 | static int save_bin_sect(mawk_state_t * MAWK, void *fd, int (*write)(void *fd, const void *buff, size_t len), INST *b, da_word len) | |
540 | { | |
541 | if (write(fd, &len, sizeof(da_word)) != sizeof(da_word)) | |
540 | 542 | return -1; |
541 | 543 | if (b != NULL) { |
542 | 544 | int l; |
552 | 554 | header_t h; |
553 | 555 | link_t l; |
554 | 556 | int n; |
555 | long int len, begin_len, end_len, main_len, num_func; | |
557 | long int begin_len, end_len, main_len; | |
558 | da_word num_func, len; | |
556 | 559 | long int *flen; |
557 | 560 | struct mawk_fdump **fps; |
558 | 561 | struct mawk_fdump *fp; |
598 | 601 | |
599 | 602 | /* L1: save nums */ |
600 | 603 | len = l.numsu; |
601 | write(fd, &len, 4); | |
604 | write(fd, &len, sizeof(da_word)); | |
602 | 605 | write(fd, l.nums, sizeof(mawk_num_t) * l.numsu); |
603 | write(fd, &num_func, 4); | |
606 | write(fd, &num_func, sizeof(da_word)); | |
604 | 607 | |
605 | 608 | /* L2: save strings */ |
606 | 609 | len = l.strsu; |
607 | write(fd, &len, 4); | |
610 | write(fd, &len, sizeof(da_word)); | |
608 | 611 | for(n = 0; n < l.strsu; n++) { |
609 | 612 | len = safe_strlen(l.strs[n]); |
610 | write(fd, &len, 4); | |
613 | write(fd, &len, sizeof(da_word)); | |
611 | 614 | if (len > 0) |
612 | 615 | write(fd, l.strs[n], len); |
613 | 616 | } |
614 | 617 | |
615 | 618 | /* L3: save vars */ |
616 | 619 | len = l.varsu; |
617 | write(fd, &len, 4); | |
620 | write(fd, &len, sizeof(da_word)); | |
618 | 621 | for(n = 0; n < l.varsu; n++) { |
619 | 622 | const char *name; |
620 | 623 | SYMTAB *stp; |
632 | 635 | |
633 | 636 | /* save name len and name*/ |
634 | 637 | len = strlen(name); |
635 | write(fd, &len, 4); | |
638 | write(fd, &len, sizeof(da_word)); | |
636 | 639 | write(fd, name, len); |
637 | 640 | |
638 | 641 | /* save value len and content - empty for now */ |
639 | 642 | len = 0; |
640 | write(fd, &len, 4); | |
643 | write(fd, &len, sizeof(da_word)); | |
641 | 644 | } |
642 | 645 | |
643 | 646 | /* L4: save begin/end/main sections */ |
654 | 657 | fp = fps[n]; |
655 | 658 | len = strlen(fp->fbp->name); |
656 | 659 | /* fprintf(stderr, "da_bin function %s/%d len=%d\n", fp->fbp->name, len,flen[n]); */ |
657 | write(fd, &len, 4); | |
660 | write(fd, &len, sizeof(da_word)); | |
658 | 661 | write(fd, fp->fbp->name, len); |
659 | 662 | /* fprintf(stderr, "NARGS=%d %d\n", fp->fbp->nargs, fp->fbp->typev[0]); */ |
660 | 663 | write(fd, &fp->fbp->nargs, 2); |
675 | 678 | #ifndef MAWK_NO_EXEC |
676 | 679 | static int bin_load_func(mawk_state_t *MAWK, void *fd, int (*read)(void *fd, void *buff, size_t len), FBLOCK *fbp) |
677 | 680 | { |
678 | int len; | |
679 | read(fd, &len, 4); | |
681 | da_word len; | |
682 | read(fd, &len, sizeof(da_word)); | |
680 | 683 | if (len > 0) { |
681 | 684 | if (len > BIN_CODE_MAXLEN) |
682 | 685 | return -1; |
689 | 692 | |
690 | 693 | static int bin_load_sect(mawk_state_t *MAWK, void *fd, int (*read)(void *fd, void *buff, size_t len), int scope) |
691 | 694 | { |
692 | int len; | |
693 | ||
694 | read(fd, &len, 4); | |
695 | da_word len; | |
696 | ||
697 | read(fd, &len, sizeof(da_word)); | |
695 | 698 | if (len > 0) { |
696 | 699 | MAWK->scope = scope; |
697 | 700 | if ((scope == SCOPE_BEGIN) || (scope == SCOPE_END)) |
727 | 730 | SYMTAB *stp; |
728 | 731 | header_t h; |
729 | 732 | link_t l; |
730 | int n, num_func; | |
731 | long int len; | |
733 | int n; | |
734 | da_word num_func, len; | |
732 | 735 | int ret; |
733 | 736 | |
734 | 737 | memset(&l, 0, sizeof(l)); |
775 | 778 | |
776 | 779 | |
777 | 780 | /* L1: load nums */ |
778 | read(fd, &len, 4); | |
781 | len = 0; | |
782 | read(fd, &len, sizeof(da_word)); | |
779 | 783 | l.numsa = l.numsu = len; |
780 | 784 | len = sizeof(*l.nums) * l.numsa; |
781 | 785 | if (len > BIN_MAXVARS) |
782 | 786 | goto err; |
783 | 787 | l.nums = malloc(len); |
784 | 788 | read(fd, l.nums, len); |
785 | read(fd, &num_func, 4); | |
789 | read(fd, &num_func, sizeof(da_word)); | |
786 | 790 | |
787 | 791 | /* L2: load strings */ |
788 | read(fd, &len, 4); | |
792 | read(fd, &len, sizeof(da_word)); | |
789 | 793 | l.strsa = l.strsu = len; |
790 | 794 | len = sizeof(*l.strs) * l.strsa; |
791 | 795 | if (len > BIN_MAXSTRS) |
794 | 798 | for(n = 0; n < l.strsu; n++) { |
795 | 799 | char *name; |
796 | 800 | |
797 | read(fd, &len, 4); | |
801 | read(fd, &len, sizeof(da_word)); | |
798 | 802 | if (len > BIN_NAME_MAXLEN) |
799 | 803 | goto err; |
800 | 804 | if (len > 0) { |
813 | 817 | } |
814 | 818 | |
815 | 819 | /* L3: load vars */ |
816 | read(fd, &len, 4); | |
820 | read(fd, &len, sizeof(da_word)); | |
817 | 821 | l.varsa = l.varsu = len; |
818 | 822 | len = sizeof(*l.vars) * l.varsa; |
819 | 823 | if (l.varsa > BIN_MAXVARS) |
829 | 833 | read(fd, &stype, 1); |
830 | 834 | |
831 | 835 | /* load name len and name*/ |
832 | read(fd, &len, 4); | |
836 | read(fd, &len, sizeof(da_word)); | |
833 | 837 | if (len > BIN_NAME_MAXLEN) |
834 | 838 | goto err; |
835 | 839 | name = mawk_zmalloc(MAWK, len+1); |
865 | 869 | |
866 | 870 | /* fprintf(stderr, "LOAD var name='%s' type=%d len=%d: %d -> %p\n", name, type, len, n, l.vars[n].cp); */ |
867 | 871 | /* load value len and content - empty for now */ |
868 | read(fd, &len, 4); | |
872 | read(fd, &len, sizeof(da_word)); | |
869 | 873 | if (len != 0) { |
870 | 874 | ret = MAWK_EWRONGVAL; |
871 | 875 | goto err2; |
889 | 893 | char *name; |
890 | 894 | FBLOCK *fbp; |
891 | 895 | |
892 | read(fd, &len, 4); | |
896 | read(fd, &len, sizeof(da_word)); | |
893 | 897 | /* fprintf(stderr, "LOAD function len=%d\n", len); */ |
894 | 898 | if (len > BIN_NAME_MAXLEN) |
895 | 899 | goto err; |
15 | 15 | |
16 | 16 | #include "conf.h" |
17 | 17 | |
18 | #warning this should be gone: | |
18 | TODO("this should be gone:") | |
19 | 19 | #include <stdio.h> |
20 | 20 | |
21 | 21 | #include "mawk.h" |
45 | 45 | FNR->d.dval = MAWK_NUM_ZERO; |
46 | 46 | MAWK->rt_fnr = 0; |
47 | 47 | MAWK->main_input = mawk_file_find_(MAWK, "/dev/stdin", F_IN, 1); |
48 | #warning TODO: abstract | |
48 | TODO(": abstract") | |
49 | 49 | MAWK->main_input->fin->flags |= MAWK_INPF_MAIN; |
50 | 50 | } |
51 | 51 | |
98 | 98 | mawk_errmsg(MAWK, errno, "cannot open %s", string(cp)->str); |
99 | 99 | mawk_exitval(MAWK, 2, NULL); |
100 | 100 | } |
101 | #warning TODO abstract this | |
101 | TODO("TODO abstract this") | |
102 | 102 | MAWK->main_input->fin->flags |= MAWK_INPF_MAIN; |
103 | 103 | |
104 | 104 | /* success -- set FILENAME and FNR */ |
340 | 340 | if (MAWK->rs_shadow.type == SEP_MLR) { |
341 | 341 | char *s; |
342 | 342 | /* trim blank lines from front of file */ |
343 | #warning TODO: probably accept \r as well | |
343 | TODO(": probably accept \r as well") | |
344 | 344 | for(s = fin->next; *s == '\n'; s++) ; |
345 | 345 | if (*s == '\0') { |
346 | 346 | /* emptied the buffer with all the \n's... so get back to initial state */ |
15 | 15 | #include "conf.h" |
16 | 16 | #include <stdlib.h> |
17 | 17 | #include <string.h> |
18 | #include <stdio.h> | |
18 | 19 | #include <ctype.h> |
19 | 20 | #include "mawk.h" |
20 | 21 | #include "code.h" |
422 | 423 | break; |
423 | 424 | |
424 | 425 | case '-': |
425 | if (argv[i][2] != 0) | |
426 | if (argv[i][2] != 0) { | |
427 | if ((strcmp(argv[i], "--version") == 0) || (strcmp(argv[i], "--help") == 0)) { | |
428 | printf("\nlmawk is libmawk " LMAWK_VER "\nFor more info, see the manual page for lmawk(1) and\nhttp://repo.hu/projects/libmawk.\n\n"); | |
429 | exit(0); | |
430 | } | |
426 | 431 | bad_option(MAWK, argv[i]); |
432 | } | |
427 | 433 | i++; |
428 | 434 | goto no_more_opts; |
429 | 435 | #ifndef MAWK_NO_COMP |
54 | 54 | m2 = mawk_initialize_argv(m, argc, argv); |
55 | 55 | |
56 | 56 | if (m2 == NULL) { |
57 | #warning TODO: cleanup m | |
57 | TODO(": cleanup m") | |
58 | 58 | return NULL; |
59 | 59 | } |
60 | 60 | m = m2; |
311 | 311 | else |
312 | 312 | fbp = fs->stval.fbp; |
313 | 313 | |
314 | #warning TODO: check if we need to grow the stack | |
314 | TODO(": check if we need to grow the stack") | |
315 | 315 | |
316 | 316 | orig_sp = MAWK->sp; |
317 | 317 | va_start(ap, argtypes); |
359 | 359 | else |
360 | 360 | fbp = fs->stval.fbp; |
361 | 361 | |
362 | #warning TODO: check if we need to grow the stack | |
362 | TODO(": check if we need to grow the stack") | |
363 | 363 | |
364 | 364 | orig_sp = MAWK->sp; |
365 | 365 | for(numargs = 0;*argtypes != '\0';argtypes++,numargs++,args++) { |
404 | 404 | else |
405 | 405 | fbp = fs->stval.fbp; |
406 | 406 | |
407 | #warning TODO: check if we need to grow the stack | |
407 | TODO(": check if we need to grow the stack") | |
408 | 408 | |
409 | 409 | for(n = 0; n< argc; n++) { |
410 | 410 | inc_mawksp(); |
452 | 452 | break; |
453 | 453 | case C_STRNUM: |
454 | 454 | case C_MBSTRN: |
455 | #warning TODO: we should be able to convert the above two | |
455 | TODO(": we should be able to convert the above two") | |
456 | 456 | case C_RE: |
457 | 457 | case C_SPACE: |
458 | 458 | case C_SNULL: |
0 | .\" Copyright 2009 Tibor Palinkas (mawk@inno.bme.hu) | |
1 | .\" | |
2 | .\" Permission is granted to make and distribute verbatim copies of this | |
3 | .\" manual provided the copyright notice and this permission notice are | |
4 | .\" preserved on all copies. | |
5 | .\" | |
6 | .\" Permission is granted to copy and distribute modified versions of this | |
7 | .\" manual under the conditions for verbatim copying, provided that the | |
8 | .\" entire resulting derived work is distributed under the terms of a | |
9 | .\" permission notice identical to this one. | |
10 | .\" | |
11 | .\" Formatted or processed versions of this manual, if unaccompanied by | |
12 | .\" the source, must acknowledge the copyright and authors of this work. | |
13 | .\" | |
14 | .TH EXAMPLE 7 2009-08-10 "libmawk" "libmawk manual" | |
15 | .SH NAME | |
16 | libmawk example \- how to use the library | |
17 | .SH SYNOPSIS | |
18 | .nf | |
19 | .B #include <libmawk.h> | |
20 | .sp | |
21 | .SH DESCRIPTION | |
22 | Libmawk is a library that lets applications to embed awk scripts using the | |
23 | code of the popular implementation | |
24 | .B mawk. | |
25 | The normal process is to call libmawk_initialize() to set up a new mawk | |
26 | context (with script(s) loaded), then in the main loop feed it using | |
27 | libmawk_append_input(). For "out of band" communication, the program | |
28 | may also call functions implemented in awk and read (or modify) global | |
29 | variables of the awk script. The hos tapplication usally will also bind | |
30 | some of its functions to the context using libmawk_register_function, which | |
31 | allows the awk script to call the host applicaiton's functions directly as | |
32 | they were awk builtins or user defined functions. After the main loop, the | |
33 | application destroys the context freeing up all memory allocated for | |
34 | the script(s). | |
35 | .sp | |
36 | One context is for one awk program. One awk program may consist of multiple | |
37 | script files (just as with command line awk, with multiple -f filename | |
38 | arguments). Libmawk is instance safe, the host application may create | |
39 | multiple instances of contexts with the same or with different set of | |
40 | awk scripts loaded. These contexts are totally separate, no variables, | |
41 | functions or any sort of states are shared. However, the host application | |
42 | may provide means of communication between those scripts by custom functions | |
43 | or by copying variable contents between them. | |
44 | .SH Example application | |
45 | The following example application creates a single context to demonstrate | |
46 | all the above mentioned functionality. | |
47 | .nf | |
48 | .fi |
58 | 58 | # define P_isnan_manual(x) 0 |
59 | 59 | |
60 | 60 | #else |
61 | #include <float.h> | |
61 | 62 | /* broken or missing NAN support, always have to check manually */ |
62 | 63 | # define P_nansafe1(dest, operation, operand) \ |
63 | 64 | do { \ |
64 | 65 | if (P_isnan(operand) || P_isnan(dest)) (dest) = P_nan(); \ |
65 | else (dest) = (operation); \ | |
66 | else { \ | |
67 | (dest) = (operation); \ | |
68 | if (P_isnan(dest)) \ | |
69 | (dest) = DBL_MAX; \ | |
70 | } \ | |
66 | 71 | } while(0) |
67 | 72 | # define P_isnan_manual P_isnan |
68 | 73 | #endif |
65 | 65 | PM_END |
66 | 66 | return r; |
67 | 67 | } |
68 | ||
69 | #ifndef MAWK_HAVE_SAFE_NAN | |
70 | double mawk_strtonum_(const char *nptr, char **endptr) | |
71 | { | |
72 | if (((nptr[0] == 'n') || (nptr[0] == 'N')) && ((nptr[1] == 'a') || (nptr[1] == 'A')) && ((nptr[2] == 'n') || (nptr[2] == 'N'))) { | |
73 | if (endptr != NULL) | |
74 | *endptr = (char *)(nptr+3); | |
75 | return P_nan(); | |
76 | } | |
77 | return strtod(nptr, endptr); | |
78 | } | |
79 | #endif |
16 | 16 | #ifdef MAWK_HAVE_SAFE_NAN |
17 | 17 | #define P_isnan(x) isnan(x) |
18 | 18 | #define P_nan() nan("nan") |
19 | #define strtonum(nptr, endptr) strtod(nptr, endptr) | |
19 | 20 | #else |
20 | 21 | #define NUM_NAN HUGE_VAL |
21 | 22 | #define P_isnan(x) ((x) == NUM_NAN) |
22 | 23 | #define P_nan() (NUM_NAN) |
24 | #define strtonum(nptr, endptr) mawk_strtonum_(nptr, endptr) | |
25 | double mawk_strtonum_(const char *nptr, char **endptr); | |
23 | 26 | #endif |
24 | 27 | |
25 | 28 | double mawk_num_pow(double x, double y); |
26 | 29 | double P_fmod(double x, double y); |
27 | 30 | |
28 | #define strtonum(nptr, endptr) strtod(nptr, endptr) | |
29 | 31 | |
32 |
71 | 71 | { |
72 | 72 | Int ival = mawk_d_to_I(p->d.dval); |
73 | 73 | const char *txt; |
74 | ||
75 | if (P_isnan(p->d.dval)) { | |
76 | mawk_vio_write_str(MAWK, fnode->vf, "nan"); | |
77 | break; | |
78 | } | |
74 | 79 | |
75 | 80 | txt = mawk_num_print_spec(ival); |
76 | 81 | if (txt != NULL) |
398 | 403 | bad_conversion(MAWK, num_conversion, who, format); |
399 | 404 | if (cp->type != C_NUM) |
400 | 405 | mawk_cast1_to_num(MAWK, cp); |
401 | pf_type = PF_F; | |
406 | if (P_isnan(cp->d.dval)) { | |
407 | cp->ptr = (PTR) mawk_new_STRING(MAWK, "nan"); | |
408 | cp->type = C_STRING; | |
409 | cp->d.dval = 42; | |
410 | p = "%s"; | |
411 | pf_type = PF_S; | |
412 | } | |
413 | else | |
414 | pf_type = PF_F; | |
402 | 415 | break; |
403 | 416 | #endif |
404 | 417 |
20 | 20 | ../examples/gdecl.dab\ |
21 | 21 | ../examples/nocomment.dab\ |
22 | 22 | ../examples/primes.dab\ |
23 | ../examples/qsort.dab\ | |
23 | ../examples/qsort.dab |
71 | 71 | mawk_vio_fifo_t *v = (mawk_vio_fifo_t *)vf; |
72 | 72 | if (!v->is_awk2app) |
73 | 73 | return -1; |
74 | #warning TODO | |
74 | TODO("TODO") | |
75 | 75 | abort(); |
76 | 76 | return -1; |
77 | 77 | } |
161 | 161 | |
162 | 162 | |
163 | 163 | |
164 | #warning TODO print runtime warnings | |
164 | TODO("TODO print runtime warnings") | |
165 | 165 | mawk_vio_t *mawk_vio_orig_open(mawk_state_t *MAWK, const char *name, mawk_vio_open_mode_t mode) |
166 | 166 | { |
167 | 167 | mawk_vio_orig_t *vf; |
286 | 286 | close(remote_fd); |
287 | 287 | /* we could deadlock if future child inherit the local fd , |
288 | 288 | set close on exec flag */ |
289 | #warning TODO: better do this by hand - close on exec is not really portable | |
289 | TODO(": better do this by hand - close on exec is not really portable") | |
290 | 290 | CLOSE_ON_EXEC(local_fd); |
291 | 291 | break; |
292 | 292 | } |