miriad 4.1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/hio.h ADDED
@@ -0,0 +1,48 @@
1
+ #if !defined(MIR_HIO_H)
2
+ #define MIR_HIO_H
3
+
4
+ #include "sysdep.h"
5
+
6
+ /*
7
+ * magic numbers at the start of an item, these are like BITPIX in fits,
8
+ * so don't change them or your MIRIAD files won't be exchangeable between
9
+ * other MIRIAD implementations
10
+ * MAXTYPES is pretty arbitrary, just make sure it's at least the last H_<type>+1
11
+ *
12
+ */
13
+
14
+ #define H_BYTE 1
15
+ #define H_INT 2
16
+ #define H_INT2 3
17
+ #define H_REAL 4
18
+ #define H_DBLE 5
19
+ #define H_TXT 6
20
+ #define H_CMPLX 7
21
+ #define H_INT8 8
22
+
23
+ #define MAXTYPES 10
24
+
25
+ #define H_BYTE_SIZE 1
26
+ #define H_INT_SIZE 4
27
+ #define H_INT2_SIZE 2
28
+ #define H_INT8_SIZE 8
29
+ #define H_REAL_SIZE 4
30
+ #define H_DBLE_SIZE 8
31
+ #define H_TXT_SIZE 1
32
+ #define H_CMPLX_SIZE 8
33
+
34
+ #define MAXPATH 256
35
+ #define MAXOPEN 26
36
+
37
+
38
+ /* prototypes are now in miriad.h (mostly) and sysdep.h (pack routines) */
39
+
40
+ /* Other handy definitions. */
41
+
42
+ #define TRUE 1
43
+ #define FALSE 0
44
+ #define max(a,b) ((a)>(b)?(a):(b))
45
+ #define min(a,b) ((a)<(b)?(a):(b))
46
+ #define mroundup(a,b) ((b)*(((a)+(b)-1)/(b)))
47
+
48
+ #endif /* MIR_HIO_H */
data/ext/interface.c ADDED
@@ -0,0 +1,74 @@
1
+ /************************************************************************/
2
+ /* */
3
+ /* Subroutines to aid interfacing between C and FORTRAN. */
4
+ /* */
5
+ /* History: */
6
+ /* rjs ??????? Original version. */
7
+ /* rjs 23dec92 Broke out into separate file. */
8
+ /* rjs 05dec95 Comment out a dirty trick in zterm that was screwing */
9
+ /* up with some compilers!! */
10
+ /* pjt 17jun02 MIR4 prototypes */
11
+ /************************************************************************/
12
+
13
+ #include <string.h>
14
+
15
+ void pad(char *string,int length)
16
+ /*
17
+ This takes a zero-terminated string, and pads it with blanks up a certain
18
+ length.
19
+
20
+ Input:
21
+ length Length to pad to.
22
+ Input/Output:
23
+ string Output is the blank padded version of the input.
24
+ ------------------------------------------------------------------------*/
25
+ {
26
+ int len0,i;
27
+ char *s;
28
+
29
+ len0 = strlen(string);
30
+ s = string + len0;
31
+ for(i=len0; i < length; i++) *s++ = ' ';
32
+ }
33
+ /************************************************************************/
34
+ char *zterm(char *string,int length)
35
+ /*
36
+ This returns a pointer to a nul terminated string. This is usually
37
+ called to convert strings from a FORTRAN to C manner. Its algorithm
38
+ consists of firstly checking if the string is already null-terminated
39
+ (without trailing blanks). If so return the string address. Otherwise
40
+ trim back trailing blanks and copy the string (null terminating) to
41
+ a buffer. The buffer is a circular one, with no checks for "overflows".
42
+ Overflows are unlikely because the FORTRAN to C boundary is only
43
+ spanned at most once at any given moment.
44
+
45
+ Input:
46
+ string Points to the string of interest.
47
+ length The FORTRAN length of the string (may include blank padding).
48
+
49
+ Output:
50
+ zterm Pointer to null terminated string.
51
+ ------------------------------------------------------------------------*/
52
+ {
53
+ #define CIRBUFSIZE 2048
54
+ static char buffer[CIRBUFSIZE];
55
+ static int offset=0;
56
+
57
+ char *s;
58
+
59
+ /* Trim back over blanks, and check if its already null terminated. */
60
+ /* If its already null terminated, there is nothing to do. */
61
+
62
+ s = string + length;
63
+ while(*--s == ' ' && length)length--;
64
+ /* if(*(string+length) == 0)return(string); */
65
+
66
+ /* We have to put it in our circular buffer. Determine where to put it. */
67
+
68
+ if(offset + length + 1 > CIRBUFSIZE) offset = 0;
69
+ s = buffer + offset;
70
+ memcpy(s,string,length);
71
+ *(s+length) = 0;
72
+ offset += length + 1;
73
+ return(s);
74
+ }
data/ext/io.h ADDED
@@ -0,0 +1,56 @@
1
+ /************************************************************************/
2
+ /* */
3
+ /* A general header file for the various file and i/o handling */
4
+ /* routines. */
5
+ /* */
6
+ /* History: */
7
+ /* rjs Dark-ages Original version. */
8
+ /* rjs 20aug92 Correct "roundup" macro when rounding 0. */
9
+ /* rjs 15may96 Moved roundup macro elsewhere. */
10
+ /* pjt 28may02 Added H_INT8 */
11
+ /* pjt 17jun02 different MIR4 structures? */
12
+ /************************************************************************/
13
+
14
+ /* Binary items start with a sequence to allow routines to blindly determine
15
+ how to read them. The "binary_item" is a catch all with only indicates
16
+ that the data is binary valued, but does not hint at the format. */
17
+
18
+ #if !defined(MIR_IO_H)
19
+ #define MIR_IO_H
20
+
21
+ #include "hio.h"
22
+ #include <unistd.h>
23
+
24
+ #define ITEM_HDR_SIZE 4
25
+
26
+ #if 1
27
+
28
+ /* MIRIAD3 and below data structures */
29
+
30
+
31
+ static char binary_item[ITEM_HDR_SIZE] = {0,0,0,0},
32
+ real_item[ITEM_HDR_SIZE] = {0,0,0,H_REAL},
33
+ int_item[ITEM_HDR_SIZE] = {0,0,0,H_INT},
34
+ int2_item[ITEM_HDR_SIZE] = {0,0,0,H_INT2},
35
+ int8_item[ITEM_HDR_SIZE] = {0,0,0,H_INT8},
36
+ char_item[ITEM_HDR_SIZE] = {0,0,0,H_BYTE},
37
+ dble_item[ITEM_HDR_SIZE] = {0,0,0,H_DBLE},
38
+ cmplx_item[ITEM_HDR_SIZE] = {0,0,0,H_CMPLX};
39
+
40
+ #else
41
+
42
+ /* MIRIAD4 data structures - not finalized on this though */
43
+
44
+ static char binary_item[ITEM_HDR_SIZE] = {1,0,0,0},
45
+ real_item[ITEM_HDR_SIZE] = {1,0,0,H_REAL},
46
+ int_item[ITEM_HDR_SIZE] = {1,0,0,H_INT},
47
+ int2_item[ITEM_HDR_SIZE] = {1,0,0,H_INT2},
48
+ int8_item[ITEM_HDR_SIZE] = {1,0,0,H_INT8},
49
+ char_item[ITEM_HDR_SIZE] = {1,0,0,H_BYTE},
50
+ dble_item[ITEM_HDR_SIZE] = {1,0,0,H_DBLE},
51
+ cmplx_item[ITEM_HDR_SIZE] = {1,0,0,H_CMPLX};
52
+
53
+
54
+ #endif
55
+
56
+ #endif /* MIR_IO_H */
data/ext/key.c ADDED
@@ -0,0 +1,934 @@
1
+ /***********************************************************************
2
+ *
3
+ * Key routines provide keyword-oriented access to the command line.
4
+ *
5
+ * History:
6
+ * rjs 24apr91 Original version.
7
+ * jm 28jun94 Wrote the ANSI-C version.
8
+ * jm 01nov94 Added expand and local traits and added keyl().
9
+ * jm 17nov94 Rewrote #if definitions for ANSI prototypes. Sun
10
+ * machines define __STDC__ even when it is 0! This
11
+ * involved creating and using PROTOTYPE in sysdep.h.
12
+ * jm 24oct96 Increased MAXSTRING from 256 to 512 and fixed a
13
+ * few lint complaints.
14
+ * jm 01aug97 Changed getKeyValue to properly handle single and
15
+ * double quotes around a value.
16
+ * pjt 03sep98 fixed malloc(size+1) bug with interesting side-effects
17
+ * on linux and HP-UX
18
+ * pjt 5aug99 increased MAXSTRING to 1024 (also do keyf.f !!!)
19
+ * pjt 6mar01 increased MAXSTRING to 2048
20
+ * mchw 15mar02 increased MAXSTRING to 4096
21
+ * pjt 22jun02 MIR4 prototypes, also added a few more Const
22
+ * jwr 22jul04 changed a few vars from size_t to ssize_t, since signed
23
+ * arithmetic is required. Also made failure of wildcard
24
+ * expansion fatal (it would crash later if only a warning
25
+ * is given)
26
+ * pjt 13jul07 make unique messages in different pieces of code
27
+ ***********************************************************************
28
+ */
29
+
30
+ #include <stdio.h>
31
+ #include <stdlib.h>
32
+ #include <string.h>
33
+ #include <ctype.h>
34
+ #include <math.h>
35
+ #include "miriad.h"
36
+
37
+ #ifndef Null
38
+ #define Null '\0'
39
+ #endif
40
+
41
+ /* if you change MAXSTRING, also do keyf.for */
42
+ #define KEYTRUE 1
43
+ #define KEYFALSE 0
44
+ #define MAXSTRING 4096
45
+
46
+ typedef struct ckeys {
47
+ char *key; /* Pointer to a malloc'd string holding the key name. */
48
+ char *Pvalue; /* Pointer to a malloc'd string holding the value. */
49
+ char *value; /* Pointer to current spot in Pvalue. */
50
+ int isexpanded; /* False if not yet expanded; true otherwise. */
51
+ int islocal; /* True if defined locally; false if globally. */
52
+ struct ckeys *fwd; /* Pointer to next ckey structure. */
53
+ } KEYS;
54
+
55
+ static KEYS *KeyHead = (KEYS *)NULL;
56
+
57
+ /* This will be set to KEYTRUE only when keyini[_c]() is called. */
58
+ static int iniCalled = KEYFALSE;
59
+
60
+ /***********************************************************************/
61
+ static char *skipLeading(Const char *string)
62
+ {
63
+ char *ptr;
64
+
65
+ if (string == (Const char *)NULL)
66
+ return((char *)NULL);
67
+
68
+ for (ptr = (char *)string; ((*ptr != Null) && isspace(*ptr)); ptr++)
69
+ /* NULL */ ;
70
+
71
+ return(ptr);
72
+ }
73
+
74
+ /***********************************************************************/
75
+ static KEYS *getKey(Const char *key)
76
+ {
77
+ char *ptr;
78
+ KEYS *t;
79
+
80
+ /* First, check that the key routines have been initialized. */
81
+ if (iniCalled == KEYFALSE) {
82
+ (void)bug_c('f', "The Key initialization routine must be called first.");
83
+ }
84
+ /*
85
+ * Search for a key by name. If the key name is not found,
86
+ * return a NULL pointer. Otherwise, return a pointer to the
87
+ * private structure of the key.
88
+ */
89
+ if ((ptr = skipLeading(key)) == (char *)NULL)
90
+ return((KEYS *)NULL);
91
+
92
+ for (t = KeyHead; t != (KEYS *)NULL; t = t->fwd)
93
+ if (strcmp(ptr, t->key) == 0)
94
+ break;
95
+
96
+ return(t);
97
+ }
98
+
99
+ /***********************************************************************/
100
+ static char *getKeyValue(Const char *key, int doexpand)
101
+ {
102
+ char *r, *s;
103
+ char quoted;
104
+ char string[MAXSTRING];
105
+ int more;
106
+ ssize_t size, depth;
107
+ KEYS *t;
108
+ FILE *fp;
109
+
110
+ if ((t = getKey(key)) == (KEYS *)NULL)
111
+ return((char *)NULL);
112
+ if ((t->value == (char *)NULL) || (*(t->value) == Null))
113
+ return((char *)NULL);
114
+ /*
115
+ * At this point, there is a value to return. Scan through to
116
+ * the end of the parameter value.
117
+ */
118
+ r = s = skipLeading(t->value);
119
+ depth = 0;
120
+ more = KEYTRUE;
121
+ quoted = Null; /* Initially, not in a quoted string. */
122
+ while ((*s != Null) && (more == KEYTRUE)) {
123
+ if (quoted == Null) { /* Not currently within a quote. */
124
+ if ((*s == '"') || (*s == '\'')) {
125
+ quoted = *s; /* Set this to the char that ends the quote. */
126
+ } else {
127
+ if (*s == '(') depth++;
128
+ else if (*s == ')') depth--;
129
+ else if (isspace(*s) || (*s == ','))
130
+ more = (depth == 0) ? KEYFALSE : KEYTRUE;
131
+ }
132
+ } else if (*s == quoted) { /* Inside a quote; read till matched. */
133
+ quoted = Null; /* Reset this to mean not in a quote. */
134
+ }
135
+ if (more == KEYTRUE) s++;
136
+ }
137
+ t->value = (*s == Null) ? s : s + 1;
138
+ *s-- = Null; /* Subtract 1 from index for following test. */
139
+
140
+ /* Remove leading and trailing quotes. */
141
+ if ((*r != Null) && (s > r)) {
142
+ if (((*r == '"') && (*s == '"')) || ((*r == '\'') && (*s == '\''))) {
143
+ *s = Null;
144
+ r++;
145
+ }
146
+ }
147
+ /*
148
+ * If the value starts with a '@' character, then open the
149
+ * given file name and store each line as a comma separated list.
150
+ * Next, if there is anything left in the keyword value list,
151
+ * add it to the end of the newly generated list. Finally, re-call
152
+ * this routine to read the first parameter off the new list.
153
+ */
154
+ if (*r == '@') {
155
+ r++;
156
+ if ((fp = fopen(r, "r")) == (FILE *)NULL) {
157
+ (void)sprintf(string, "Error opening @ file [%s].", r);
158
+ (void)bug_c('f', string);
159
+ }
160
+
161
+ more = KEYTRUE;
162
+ while (fgets(string, MAXSTRING, fp) != (char *)NULL) {
163
+ if (((size = strlen(string)) > (size_t)0) && (string[size-1] == '\n'))
164
+ string[size-1] = Null;
165
+
166
+ r = skipLeading(string);
167
+ if ((r == (char *)NULL) || (*r == Null) || (*r == '#'))
168
+ continue;
169
+
170
+ if (more == KEYTRUE) {
171
+ depth = strlen(r) + 1;
172
+ if ((s = (char *)malloc(depth)) == (char *)NULL)
173
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
174
+ (void)strcpy(s, r);
175
+ more = KEYFALSE;
176
+ } else {
177
+ depth += strlen(r) + 2;
178
+ if ((s = (char *)realloc(s, depth)) == (char *)NULL)
179
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
180
+ (void)strcat(s, ",");
181
+ (void)strcat(s, r);
182
+ }
183
+ }
184
+
185
+ (void)fclose(fp);
186
+
187
+ if (depth == 0)
188
+ (void)bug_c('f', "Trouble processing the @ directive.");
189
+
190
+ if (*(t->value) != Null) {
191
+ depth += strlen(t->value) + 2;
192
+ if ((s = (char *)realloc(s, depth)) == (char *)NULL)
193
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
194
+ (void)strcat(s, ",");
195
+ (void)strcat(s, t->value);
196
+ }
197
+
198
+ (void)free((Void *)t->Pvalue);
199
+ t->value = t->Pvalue = s;
200
+ t->isexpanded = KEYTRUE;
201
+ r = getKeyValue(key, doexpand);
202
+ } else if ((doexpand == KEYTRUE) && (t->isexpanded == KEYFALSE)) {
203
+ /*
204
+ * Otherwise, if expansion is desired and the keyword has not
205
+ * yet been expanded, call the dio.c routine dexpand_c() to
206
+ * return the result of the system call to "echo r".
207
+ */
208
+ size = dexpand_c(r, string, MAXSTRING);
209
+ if (size < 1) {
210
+ (void)sprintf(string, "Error doing wildcard expansion of [%s].", r);
211
+ (void)bug_c('f', string);
212
+ } else {
213
+ if (*(t->value) != Null)
214
+ size += strlen(t->value) + 2;
215
+ if ((s = (char *)malloc(size+1)) == (char *)NULL)
216
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
217
+ (void)strcpy(s, string);
218
+ if (*(t->value) != Null) {
219
+ (void)strcat(s, ",");
220
+ (void)strcat(s, t->value);
221
+ }
222
+ (void)free((Void *)t->Pvalue);
223
+ t->value = t->Pvalue = s;
224
+ t->isexpanded = KEYTRUE;
225
+ }
226
+ r = getKeyValue(key, doexpand);
227
+ }
228
+
229
+ return((*r == Null) ? (char *)NULL : r);
230
+ }
231
+
232
+ /***********************************************************************/
233
+ void keyinit_c(Const char *task)
234
+ {
235
+ buglabel_c(task); /* Let the bug routines know the task name. */
236
+ iniCalled = KEYTRUE; /* Is True only when keyini[_c]() is called. */
237
+ }
238
+
239
+ /***********************************************************************/
240
+ void keyput_c(Const char *task, char *string)
241
+ /** KeyPut -- Store a keyword for later retrieval. */
242
+ /*& pjt */
243
+ /*: user-input,command-line */
244
+ /*+ FORTRAN call sequence:
245
+
246
+ subroutine keyput(task,value)
247
+ character task*(*),value*(*)
248
+
249
+ This task stores the keyword=value pair for later retrieval by the
250
+ other key routines. If the keyword has previously been saved prior
251
+ to calling this routine, then this version will only be saved if
252
+ (1) the previous was not defined locally (ie. task/keyword) or
253
+ (2) this reference is also a local reference.
254
+
255
+ If the keyword is locally defined (ie. task/keyword) but the task
256
+ name does not match the value of the input string task, then the
257
+ keyword is not (ever) saved.
258
+
259
+ NOTE: This is an internal routine that is only called by KeyIni.
260
+
261
+ Input:
262
+ task The name of the current task.
263
+ value The keyword=value pair.
264
+
265
+ Output:
266
+ (none)
267
+ */
268
+ /*--*/
269
+ /*---------------------------------------------------------------------*/
270
+ {
271
+ char *s, *key;
272
+ char *pequal, *pslash;
273
+ char errmsg[MAXSTRING];
274
+ int localkey;
275
+ KEYS *t;
276
+
277
+ if (iniCalled == KEYFALSE) {
278
+ (void)bug_c('f',
279
+ "The Key initialization routine must be called before calling KEYPUT.");
280
+ }
281
+
282
+ if (((s = skipLeading(string)) == (char *)NULL) || (*s == Null)) {
283
+ (void)sprintf(errmsg, "Badly formed parameter-1: [%s].", string);
284
+ (void)bug_c('w', errmsg);
285
+ return;
286
+ } else if (*s == '#') { /* Quietly return on comment lines. */
287
+ return;
288
+ }
289
+
290
+ key = s; /* Get the key name. */
291
+ while ((*s != Null) && (isalnum(*s) || (*s == '$')))
292
+ s++;
293
+ if (*s == Null) {
294
+ (void)sprintf(errmsg, "Badly formed parameter-2: [%s].", string);
295
+ (void)bug_c('w', errmsg);
296
+ return;
297
+ }
298
+ /*
299
+ * Search for the local keyword character (/). If it exists,
300
+ * it must appear before the equal sign with text that precedes
301
+ * and follows it. If the key is local, the key and value will
302
+ * be saved only if the task name matches the text before the
303
+ * local flag character.
304
+ */
305
+ localkey = KEYFALSE;
306
+ if (((pslash = strchr(s, '/')) != (char *)NULL) &&
307
+ ((pequal = strchr(s, '=')) != (char *)NULL) &&
308
+ (pslash < pequal)) {
309
+ *s = Null; /* Terminate the task name. */
310
+ if (strcmp(task, key) != 0) /* This keyword doesn't match task. */
311
+ return;
312
+ s = skipLeading(pslash+1); /* Skip blanks after the local char. */
313
+
314
+ localkey = KEYTRUE;
315
+ key = s; /* Now, get the real [local] key name. */
316
+ while ((*s != Null) && (isalnum(*s) || (*s == '$'))) s++;
317
+ if (*s == Null) {
318
+ (void)sprintf(errmsg, "Badly formed parameter-3: [%s].", string);
319
+ (void)bug_c('w', errmsg);
320
+ return;
321
+ }
322
+ }
323
+ *s++ = Null; /* Properly terminate the keyword. */
324
+
325
+ /* Now move to the value part of this keyword. */
326
+ while ((*s != Null) && (isspace(*s) || (*s == '=')))
327
+ s++;
328
+ if ((*s == Null) || (strlen(s) < (size_t)1)) {
329
+ (void)sprintf(errmsg, "Badly formed parameter-4: [%s=%s].", key, string);
330
+ (void)bug_c('w', errmsg);
331
+ return;
332
+ }
333
+ /*
334
+ * See if this keyword already exists. If not, then create it.
335
+ * If it exists and was not previously declared local, then
336
+ * this version will override the previous reference of the key.
337
+ * If this reference was previously defined locally then only
338
+ * another local reference will override it.
339
+ */
340
+ for (t = KeyHead; t != (KEYS *)NULL; t = t->fwd) {
341
+ if (strcmp(key, t->key) == 0)
342
+ break;
343
+ }
344
+
345
+ if (t == (KEYS *)NULL) {
346
+ if ((t = (KEYS *)malloc(sizeof(KEYS))) == (KEYS *)NULL)
347
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
348
+ if ((t->key = (char *)malloc(strlen(key) + 1)) == (char *)NULL)
349
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
350
+ (void)strcpy(t->key, key);
351
+ t->fwd = KeyHead;
352
+ KeyHead = t;
353
+ } else if ((localkey == KEYTRUE) || (t->islocal != KEYTRUE)) {
354
+ if (t->Pvalue != (char *)NULL)
355
+ (void)free((Void *)t->Pvalue);
356
+ } else {
357
+ return;
358
+ }
359
+
360
+ if ((t->Pvalue = (char *)malloc(strlen(s) + 1)) == (char *)NULL)
361
+ (void)bug_c('f', "Could not allocate memory in the key routines.");
362
+ (void)strcpy(t->Pvalue, s);
363
+ t->value = t->Pvalue;
364
+ t->isexpanded = KEYFALSE;
365
+ t->islocal = localkey;
366
+
367
+ return;
368
+ }
369
+
370
+ /***********************************************************************/
371
+ void keyini_c(int argc, char *argv[])
372
+ /** KeyIni_c -- Initialise the `key' routines (C version). */
373
+ /*& pjt */
374
+ /*: user-input, command-line */
375
+ /*+
376
+
377
+ void keyini_c(int argc, char *argv[])
378
+
379
+ Keyini_c performs some initial parsing of the command line breaking
380
+ it up into its keyword=value pairs. It also stores the name of
381
+ the program (which is currently only used by the bug routines).
382
+
383
+ NOTE: This has a different calling sequence than the Fortran
384
+ version.
385
+ */
386
+ /*--*/
387
+ /*---------------------------------------------------------------------*/
388
+ {
389
+ char *task;
390
+ char string[MAXSTRING];
391
+ register int i;
392
+ size_t size;
393
+ FILE *fp;
394
+ /*
395
+ * Get the program name, and tell the bug routines what it
396
+ * really is. Then strip off any leading path characters
397
+ * so only the task name remains.
398
+ */
399
+ keyinit_c(argv[0]);
400
+ task = argv[0] + strlen(argv[0]) - 1;
401
+ while ((task > argv[0]) && (strchr("]/", task[-1]) == (char *)NULL))
402
+ task--;
403
+
404
+ for (i = 1; i < argc; i++) {
405
+ if (strcmp("-f", argv[i]) == 0) { /* Read args from a file. */
406
+ if (++i >= argc)
407
+ (void)bug_c('f', "KeyIni: No parameter file given for -f option.");
408
+
409
+ if ((fp = fopen(argv[i], "r")) == (FILE *)NULL) {
410
+ (void)sprintf(string,
411
+ "KeyIni: Failed to open the parameter file [%s].", argv[i]);
412
+ (void)bug_c('f', string);
413
+ }
414
+
415
+ while (fgets(string, MAXSTRING, fp) != (char *)NULL) {
416
+ if (((size = strlen(string)) > (size_t)0) && (string[size-1] == '\n'))
417
+ string[size-1] = Null;
418
+ keyput_c(task, string);
419
+ }
420
+
421
+ (void)fclose(fp);
422
+ } else if (strcmp("-?", argv[i]) == 0) { /* Give help. */
423
+ (void)sprintf(string, "mirhelp %s", task);
424
+ (void)system(string);
425
+ (void)exit(0);
426
+ } else if (strcmp("-k", argv[i]) == 0) { /* List the keywords. */
427
+ (void)sprintf(string, "doc %s", task);
428
+ (void)system(string);
429
+ (void)exit(0);
430
+ } else if (argv[i][0] == '-') { /* Others not understood yet. */
431
+ (void)sprintf(string, "KeyIni: Flag [%s] not understood.", argv[i]);
432
+ (void)bug_c('w', string);
433
+ } else { /* Otherwise, the argument is a parameter. */
434
+ keyput_c(task, argv[i]);
435
+ }
436
+ }
437
+ return;
438
+ }
439
+
440
+ /***********************************************************************/
441
+ void keyfin_c(void)
442
+ /** KeyFin -- Finish access to the 'key' routines. */
443
+ /*& pjt */
444
+ /*: user-input,command-line */
445
+ /*+ FORTRAN call sequence:
446
+
447
+ subroutine keyfin
448
+
449
+ A call to KeyFin indicates that all of the parameters that the
450
+ program wants have been retrieved from the command line. KeyFin
451
+ makes sure all command line parameters have been read.
452
+ */
453
+ /*--*/
454
+ /*---------------------------------------------------------------------*/
455
+ {
456
+ char errmsg[MAXSTRING];
457
+ KEYS *t, *next;
458
+
459
+ if (iniCalled == KEYFALSE) {
460
+ (void)bug_c('f',
461
+ "The Key initialization routine must be called before calling KEYFIN.");
462
+ }
463
+
464
+ next = (KEYS *)NULL;
465
+ for (t = KeyHead; t != (KEYS *)NULL; t = next) {
466
+ next = t->fwd;
467
+ if ((t->value != (char *)NULL) && (*(t->value) != Null)) {
468
+ (void)sprintf(errmsg, "Keyword [%s] not used or not exhausted.",
469
+ t->key);
470
+ (void)bug_c('w', errmsg);
471
+ }
472
+
473
+ if (t->Pvalue != (char *)NULL)
474
+ (void)free((Void *)t->Pvalue);
475
+ if (t->key != (char *)NULL)
476
+ (void)free((Void *)t->key);
477
+ (void)free((Void *)t);
478
+ }
479
+
480
+ KeyHead = (KEYS *)NULL;
481
+ iniCalled = KEYFALSE;
482
+ return;
483
+ }
484
+
485
+ /***********************************************************************/
486
+ /* Returns FORT_TRUE if keyword is present; FORT_FALSE otherwise. */
487
+ int keyprsnt_c(Const char *keyword)
488
+ /** KeyPrsnt -- Determine if a keyword is present on the command line. */
489
+ /*& pjt */
490
+ /*: user-input,command-line */
491
+ /*+ FORTRAN call sequence:
492
+
493
+ logical function keyprsnt(key)
494
+ character key*(*)
495
+
496
+ Determine if a parameter is still present.
497
+
498
+ Input:
499
+ key The keyword to check.
500
+
501
+ Output:
502
+ keyprsnt Is .TRUE. if the keyword is present; .FALSE. otherwise.
503
+ */
504
+ /*--*/
505
+ /*---------------------------------------------------------------------*/
506
+ {
507
+ int isPresent;
508
+ KEYS *t;
509
+
510
+ t = getKey(keyword);
511
+ isPresent = ((t != (KEYS *)NULL) &&
512
+ (t->value != (char *)NULL) &&
513
+ (*(t->value) != Null)) ? FORT_TRUE : FORT_FALSE;
514
+
515
+ return(isPresent);
516
+ }
517
+
518
+ /***********************************************************************/
519
+ void keya_c(Const char *keyword, char *value, Const char *keydef)
520
+ /** Keya -- Retrieve a character string from the command line. */
521
+ /*& pjt */
522
+ /*: user-input,command-line */
523
+ /*+ FORTRAN call sequence:
524
+
525
+ subroutine keya(key,value,default)
526
+ character key*(*)
527
+ character value*(*),default*(*)
528
+
529
+ Retrieve a character string from the command line. If the keyword
530
+ is not found, the default is returned.
531
+
532
+ Input:
533
+ key The name of the keyword to return.
534
+ default The default value to return if the keyword is not
535
+ present on the command line.
536
+ Output:
537
+ value The returned value.
538
+ */
539
+ /*--*/
540
+ /*---------------------------------------------------------------------*/
541
+ {
542
+ char *s;
543
+
544
+ s = getKeyValue(keyword, KEYFALSE);
545
+ (void)strcpy(value, ((s == (char *)NULL) ? keydef : s));
546
+ return;
547
+ }
548
+
549
+ /***********************************************************************/
550
+ void keyf_c(Const char *keyword, char *value, Const char *keydef)
551
+ /** Keyf -- Retrieve a file name (with wildcards) from the command line. */
552
+ /*& pjt */
553
+ /*: user-input,command-line */
554
+ /*+ FORTRAN call sequence:
555
+
556
+ subroutine keyf(key,value,default)
557
+ character key*(*)
558
+ character value*(*),default*(*)
559
+
560
+ Retrieve a character string from the command line. If the keyword
561
+ is not found, the default is returned.
562
+
563
+ Input:
564
+ key The name of the keyword to return.
565
+ default The default value to return if the keyword is not
566
+ present on the command line.
567
+ Output:
568
+ value The returned value.
569
+ */
570
+ /*--*/
571
+ /*---------------------------------------------------------------------*/
572
+ {
573
+ char *s;
574
+
575
+ /* Expand any wildcards and match them with files. */
576
+ s = getKeyValue(keyword, KEYTRUE);
577
+ (void)strcpy(value, ((s == (char *)NULL) ? keydef : s));
578
+ return;
579
+ }
580
+
581
+ /***********************************************************************/
582
+ void keyd_c(Const char *keyword, double *value, Const double keydef)
583
+ /** Keyd -- Retrieve a double precision from the command line. */
584
+ /*& pjt */
585
+ /*: user-input,command-line */
586
+ /*+ FORTRAN call sequence:
587
+
588
+ subroutine keyd(key,value,default)
589
+ character key*(*)
590
+ double precision value,default
591
+
592
+ Retrieve a double precision value from the command line. If the
593
+ keyword is not found, the default is returned.
594
+
595
+ Input:
596
+ key The name of the keyword to return.
597
+ default The default value to return, if the keyword is not
598
+ present on the command line.
599
+ Output:
600
+ value The returned value.
601
+ */
602
+ /*--*/
603
+ /*---------------------------------------------------------------------*/
604
+ {
605
+ char *s, *ptr;
606
+ char errmsg[MAXSTRING];
607
+
608
+ *value = keydef;
609
+ if ((s = getKeyValue(keyword, KEYFALSE)) == (char *)NULL)
610
+ return;
611
+
612
+ ptr = (char *)NULL;
613
+ *value = strtod(s, &ptr);
614
+ if (s == ptr) {
615
+ (void)sprintf(errmsg,
616
+ "KeyD: Conversion error decoding parameter [%s=%s].", keyword, s);
617
+ (void)bug_c('f', errmsg);
618
+ }
619
+
620
+ return;
621
+ }
622
+
623
+ /***********************************************************************/
624
+ void keyr_c(Const char *keyword, float *value, Const float keydef)
625
+ /** Keyr -- Retrieve a real value from the command line. */
626
+ /*& pjt */
627
+ /*: user-input,command-line */
628
+ /*+ FORTRAN call sequence:
629
+
630
+ subroutine keyr(key,value,default)
631
+ character key*(*)
632
+ real value,default
633
+
634
+ Retrieve a real value from the command line. If the keyword is
635
+ not found, the default is returned.
636
+
637
+ Input:
638
+ key The name of the keyword to return.
639
+ default The default value to return, if the keyword is not
640
+ present on the command line.
641
+ Output:
642
+ value The returned value.
643
+ */
644
+ /*--*/
645
+ /*---------------------------------------------------------------------*/
646
+ {
647
+ double retval, defval;
648
+
649
+ defval = keydef;
650
+ keyd_c(keyword, &retval, defval);
651
+ *value = retval;
652
+ return;
653
+ }
654
+
655
+ /***********************************************************************/
656
+ void keyi_c(Const char *keyword, int *value, Const int keydef)
657
+ /** Keyi -- Retrieve an integer from the command line. */
658
+ /*& pjt */
659
+ /*: user-input,command-line */
660
+ /*+ FORTRAN call sequence:
661
+
662
+ subroutine keyi(key,value,default)
663
+ character key*(*)
664
+ integer value,default
665
+
666
+ Retrieve an integer from the command line. If the keyword is
667
+ not found, the default is returned. The integer can be input
668
+ as a hexadecimal, octal or decimal number using a prefix 0x, %x
669
+ or h for hex; o or %o for octal; and +, - or nothing for decimal.
670
+
671
+ Input:
672
+ key The name of the keyword to return.
673
+ default The default value to return, if the keyword is not
674
+ present on the command line.
675
+ Output:
676
+ value The returned value.
677
+ */
678
+ /*--*/
679
+ /*---------------------------------------------------------------------*/
680
+ {
681
+ char *s, *ptr;
682
+ char temp[MAXSTRING];
683
+ int iarg, dummy;
684
+ double dval;
685
+
686
+ *value = keydef;
687
+ if ((s = getKeyValue(keyword, KEYFALSE)) == (char *)NULL)
688
+ return;
689
+ /*
690
+ * This business is done instead of a call to strtol because
691
+ * hexadecimal and octal are also acceptable integer inputs.
692
+ */
693
+ (void)sprintf(temp, "%s~~1", s);
694
+ if ((sscanf(temp, "%i~~%d", &iarg, &dummy) == 2) && (dummy == 1)) {
695
+ *value = iarg; /* Token was just a simple integer. */
696
+ return;
697
+ }
698
+
699
+ /* Number is floating point; find it and then take nint(). */
700
+ ptr = (char *)NULL;
701
+ dval = strtod(s, &ptr);
702
+ if (s == ptr) {
703
+ (void)sprintf(temp,
704
+ "KeyI: Conversion error decoding parameter [%s=%s].", keyword, s);
705
+ (void)bug_c('f', temp);
706
+ }
707
+ *value = (dval >= 0) ? floor(dval + 0.5) : ceil(dval - 0.5);
708
+
709
+ return;
710
+ }
711
+
712
+ /***********************************************************************/
713
+ void keyl_c(Const char *keyword, int *value, Const int keydef)
714
+ /** keyl -- Retrieve a logical value from the command line. */
715
+ /*& pjt */
716
+ /*: user-input,command-line */
717
+ /*+ FORTRAN call sequence:
718
+
719
+ subroutine keyl(key,value,default)
720
+ character key*(*)
721
+ logical value,default
722
+
723
+ Retrieve a logical value from the command line. If the keyword is
724
+ not found, the default is returned. It associates (case
725
+ insensitive) words starting with 'y', 't' and '1' as .TRUE. and
726
+ words starting with 'n', 'f' and '0' as .FALSE. Values of .TRUE.
727
+ and .FALSE. are also detected... both with minimum match.
728
+
729
+ Input:
730
+ key The name of the keyword to return.
731
+ default The default value to return, if the keyword is not
732
+ present on the command line.
733
+ Output:
734
+ value The returned value.
735
+ */
736
+ /*--*/
737
+ /*---------------------------------------------------------------------*/
738
+ {
739
+ char string[MAXSTRING];
740
+ char errmsg[MAXSTRING];
741
+ int state;
742
+
743
+ if (keydef == FORT_FALSE) {
744
+ keya_c(keyword, string, "f");
745
+ state = KEYFALSE;
746
+ } else {
747
+ keya_c(keyword, string, "t");
748
+ state = KEYTRUE;
749
+ }
750
+
751
+ (void)sprintf(errmsg, "KeyL: invalid value for a logical: [%s].", string);
752
+ switch ((int)string[0]) {
753
+ case 'f': case 'F': case 'n': case 'N': case '0':
754
+ state = KEYFALSE;
755
+ break;
756
+ case 't': case 'T': case 'y': case 'Y': case '1':
757
+ state = KEYTRUE;
758
+ break;
759
+ case '.':
760
+ switch ((int)string[1]) {
761
+ case 'f': case 'F':
762
+ state = KEYFALSE;
763
+ break;
764
+ case 't': case 'T':
765
+ state = KEYTRUE;
766
+ break;
767
+ default:
768
+ (void)bug_c('w', errmsg);
769
+ break;
770
+ }
771
+ break;
772
+ default:
773
+ (void)bug_c('w', errmsg);
774
+ break;
775
+ }
776
+
777
+ *value = (state == KEYTRUE) ? FORT_TRUE : FORT_FALSE;
778
+ return;
779
+ }
780
+
781
+ /***********************************************************************/
782
+ /*
783
+ * The following macro is used by all of the subsequent multi-get
784
+ * routines. It assumes that:
785
+ *
786
+ * Const char *keyword is the name of the key to retrieve;
787
+ * T value[] is the array to receive each returned value;
788
+ * int nmax is the maximum number of items to get; and
789
+ * int *n is the number of items returned;
790
+ *
791
+ * where T is the type of the variable (char *, double, float, or int).
792
+ *
793
+ * In the macro below,
794
+ * task is the name of the individual item retrieval task;
795
+ * defval is the default value to be used if the keyword is missing; and
796
+ * name is a string representing the task name (to be used in
797
+ * an error message.
798
+ *
799
+ * The do {} while (1==0) construct is done so that the macro may
800
+ * be called like a regular subroutine.
801
+ */
802
+ #define MULTIGET(task,defval,name) \
803
+ do { \
804
+ char errmsg[MAXSTRING]; \
805
+ register int count = 0; \
806
+ \
807
+ while ((count < nmax) && (keyprsnt_c(keyword) == FORT_TRUE)) \
808
+ task(keyword, &value[count++], defval); \
809
+ \
810
+ if (keyprsnt_c(keyword) == FORT_TRUE) { \
811
+ (void)sprintf(errmsg, "%s: Buffer overflow for keyword [%s].", \
812
+ name, keyword); \
813
+ (void)bug_c('f', errmsg); \
814
+ } \
815
+ \
816
+ *n = count; \
817
+ } while (1==0)
818
+
819
+ /***********************************************************************/
820
+ void mkeyd_c(Const char *keyword, double value[], Const int nmax, int *n)
821
+ /** MKeyd -- Retrieve multiple double values from the command line. */
822
+ /*& pjt */
823
+ /*: user-input,command-line */
824
+ /*+ FORTRAN call sequence:
825
+
826
+ subroutine mkeyd(key,value,nmax,n)
827
+ integer nmax, n
828
+ character key*(*)
829
+ double precision value(nmax)
830
+
831
+ Retrieve multiple double precision values from the command line.
832
+ If the keyword is not found, then zero values are returned.
833
+
834
+ Input:
835
+ key The name of the keyword to return.
836
+ nmax The maximum number of values to return
837
+
838
+ Output:
839
+ n The number of values returned.
840
+ value The returned values
841
+ */
842
+ /*--*/
843
+ /*---------------------------------------------------------------------*/
844
+ {
845
+ MULTIGET(keyd_c, 0.0, "MKeyD");
846
+ return;
847
+ }
848
+
849
+ /***********************************************************************/
850
+ void mkeyr_c(Const char *keyword, float value[], Const int nmax, int *n)
851
+ /** MKeyr -- Retrieve multiple real values from the command line. */
852
+ /*& pjt */
853
+ /*: user-input,command-line */
854
+ /*+ FORTRAN call sequence:
855
+
856
+ subroutine mkeyr(key,value,nmax,n)
857
+ integer nmax, n
858
+ character key*(*)
859
+ real value(nmax)
860
+
861
+ Retrieve multiple real values from the command line. If the keyword
862
+ is not found, then zero values are returned.
863
+
864
+ Input:
865
+ key The name of the keyword to return.
866
+ nmax The maximum number of values to return
867
+
868
+ Output:
869
+ n The number of values returned.
870
+ value The returned values
871
+ */
872
+ /*--*/
873
+ /*---------------------------------------------------------------------*/
874
+ {
875
+ MULTIGET(keyr_c, 0.0, "MKeyR");
876
+ return;
877
+ }
878
+
879
+ /***********************************************************************/
880
+ void mkeyi_c(Const char *keyword, int value[], Const int nmax, int *n)
881
+ /** MKeyi -- Retrieve multiple integer values from the command line. */
882
+ /*& pjt */
883
+ /*: user-input,command-line */
884
+ /*+ FORTRAN call sequence:
885
+
886
+ subroutine mkeyi(key,value,nmax,n)
887
+ integer nmax, n
888
+ character key*(*)
889
+ integer value(nmax)
890
+
891
+ Retrieve multiple integer values from the command line. If the
892
+ keyword is not found, then zero values are returned.
893
+
894
+ Input:
895
+ key The name of the keyword to return.
896
+ nmax The maximum number of values to return
897
+
898
+ Output:
899
+ n The number of values returned.
900
+ value The returned values
901
+ */
902
+ /*--*/
903
+ /*---------------------------------------------------------------------*/
904
+ {
905
+ MULTIGET(keyi_c, 0, "MKeyI");
906
+ return;
907
+ }
908
+
909
+ #ifdef TESTBED
910
+ /***********************************************************************/
911
+ int main(int argc, char *argv[])
912
+ {
913
+ char aval[100];
914
+ register int i;
915
+ int ival;
916
+ float fval;
917
+ double cnt[5];
918
+
919
+ keyini_c(argc, argv);
920
+ mkeyd_c("cnt", cnt, 5, &ival);
921
+ for (i = 0; i < ival; i++)
922
+ (void)printf("cnt[%d] = %g\n", i+1, cnt[i]);
923
+ for (i = 0; i < 5; i++) {
924
+ keyi_c("alpha", &ival, 100);
925
+ (void)printf("Alpha[100] = %d ", ival);
926
+ keya_c("beta", aval, "def-val");
927
+ (void)printf("Beta[def-val] = %s ", aval);
928
+ keyr_c("gamma", &fval, 10.0);
929
+ (void)printf("Gamma[10.0] = %g\n", fval);
930
+ }
931
+ keyfin_c();
932
+ (void)exit(0);
933
+ }
934
+ #endif