1 | /****************************************************************************/ |
---|
2 | /* CLIB.C: assorted C routines with prototypes in stdinc.h. */ |
---|
3 | /* Copyright (c) 1999 by Joshua E. Barnes, Tokyo, JAPAN. */ |
---|
4 | /****************************************************************************/ |
---|
5 | |
---|
6 | #include "stdinc.h" |
---|
7 | #include "getparam.h" |
---|
8 | #include <sys/types.h> |
---|
9 | #include <sys/times.h> |
---|
10 | #include <sys/param.h> |
---|
11 | #include <sys/stat.h> |
---|
12 | #include <stdarg.h> |
---|
13 | |
---|
14 | /* |
---|
15 | * ALLOCATE: memory allocation, with error checking. |
---|
16 | */ |
---|
17 | |
---|
18 | void *allocate(int nb) |
---|
19 | { |
---|
20 | void *mem; |
---|
21 | |
---|
22 | mem = calloc(nb, 1); /* allocate, also clearing memory */ |
---|
23 | if (mem == NULL) |
---|
24 | error("allocate in %s: not enuf memory (%d bytes)\n", |
---|
25 | getargv0(), nb); |
---|
26 | return (mem); |
---|
27 | } |
---|
28 | |
---|
29 | /* |
---|
30 | * CPUTIME: compute total process CPU time in minutes. |
---|
31 | */ |
---|
32 | |
---|
33 | double cputime(void) |
---|
34 | { |
---|
35 | struct tms buffer; |
---|
36 | |
---|
37 | if (times(&buffer) == -1) |
---|
38 | error("cputime in %s: times() call failed\n", getargv0()); |
---|
39 | return ((buffer.tms_utime + buffer.tms_stime) / (60.0 * HZ)); |
---|
40 | } |
---|
41 | |
---|
42 | /* |
---|
43 | * ERROR: scream and die quickly. |
---|
44 | */ |
---|
45 | |
---|
46 | void error(string fmt, ...) |
---|
47 | { |
---|
48 | va_list ap; |
---|
49 | |
---|
50 | va_start(ap, fmt); |
---|
51 | vfprintf(stderr, fmt, ap); /* invoke interface to printf */ |
---|
52 | fflush(stderr); /* drain std error buffer */ |
---|
53 | va_end(ap); |
---|
54 | exit(1); /* quit with error status */ |
---|
55 | } |
---|
56 | |
---|
57 | /* |
---|
58 | * EPRINTF: scream, but don't die yet. |
---|
59 | */ |
---|
60 | |
---|
61 | void eprintf(string fmt, ...) |
---|
62 | { |
---|
63 | va_list ap; |
---|
64 | |
---|
65 | va_start(ap, fmt); |
---|
66 | vfprintf(stderr, fmt, ap); /* invoke interface to printf */ |
---|
67 | fflush(stderr); /* drain std error buffer */ |
---|
68 | va_end(ap); |
---|
69 | } |
---|
70 | |
---|
71 | /* |
---|
72 | * SCANOPT: scan string of the form "word1,word2,..." for a match. |
---|
73 | * Words must be separated by commas only -- no spaces allowed! |
---|
74 | */ |
---|
75 | |
---|
76 | bool scanopt(string opt, string key) |
---|
77 | { |
---|
78 | char *op, *kp; |
---|
79 | |
---|
80 | op = (char *) opt; /* start scan of option strings */ |
---|
81 | while (*op != NULL) { /* loop while words left to check */ |
---|
82 | kp = key; /* (re)start scan of key word */ |
---|
83 | while ((*op != ',' ? *op : (char) NULL) == *kp) { |
---|
84 | /* char by char, compare word, key */ |
---|
85 | if (*kp++ == NULL) /* reached end of key word, so... */ |
---|
86 | return (TRUE); /* indicate success */ |
---|
87 | op++; /* else go on to next char */ |
---|
88 | } |
---|
89 | while (*op != NULL && *op++ != ',') |
---|
90 | /* scan for start of next word */ |
---|
91 | continue; |
---|
92 | } |
---|
93 | return (FALSE); /* indicate failure */ |
---|
94 | } |
---|
95 | |
---|
96 | /* |
---|
97 | * STROPEN: open a STDIO stream like fopen, with these extensions: (1) |
---|
98 | * existing files cannot be opend for writing unless mode == "w!" or |
---|
99 | * mode == "a", (2) names of form "-" map to stdin/stdout, depending on |
---|
100 | * mode, and (3) names of the form "-num" up a stream to read/write file |
---|
101 | * descriptor num. |
---|
102 | */ |
---|
103 | |
---|
104 | stream stropen(string name, string mode) |
---|
105 | { |
---|
106 | bool inflag; |
---|
107 | int fds; |
---|
108 | stream res; |
---|
109 | struct stat buf; |
---|
110 | |
---|
111 | inflag = streq(mode, "r"); |
---|
112 | if (name[0] == '-') { |
---|
113 | if (streq(name, "-")) { |
---|
114 | fds = dup(fileno(inflag ? stdin : stdout)); |
---|
115 | if (fds == -1) |
---|
116 | error("stropen in %s: cannot dup %s\n", |
---|
117 | getargv0(), inflag ? "stdin" : "stdout"); |
---|
118 | } else |
---|
119 | fds = atoi(&name[1]); |
---|
120 | res = fdopen(fds, streq(mode, "w!") ? "w" : mode); |
---|
121 | if (res == NULL) |
---|
122 | error("stropen in %s: cannot open f.d. %d for %s\n", |
---|
123 | getargv0(), fds, inflag ? "input" : "output"); |
---|
124 | } else { |
---|
125 | if (streq(mode, "w") && stat(name, &buf) == 0) |
---|
126 | error("stropen in %s: file \"%s\" already exists\n", |
---|
127 | getargv0(), name); |
---|
128 | res = fopen(name, streq(mode, "w!") ? "w" : mode); |
---|
129 | if (res == NULL) |
---|
130 | error("stropen in %s: cannot open file \"%s\" for %s\n", |
---|
131 | getargv0(), name, inflag ? "input" : "output"); |
---|
132 | } |
---|
133 | return (res); |
---|
134 | } |
---|