00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "defs.h"
00024 #include "usignal.h"
00025
00026 char binread[] = "rb", textread[] = "r";
00027 char binwrite[] = "wb", textwrite[] = "w";
00028 char *c_functions = "c_functions";
00029 char *coutput = "c_output";
00030 char *initfname = "raw_data";
00031 char *initbname = "raw_data.b";
00032 char *blkdfname = "block_data";
00033 char *p1_file = "p1_file";
00034 char *p1_bakfile = "p1_file.BAK";
00035 char *sortfname = "init_file";
00036 char *proto_fname = "proto_file";
00037
00038 char link_msg[] = "on Microsoft Windows system, link with libf2c.lib;\n\
00039 on Linux or Unix systems, link with .../path/to/libf2c.a -lm\n\
00040 or, if you install libf2c.a in a standard place, with -lf2c -lm\n\
00041 -- in that order, at the end of the command line, as in\n\
00042 cc *.o -lf2c -lm\n\
00043 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,\n\n\
00044 http://www.netlib.org/f2c/libf2c.zip";
00045
00046 char *outbuf = "", *outbtail;
00047
00048 #undef WANT_spawnvp
00049 #ifdef MSDOS
00050 #ifndef NO_spawnvp
00051 #define WANT_spawnvp
00052 #endif
00053 #endif
00054
00055 #ifdef _WIN32
00056 #include <windows.h>
00057 #undef WANT_spawnvp
00058 #define WANT_spawnvp
00059 #undef MSDOS
00060 #define MSDOS
00061 #endif
00062
00063 #ifdef WANT_spawnvp
00064 #include <process.h>
00065 #ifndef _P_WAIT
00066 #define _P_WAIT P_WAIT
00067 #endif
00068 static char **spargv, **pfname;
00069 #endif
00070
00071 char *tmpdir = "";
00072
00073 #ifdef __cplusplus
00074 #define Cextern extern "C"
00075 extern "C" {
00076 static void flovflo(int), killed(int);
00077 static int compare(const void *a, const void *b);
00078 }
00079 #else
00080 #define Cextern extern
00081 #endif
00082
00083 Cextern int unlink Argdcl((const char *));
00084 Cextern int fork Argdcl((void)), getpid Argdcl((void)), wait Argdcl((int*));
00085
00086 #ifdef _MSC_VER
00087 #define unlink _unlink
00088 #endif
00089
00090 void
00091 #ifdef KR_headers
00092 Un_link_all(cdelete)
00093 int cdelete;
00094 #else
00095 Un_link_all(int cdelete)
00096 #endif
00097 {
00098 if (!debugflag) {
00099 unlink(c_functions);
00100 unlink(initfname);
00101 unlink(p1_file);
00102 unlink(sortfname);
00103 unlink(blkdfname);
00104 if (cdelete && coutput)
00105 unlink(coutput);
00106 }
00107 }
00108
00109 #ifndef _MSC_VER
00110 #ifndef NO_TEMPDIR
00111 static void rmtdir(Void)
00112 {
00113 char *s;
00114 if (*(s = tmpdir))
00115 {
00116 tmpdir = "";
00117 rmdir(s);
00118 }
00119 }
00120 #endif
00121 #endif
00122
00123 #ifndef MSDOS
00124 #include "sysdep.hd"
00125 #endif
00126
00127 static void
00128 alloc_names(Void)
00129 {
00130 int k = strlen(tmpdir) + 24;
00131 c_functions = (char *)ckalloc(7*k);
00132 initfname = c_functions + k;
00133 initbname = initfname + k;
00134 blkdfname = initbname + k;
00135 p1_file = blkdfname + k;
00136 p1_bakfile = p1_file + k;
00137 sortfname = p1_bakfile + k;
00138 }
00139
00140 void
00141 set_tmp_names(Void)
00142 {
00143 #ifdef MSDOS
00144 char buf[64], *s, *t;
00145 #ifdef _WIN32
00146 DWORD flags, maxlen, volser;
00147 char volname[512], f2c[24], fsname[512];
00148 int i;
00149
00150 if (debugflag == 1)
00151 return;
00152 i = sprintf(f2c, "%x", _getpid());
00153 if (!GetVolumeInformation(NULL, volname, sizeof(volname), &volser, &maxlen,
00154 &flags, fsname, sizeof(fsname))
00155 || maxlen < (DWORD)(i+8))
00156 strcpy(f2c, "f2c_");
00157 #else
00158 static char f2c[] = "f2c_";
00159 if (debugflag == 1)
00160 return;
00161 #endif
00162
00163 if (!*tmpdir || *tmpdir == '.' && !tmpdir[1])
00164 t = "";
00165 else {
00166
00167
00168
00169
00170 for(s = tmpdir, t = buf; *s; s++, t++)
00171 if ((*t = *s) == '/')
00172 *t = '\\';
00173 if (t[-1] != '\\')
00174 *t++ = '\\';
00175 *t = 0;
00176 t = buf;
00177 }
00178 alloc_names();
00179 sprintf(c_functions, "%s%sfunc", t, f2c);
00180 sprintf(initfname, "%s%srd", t, f2c);
00181 sprintf(blkdfname, "%s%sblkd", t, f2c);
00182 sprintf(p1_file, "%s%sp1f", t, f2c);
00183 sprintf(p1_bakfile, "%s%sp1fb", t, f2c);
00184 sprintf(sortfname, "%s%ssort", t, f2c);
00185 #else
00186 long pid;
00187
00188 #define L_TDNAME 20
00189 #ifdef NO_MKDTEMP
00190 #ifdef NO_MKSTEMP
00191 #undef L_TDNAME
00192 #define L_TDNAME L_tmpnam
00193 #endif
00194 #endif
00195 static char tdbuf[L_TDNAME];
00196
00197 if (debugflag == 1)
00198 return;
00199 pid = getpid();
00200 if (!*tmpdir) {
00201 #ifdef NO_TEMPDIR
00202 tmpdir = "/tmp";
00203 #else
00204 #ifdef NO_MKDTEMP
00205 #ifdef NO_MKSTEMP
00206 if (!(tmpdir = tmpnam(tdbuf))) {
00207 fprintf(stderr, "tmpnam failed (for -T)\n");
00208 exit(1);
00209 }
00210 #else
00211 int f;
00212 strcpy(tdbuf, "/tmp/f2ctd_XXXXXX");
00213 f = mkstemp(tdbuf);
00214 if (f >= 0) {
00215 close(f);
00216 remove(tmpdir = tdbuf);
00217 }
00218 else {
00219 fprintf(stderr, "mkstemp failed (for -T)\n");
00220 exit(1);
00221 }
00222 #endif
00223 if (mkdir(tdbuf,0700)) {
00224 fprintf(stderr, "mkdir failed (for -T)\n");
00225 exit(1);
00226 }
00227 #else
00228 strcpy(tdbuf, "/tmp/f2ctd_XXXXXX");
00229 if (!(tmpdir = mkdtemp(tdbuf))) {
00230 fprintf(stderr, "mkdtemp failed (for -T)\n");
00231 exit(1);
00232 }
00233 #endif
00234 if (!debugflag)
00235 atexit(rmtdir);
00236 #endif
00237 }
00238 alloc_names();
00239 sprintf(c_functions, "%s/f2c%ld_func", tmpdir, pid);
00240 sprintf(initfname, "%s/f2c%ld_rd", tmpdir, pid);
00241 sprintf(blkdfname, "%s/f2c%ld_blkd", tmpdir, pid);
00242 sprintf(p1_file, "%s/f2c%ld_p1f", tmpdir, pid);
00243 sprintf(p1_bakfile, "%s/f2c%ld_p1fb", tmpdir, pid);
00244 sprintf(sortfname, "%s/f2c%ld_sort", tmpdir, pid);
00245 #endif
00246 sprintf(initbname, "%s.b", initfname);
00247 if (debugflag)
00248 fprintf(diagfile, "%s %s %s %s %s %s\n", c_functions,
00249 initfname, blkdfname, p1_file, p1_bakfile, sortfname);
00250 }
00251
00252 char *
00253 #ifdef KR_headers
00254 c_name(s, ft)
00255 char *s;
00256 int ft;
00257 #else
00258 c_name(char *s, int ft)
00259 #endif
00260 {
00261 char *b, *s0;
00262 int c;
00263
00264 b = s0 = s;
00265 while(c = *s++)
00266 if (c == '/')
00267 b = s;
00268 if (--s < s0 + 3 || s[-2] != '.'
00269 || ((c = *--s) != 'f' && c != 'F')) {
00270 infname = s0;
00271 Fatal("file name must end in .f or .F");
00272 }
00273 strcpy(outbtail, b);
00274 outbtail[s-b] = ft;
00275 b = copys(outbuf);
00276 return b;
00277 }
00278
00279 static void
00280 #ifdef KR_headers
00281 killed(sig)
00282 int sig;
00283 #else
00284 killed(int sig)
00285 #endif
00286 {
00287 sig = sig;
00288 signal(SIGINT, SIG_IGN);
00289 #ifdef SIGQUIT
00290 signal(SIGQUIT, SIG_IGN);
00291 #endif
00292 #ifdef SIGHUP
00293 signal(SIGHUP, SIG_IGN);
00294 #endif
00295 signal(SIGTERM, SIG_IGN);
00296 Un_link_all(1);
00297 exit(126);
00298 }
00299
00300 static void
00301 #ifdef KR_headers
00302 sig1catch(sig)
00303 int sig;
00304 #else
00305 sig1catch(int sig)
00306 #endif
00307 {
00308 sig = sig;
00309 if (signal(sig, SIG_IGN) != SIG_IGN)
00310 signal(sig, killed);
00311 }
00312
00313 static void
00314 #ifdef KR_headers
00315 flovflo(sig)
00316 int sig;
00317 #else
00318 flovflo(int sig)
00319 #endif
00320 {
00321 sig = sig;
00322 Fatal("floating exception during constant evaluation; cannot recover");
00323
00324
00325
00326
00327 signal(SIGFPE, flovflo);
00328 }
00329
00330 void
00331 #ifdef KR_headers
00332 sigcatch(sig)
00333 int sig;
00334 #else
00335 sigcatch(int sig)
00336 #endif
00337 {
00338 sig = sig;
00339 sig1catch(SIGINT);
00340 #ifdef SIGQUIT
00341 sig1catch(SIGQUIT);
00342 #endif
00343 #ifdef SIGHUP
00344 sig1catch(SIGHUP);
00345 #endif
00346 sig1catch(SIGTERM);
00347 signal(SIGFPE, flovflo);
00348 }
00349
00350
00351
00352
00353 void
00354 #ifdef KR_headers
00355 argkludge(pargc, pargv) int *pargc; char ***pargv;
00356 #else
00357 argkludge(int *pargc, char ***pargv)
00358 #endif
00359 {
00360 #ifdef WANT_spawnvp
00361 size_t L, L1;
00362 int argc, i, nf;
00363 char **a, **argv, *s, *t, *t0;
00364
00365
00366
00367
00368
00369 L = argc = *pargc;
00370 argv = *pargv;
00371 for(i = nf = 0; i < argc; i++) {
00372 L += L1 = strlen(s = argv[i]);
00373 if (L1 > 2 && s[L1-2] == '.')
00374 switch(s[L1-1]) {
00375 case 'f':
00376 case 'F':
00377 nf++;
00378 }
00379 }
00380 if (nf <= 1)
00381 return;
00382
00383
00384
00385 i = argc - nf + 2;
00386 a = spargv = (char**)Alloc(i*sizeof(char*) + L);
00387 t = (char*)(a + i);
00388 for(i = 0; i < argc; i++) {
00389 *a++ = t0 = t;
00390 for(s = argv[i]; *t++ = *s; s++);
00391 if (t-t0 > 3 && s[-2] == '.')
00392 switch(s[-1]) {
00393 case 'f':
00394 case 'F':
00395 --a;
00396 t = t0;
00397 }
00398 }
00399 pfname = a++;
00400 *a = 0;
00401 #endif
00402 }
00403
00404 int
00405 #ifdef KR_headers
00406 dofork(fname) char *fname;
00407 #else
00408 dofork(char *fname)
00409 #endif
00410 {
00411 extern int retcode;
00412 #ifdef MSDOS
00413 #ifdef WANT_spawnvp
00414 *pfname = fname;
00415 retcode |= _spawnvp(_P_WAIT, spargv[0], (char const*const*)spargv);
00416 #else
00417 Fatal("Only one Fortran input file allowed under MS-DOS");
00418 #endif
00419 #else
00420 int pid, status, w;
00421
00422 if (!(pid = fork()))
00423 return 1;
00424 if (pid == -1)
00425 Fatal("bad fork");
00426 while((w = wait(&status)) != pid)
00427 if (w == -1)
00428 Fatal("bad wait code");
00429 retcode |= status >> 8;
00430 #endif
00431 return 0;
00432 }
00433
00434
00435
00436 char escapes[Table_size];
00437
00438 #ifdef non_ASCII
00439 char *str_fmt[Table_size];
00440 static char *str0fmt[127] = {
00441 #else
00442 char *str_fmt[Table_size] = {
00443 #endif
00444 "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
00445 "\\b", "\\t", "\\n", "\\013", "\\f", "\\r", "\\016", "\\017",
00446 "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
00447 "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
00448 " ", "!", "\\\"", "#", "$", "%%", "&", "'",
00449 "(", ")", "*", "+", ",", "-", ".", "/",
00450 "0", "1", "2", "3", "4", "5", "6", "7",
00451 "8", "9", ":", ";", "<", "=", ">", "?",
00452 "@", "A", "B", "C", "D", "E", "F", "G",
00453 "H", "I", "J", "K", "L", "M", "N", "O",
00454 "P", "Q", "R", "S", "T", "U", "V", "W",
00455 "X", "Y", "Z", "[", "\\\\", "]", "^", "_",
00456 "`", "a", "b", "c", "d", "e", "f", "g",
00457 "h", "i", "j", "k", "l", "m", "n", "o",
00458 "p", "q", "r", "s", "t", "u", "v", "w",
00459 "x", "y", "z", "{", "|", "}", "~"
00460 };
00461
00462 #ifdef non_ASCII
00463 char *chr_fmt[Table_size];
00464 static char *chr0fmt[127] = {
00465 #else
00466 char *chr_fmt[Table_size] = {
00467 #endif
00468 "\\0", "\\1", "\\2", "\\3", "\\4", "\\5", "\\6", "\\7",
00469 "\\b", "\\t", "\\n", "\\13", "\\f", "\\r", "\\16", "\\17",
00470 "\\20", "\\21", "\\22", "\\23", "\\24", "\\25", "\\26", "\\27",
00471 "\\30", "\\31", "\\32", "\\33", "\\34", "\\35", "\\36", "\\37",
00472 " ", "!", "\"", "#", "$", "%%", "&", "\\'",
00473 "(", ")", "*", "+", ",", "-", ".", "/",
00474 "0", "1", "2", "3", "4", "5", "6", "7",
00475 "8", "9", ":", ";", "<", "=", ">", "?",
00476 "@", "A", "B", "C", "D", "E", "F", "G",
00477 "H", "I", "J", "K", "L", "M", "N", "O",
00478 "P", "Q", "R", "S", "T", "U", "V", "W",
00479 "X", "Y", "Z", "[", "\\\\", "]", "^", "_",
00480 "`", "a", "b", "c", "d", "e", "f", "g",
00481 "h", "i", "j", "k", "l", "m", "n", "o",
00482 "p", "q", "r", "s", "t", "u", "v", "w",
00483 "x", "y", "z", "{", "|", "}", "~"
00484 };
00485
00486 void
00487 fmt_init(Void)
00488 {
00489 static char *str1fmt[6] =
00490 { "\\b", "\\t", "\\n", "\\f", "\\r", "\\013" };
00491 register int i, j;
00492 register char *s;
00493
00494
00495
00496 #ifdef non_ASCII
00497 i = 0;
00498 #else
00499 i = 127;
00500 #endif
00501 s = Alloc(5*(Table_size - i));
00502 for(; i < Table_size; i++) {
00503 sprintf(str_fmt[i] = s, "\\%03o", i);
00504 s += 5;
00505 }
00506 #ifdef non_ASCII
00507 for(i = 32; i < 127; i++) {
00508 s = str0fmt[i];
00509 str_fmt[*(unsigned char *)s] = s;
00510 }
00511 str_fmt['"'] = "\\\"";
00512 #else
00513 if (Ansi == 1)
00514 str_fmt[7] = chr_fmt[7] = "\\a";
00515 #endif
00516
00517
00518
00519 #ifdef non_ASCII
00520 for(i = 0; i < 32; i++)
00521 chr_fmt[i] = chr0fmt[i];
00522 #else
00523 i = 127;
00524 #endif
00525 for(; i < Table_size; i++)
00526 chr_fmt[i] = "\\%o";
00527 #ifdef non_ASCII
00528 for(i = 32; i < 127; i++) {
00529 s = chr0fmt[i];
00530 j = *(unsigned char *)s;
00531 if (j == '\\')
00532 j = *(unsigned char *)(s+1);
00533 chr_fmt[j] = s;
00534 }
00535 #endif
00536
00537
00538
00539 for(i = 0; i < Table_size; i++)
00540 escapes[i] = i;
00541 for(s = "btnfr0", i = 0; i < 6; i++)
00542 escapes[*(unsigned char *)s++] = "\b\t\n\f\r"[i];
00543
00544
00545 if (Ansi)
00546 str1fmt[5] = "\\v";
00547 if ('\v' == 'v') {
00548 str1fmt[5] = "v";
00549 #ifndef non_ASCII
00550 escapes['v'] = 11;
00551 #endif
00552 }
00553 else
00554 escapes['v'] = '\v';
00555 for(s = "\b\t\n\f\r\v", i = 0; j = *(unsigned char *)s++;)
00556 str_fmt[j] = chr_fmt[j] = str1fmt[i++];
00557
00558 chr_fmt[11] = (char*)(Ansi ? "\\v" : "\\13");
00559 }
00560
00561 void
00562 outbuf_adjust(Void)
00563 {
00564 int n, n1;
00565 char *s;
00566
00567 n = n1 = strlen(outbuf);
00568 if (*outbuf && outbuf[n-1] != '/')
00569 n1++;
00570 s = Alloc(n+64);
00571 outbtail = s + n1;
00572 strcpy(s, outbuf);
00573 if (n != n1)
00574 strcpy(s+n, "/");
00575 outbuf = s;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 #ifdef SYSTEM_SORT
00589
00590 int
00591 #ifdef KR_headers
00592 dsort(from, to)
00593 char *from;
00594 char *to;
00595 #else
00596 dsort(char *from, char *to)
00597 #endif
00598 {
00599 char buf[200];
00600 sprintf(buf, "sort <%s >%s", from, to);
00601 return system(buf) >> 8;
00602 }
00603 #else
00604
00605 static int
00606 #ifdef KR_headers
00607 compare(a,b)
00608 char *a, *b;
00609 #else
00610 compare(const void *a, const void *b)
00611 #endif
00612 { return strcmp(*(char **)a, *(char **)b); }
00613
00614 int
00615 #ifdef KR_headers
00616 dsort(from, to)
00617 char *from;
00618 char *to;
00619 #else
00620 dsort(char *from, char *to)
00621 #endif
00622 {
00623 struct Memb {
00624 struct Memb *next;
00625 int n;
00626 char buf[32000];
00627 };
00628 typedef struct Memb memb;
00629 memb *mb, *mb1;
00630 register char *x, *x0, *xe;
00631 register int c, n;
00632 FILE *f;
00633 char **z, **z0;
00634 int nn = 0;
00635
00636 f = opf(from, textread);
00637 mb = (memb *)Alloc(sizeof(memb));
00638 mb->next = 0;
00639 x0 = x = mb->buf;
00640 xe = x + sizeof(mb->buf);
00641 n = 0;
00642 for(;;) {
00643 c = getc(f);
00644 if (x >= xe && (c != EOF || x != x0)) {
00645 if (!n)
00646 return 126;
00647 nn += n;
00648 mb->n = n;
00649 mb1 = (memb *)Alloc(sizeof(memb));
00650 mb1->next = mb;
00651 mb = mb1;
00652 memcpy(mb->buf, x0, n = x-x0);
00653 x0 = mb->buf;
00654 x = x0 + n;
00655 xe = x0 + sizeof(mb->buf);
00656 n = 0;
00657 }
00658 if (c == EOF)
00659 break;
00660 if (c == '\n') {
00661 ++n;
00662 *x++ = 0;
00663 x0 = x;
00664 }
00665 else
00666 *x++ = c;
00667 }
00668 clf(&f, from, 1);
00669 f = opf(to, textwrite);
00670 if (x > x0) {
00671 *x = 0;
00672 ++n;
00673 }
00674 mb->n = n;
00675 nn += n;
00676 if (!nn)
00677 goto done;
00678 z = z0 = (char **)Alloc(nn*sizeof(char *));
00679 for(mb1 = mb; mb1; mb1 = mb1->next) {
00680 x = mb1->buf;
00681 n = mb1->n;
00682 for(;;) {
00683 *z++ = x;
00684 if (--n <= 0)
00685 break;
00686 while(*x++);
00687 }
00688 }
00689 qsort((char *)z0, nn, sizeof(char *), compare);
00690 for(n = nn, z = z0; n > 0; n--)
00691 fprintf(f, "%s\n", *z++);
00692 free((char *)z0);
00693 done:
00694 clf(&f, to, 1);
00695 do {
00696 mb1 = mb->next;
00697 free((char *)mb);
00698 }
00699 while(mb = mb1);
00700 return 0;
00701 }
00702 #endif