1 /*$Id$*/
2 #include <stdio.h>
3 #include <string.h>
4 #include "rtdb.h"
5 #include "macdecls.h"
6 #ifdef CRAY
7 #include <fortran.h>
8 #endif
9 #define FATR
10 #define MXLGTH 32768
11 
12 #define FORTRAN_TRUE  ((Logical) 1)
13 #define FORTRAN_FALSE ((Logical) 0)
14 
15 
16 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
fortchar_to_string(_fcd f,int flen,char * buf,const int buflen)17 int fortchar_to_string(_fcd f, int flen, char *buf, const int buflen)
18 #else
19 int fortchar_to_string(const char *f, int flen, char *buf, const int buflen)
20 #endif
21 {
22 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
23   char *fstring;
24     fstring = _fcdtocp(f);
25     flen = _fcdlen(f);
26 
27   while (flen-- && fstring[flen] == ' ')
28     ;
29 
30   if (flen < 0) flen=0;		/* Empty strings break use of strtok
31 				   since consecutive separators are
32 				   treated as one */
33   if ((flen+1) >= buflen)
34     return 0;			/* Won't fit */
35 
36   flen++;
37   buf[flen] = 0;
38   while(flen--)
39     buf[flen] = fstring[flen];
40 #else
41   while (flen-- && f[flen] == ' ')
42     ;
43 
44   if (flen < 0) flen=0;		/* Empty strings break use of strtok
45 				   since consecutive separators are
46 				   treated as one */
47   if ((flen+1) >= buflen)
48     return 0;			/* Won't fit */
49 
50   flen++;
51   buf[flen] = 0;
52   while(flen--)
53     buf[flen] = f[flen];
54 #endif
55 
56   return 1;
57 }
58 
59 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
string_to_fortchar(_fcd f,int flen,char * buf)60 int string_to_fortchar(_fcd f, int flen, char *buf)
61 #else
62 int string_to_fortchar(char *f, int flen, char *buf)
63 #endif
64 {
65   int len = (int) strlen(buf), i;
66 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
67   flen = _fcdlen(f);
68 #endif
69 
70   if (len > flen) {
71     return 0;			/* Won't fit */
72 }
73 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
74   for (i=0; i<len; i++)
75     _fcdtocp(f)[i] = buf[i];
76   for (i=len; i<flen; i++)
77     _fcdtocp(f)[i] = ' ';
78 #else
79   for (i=0; i<len; i++)
80     f[i] = buf[i];
81   for (i=len; i<flen; i++)
82     f[i] = ' ';
83 #endif
84   return 1;
85 }
86 
87 
rtdb_parallel_(const Logical * mode)88 Logical FATR rtdb_parallel_(const Logical *mode)
89 {
90   /* This causes problems on machines where true != 1 (i.e. intel)
91    * so it is better just to pass what we are given
92    *
93    * int new = (*mode == FORTRAN_TRUE);
94    */
95   int new = *mode;
96   int old = rtdb_parallel(new);
97 
98   if (old)
99     return FORTRAN_TRUE;
100   else
101     return FORTRAN_FALSE;
102 }
103 
104 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
rtdb_open_(_fcd filename,_fcd mode,Integer * handle)105 Logical FATR rtdb_open_(_fcd filename, _fcd mode, Integer *handle)
106 {
107   int flen = _fcdlen(filename);
108   int mlen = _fcdlen(mode);
109 #else
110 Logical FATR rtdb_open_(const char *filename, const char *mode, Integer *handle,
111 		   const Integer flen, const Integer mlen)
112 {
113 #endif
114   char fbuf[256], mbuf[256];
115   int hbuf;
116 
117   if (!fortchar_to_string(filename, flen, fbuf, sizeof(fbuf))) {
118     (void) fprintf(stderr, "rtdb_open: fbuf is too small, need=%d\n",
119 		   (int) flen);
120     return FORTRAN_FALSE;
121   }
122 
123   if (!fortchar_to_string(mode, mlen, mbuf, sizeof(mbuf))) {
124     (void) fprintf(stderr, "rtdb_open: mbuf is too small, need=%d\n",
125 		   (int) mlen);
126     return FORTRAN_FALSE;
127   }
128 
129   if (rtdb_open(fbuf, mbuf, &hbuf)) {
130     *handle = (Integer) hbuf;
131     return FORTRAN_TRUE;
132   }
133   else {
134     return FORTRAN_FALSE;
135   }
136 }
137 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
138 Logical FATR rtdb_clone_(const Integer *handle, _fcd suffix)
139 {
140   int mlen = _fcdlen(suffix);
141 #else
142 Logical FATR rtdb_clone_(const Integer *handle, const char *suffix, const int mlen)
143 {
144 #endif
145   char mbuf[256];
146   int hbuf = (int) *handle;
147 
148   if (!fortchar_to_string(suffix, mlen, mbuf, sizeof(mbuf))) {
149     (void) fprintf(stderr, "rtdb_clone: mbuf is too small, need=%d\n", mlen);
150     return FORTRAN_FALSE;
151   }
152  if (rtdb_clone(hbuf, mbuf))
153     return FORTRAN_TRUE;
154  else
155     return FORTRAN_FALSE;
156 }
157 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
158 Logical FATR rtdb_getfname_(const Integer *handle, _fcd fname)
159 {
160   int mlen = _fcdlen(fname);
161 #else
162 Logical FATR rtdb_getfname_(const Integer *handle, char *fname, const int mlen)
163 {
164 #endif
165   char mbuf[256];
166   int hbuf = (int) *handle;
167 
168   if (rtdb_getfname(hbuf, mbuf)){
169     if (!string_to_fortchar(fname, mlen, mbuf)) {
170       (void) fprintf(stderr, "rtdb_fname: mbuf is too small, need=%ld\n",strlen(mbuf));
171       return FORTRAN_FALSE;
172     }
173     return FORTRAN_TRUE;
174   }
175  else
176     return FORTRAN_FALSE;
177 }
178 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
179 Logical FATR rtdb_close_(const Integer *handle, _fcd mode)
180 {
181   int mlen = _fcdlen(mode);
182 #else
183 Logical FATR rtdb_close_(const Integer *handle, const char *mode, const int mlen)
184 {
185 #endif
186   char mbuf[256];
187   int hbuf = (int) *handle;
188 
189   if (!fortchar_to_string(mode, mlen, mbuf, sizeof(mbuf))) {
190     (void) fprintf(stderr, "rtdb_close: mbuf is too small, need=%d\n", mlen);
191     return FORTRAN_FALSE;
192   }
193  if (rtdb_close(hbuf, mbuf))
194     return FORTRAN_TRUE;
195  else
196     return FORTRAN_FALSE;
197 }
198 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
199 Logical FATR rtdb_get_info_(const Integer *handle, _fcd name,
200 		       Integer *ma_type, Integer *nelem, _fcd date)
201 {
202     int nlen = _fcdlen(name);
203     int dlen = _fcdlen(date);
204 #else
205 Logical FATR rtdb_get_info_(const Integer *handle, const char *name,
206 		       Integer *ma_type, Integer *nelem, char *date,
207 		       const int nlen, const int dlen)
208 {
209 #endif
210 
211   int hbuf = (int) *handle;
212   char dbuf[26], nbuf[256];
213   int nelbuf, typebuf;
214 
215   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
216     (void) fprintf(stderr, "rtdb_get_info: nbuf is too small, need=%d\n",
217 		   nlen);
218     return FORTRAN_FALSE;
219   }
220 
221   if (dlen < 24) {
222     (void) fprintf(stderr, "rtdb_get_info: date must be > character*24\n");
223     return FORTRAN_FALSE;
224   }
225 
226   if (rtdb_get_info(hbuf, nbuf, &typebuf, &nelbuf, dbuf)) {
227     *ma_type = (Integer) typebuf;
228     *nelem   = (Integer) nelbuf;
229 
230     if (typebuf == MT_CHAR)	/* Fortran is ignorant of trailing null char */
231       *nelem = *nelem - 1;
232 
233     if (!string_to_fortchar(date, dlen, dbuf)) {
234       (void) fprintf(stderr, "rtdb_get_info: nbuf is too small, need=%d\n",
235 		     nlen);
236       return FORTRAN_FALSE;
237     }
238 
239     return FORTRAN_TRUE;
240   }
241   else {
242     return FORTRAN_FALSE;
243   }
244 }
245 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
246 Logical FATR rtdb_put_(const Integer *handle, _fcd name, const Integer *ma_type,
247 		  const Integer *nelem, const void *array)
248 {
249     int nlen = _fcdlen(name);
250 #else
251 Logical FATR rtdb_put_(const Integer *handle, const char *name, const Integer *ma_type,
252 		  const Integer *nelem, const void *array, const int nlen)
253 {
254 #endif
255   int hbuf = (int) *handle;
256   char nbuf[256];
257   int nelbuf;
258   int typebuf;
259 
260   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
261     (void) fprintf(stderr, "rtdb_put: nbuf is too small, need=%d\n",
262 		   nlen);
263     return FORTRAN_FALSE;
264   }
265 
266   nelbuf = (int) *nelem;
267   typebuf= (int) *ma_type;
268 
269 #ifdef DEBUG
270   printf("put: rtdb=%d, mat=%d, nel=%d, name=%s\n", hbuf, typebuf, nelbuf, nbuf);
271   fflush(stdout);
272 #endif
273 
274   if (rtdb_put(hbuf, nbuf, typebuf, nelbuf, array))
275     return FORTRAN_TRUE;
276   else
277     return FORTRAN_FALSE;
278 }
279 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
280 Logical FATR rtdb_get_(const Integer *handle, _fcd name,
281 		  const Integer *ma_type, const Integer *nelem,
282 		  void *array)
283 {
284     int nlen = _fcdlen(name);
285 #else
286 Logical FATR rtdb_get_(const Integer *handle, const char *name,
287 		  const Integer *ma_type, const Integer *nelem,
288 		  void *array, const int nlen)
289 {
290 #endif
291   int hbuf = (int) *handle;
292   char nbuf[256];
293   int nelbuf;
294   int typebuf;
295 
296   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
297     (void) fprintf(stderr, "rtdb_get: nbuf is too small, need=%d\n",
298 		   nlen);
299     return FORTRAN_FALSE;
300   }
301 
302   nelbuf = (int) *nelem;
303   typebuf= (int) *ma_type;
304 
305 #ifdef DEBUG
306   printf("get: rtdb=%d, mat=%d, nel=%d, name=%s\n", hbuf, typebuf, nelbuf, nbuf);
307   fflush(stdout);
308 #endif
309 
310   if (rtdb_get(hbuf, nbuf, typebuf, nelbuf, array)) {
311     return FORTRAN_TRUE;
312   }
313   else
314     return FORTRAN_FALSE;
315 }
316 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
317 Logical FATR rtdb_ma_get_(const Integer *handle, _fcd name, Integer *ma_type,
318 		     Integer *nelem, Integer *ma_handle)
319 {
320     int nlen = _fcdlen(name);
321 #else
322 Logical FATR rtdb_ma_get_(const Integer *handle, const char *name, Integer *ma_type,
323 		     Integer *nelem, Integer *ma_handle, const int nlen)
324 {
325 #endif
326   int hbuf = (int) *handle;
327   char nbuf[256];
328   int nelbuf;
329   int typebuf;
330   int handbuf;
331 
332   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
333     (void) fprintf(stderr, "rtdb_ma_get: nbuf is too small, need=%d\n",
334 		   nlen);
335     return FORTRAN_FALSE;
336   }
337 
338   if (rtdb_ma_get(hbuf, nbuf, &typebuf, &nelbuf, &handbuf)) {
339     *ma_type   = (Integer) typebuf;
340     *ma_handle = (Integer) handbuf;
341     *nelem     = (Integer) nelbuf;
342 
343     return FORTRAN_TRUE;
344   }
345   else
346     return FORTRAN_FALSE;
347 }
348 
349 Logical FATR rtdb_print_(const Integer *handle, const Logical *print_values)
350 {
351   int hbuf = (int) *handle;
352   int pbuf = (int) *print_values;
353 
354   if (rtdb_print(hbuf, pbuf))
355     return FORTRAN_TRUE;
356   else
357     return FORTRAN_FALSE;
358 }
359 
360 /**
361 \ingroup rtdb
362 @{
363 */
364 
365 /**
366   \brief Store a character string on the RTDB
367 
368   This function is supposed to be called from a Fortran code.
369 
370   \param handle [Input] the RTDB handle
371   \param name   [Input] the key
372   \param nelem  [Input] the length of the character buffer
373   \param array  [Input] the value of the string
374 
375   \return Return FORTRAN_TRUE if successfull, and FORTRAN_FALSE otherwise.
376 */
377 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
378 Logical FATR rtdb_cput_(const Integer *handle, _fcd name,
379 		   const Integer *nelem,
380 		   _fcd farray)
381 {
382     int nlen = _fcdlen(name);
383     int alen = _fcdlen(farray);
384     char *array = _fcdtocp(farray);
385 #else
386 Logical FATR rtdb_cput_(const Integer *handle, const char *name,
387 		   const Integer *nelem,
388 		   const char *array, const int nlen, const int alen)
389 {
390 #endif
391 /*
392   Insert an array of Fortran character variables into the data base.
393   Each array element is striped of trailing blanks, terminated with CR,
394   and appended to the list. The entire array must fit into abuf.
395 */
396 
397   int hbuf = (int) *handle;
398   char nbuf[256];
399   char abuf[MXLGTH]=" ";
400   int nelbuf;
401   int typebuf;
402   int i, left;
403   char *next;
404 
405   for (i=0, left=sizeof(abuf), next=abuf;
406        i<*nelem;
407        i++, array+=alen) {
408 #if defined(CRAY) && !defined(__crayx1)
409       _fcd element = _cptofcd(array, alen);
410 #elif defined(WIN32) &&! defined(__MINGW32__)
411       _fcd element;
412       element.string = array;
413       element.len = alen;
414 #elif defined(USE_FCD)
415 #error Do something about _fcd
416 #else
417       const char *element = array;
418 #endif
419 
420     if (!fortchar_to_string(element, alen, next, left)) {
421       (void) fprintf(stderr, "rtdb_cput: abuf is too small, increase MXLGTH to=%d\n",
422 		     (int) (alen + sizeof(abuf) - left));
423       return FORTRAN_FALSE;
424     }
425     left -= strlen(next) + 1;
426     next += strlen(next) + 1;
427     if (i != (*nelem - 1))
428       *(next-1) = '\n';
429   }
430 
431   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
432     (void) fprintf(stderr, "rtdb_cput: nbuf is too small, need=%d\n",
433 		   nlen);
434     return FORTRAN_FALSE;
435   }
436 
437   nelbuf = strlen(abuf) + 1;
438   typebuf= (int) MT_CHAR;
439 
440 #ifdef DEBUG
441   printf("cput: rtdb=%d, mat=%d, nel=%d, name=%s\n", hbuf, typebuf, nelbuf, nbuf);
442   fflush(stdout);
443 #endif
444 
445   if (rtdb_put(hbuf, nbuf, typebuf, nelbuf, abuf))
446     return FORTRAN_TRUE;
447   else
448     return FORTRAN_FALSE;
449 }
450 
451 /*MV*/
452 /**
453   \brief Retrieve the length of a character string on the RTDB
454 
455   When a character string is stored on the RTDB it is not necessarily obvious
456   how long the string is. Hence it is useful to be able to check the length of
457   the string before attempting to retrieve it to make sure that a buffer of
458   sufficient length is provided.
459 
460   This function is supposed to be called from a Fortran code.
461 
462   \param handle [Input] the RTDB handle
463   \param name   [Input] the key
464   \param nelem  [Output] the number of characters
465 
466   \return Return FORTRAN_TRUE if successfull, and FORTRAN_FALSE otherwise.
467 */
468 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
469 Logical FATR rtdb_cget_size_(const Integer *handle, _fcd name,
470 		   const Integer *nelem)
471 {
472     int nlen = _fcdlen(name);
473     int alen = _fcdlen(farray);
474 #else
475 Logical FATR rtdb_cget_size_(const Integer *handle, const char *name,
476 		   Integer *nelem,
477 		   const int nlen, const int alen)
478 {
479 #endif
480 
481 /*
482   Read an array of Fortran character variables from the data base.
483 
484   Put stored the array as follows:
485   .  Each array element is striped of trailing blanks, terminated with CR,
486   .  and appended to the list. The entire array must fit into abuf.
487 */
488 
489   int hbuf = (int) *handle;
490   char nbuf[256];
491   char abuf[MXLGTH];
492   int nelbuf;
493   int typebuf;
494   int i;
495   char *next;
496   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
497     (void) fprintf(stderr, "rtdb_cget: nbuf is too small, need=%d\n",
498 		   nlen);
499     return FORTRAN_FALSE;
500   }
501 
502 
503   nelbuf = sizeof(abuf);
504   typebuf= (int) MT_CHAR;
505 
506   if (!rtdb_get(hbuf, nbuf, typebuf, nelbuf, abuf)) {
507       return FORTRAN_FALSE;	/* Not there */
508   }
509 
510   for (i=0, next=strtok(abuf, "\n");
511        next;
512        i++, next=strtok((char *) 0, "\n")) {
513   }
514   *nelem = i;
515   return FORTRAN_TRUE;
516 }
517 
518 
519 
520 
521 /*MV*/
522 /**
523   \brief Retrieve a character string from the RTDB
524 
525   Retrieve a character string from the RTDB and return it in the character
526   buffer provided. The buffer must be large enough to hold the value otherwise
527   the function will fail.
528 
529   This function is supposed to be called from a Fortran code.
530 
531   \param handle [Input] the RTDB handle
532   \param name   [Input] the key
533   \param nelem  [Input] the length of the character buffer
534   \param array  [Output] the value of the string
535 
536   \return Return FORTRAN_TRUE if successfull, and FORTRAN_FALSE otherwise.
537 */
538 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
539 Logical FATR rtdb_cget_(const Integer *handle, _fcd name,
540 		   const Integer *nelem,
541 		   _fcd farray)
542 {
543     int nlen = _fcdlen(name);
544     int alen = _fcdlen(farray);
545     char *array = _fcdtocp(farray);
546 #else
547 Logical FATR rtdb_cget_(const Integer *handle, const char *name,
548 		   const Integer *nelem,
549 		   char *array, const int nlen, const int alen)
550 {
551 #endif
552 /*
553   Read an array of Fortran character variables from the data base.
554 
555   Put stored the array as follows:
556   .  Each array element is striped of trailing blanks, terminated with CR,
557   .  and appended to the list. The entire array must fit into abuf.
558 */
559 
560   int hbuf = (int) *handle;
561   char nbuf[256];
562   char abuf[MXLGTH];
563   int nelbuf;
564   int typebuf;
565   int i;
566   char *next;
567 
568   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
569     (void) fprintf(stderr, "rtdb_cget: nbuf is too small, need=%d\n",
570 		   nlen);
571     return FORTRAN_FALSE;
572   }
573 
574   nelbuf = sizeof(abuf);
575   typebuf= (int) MT_CHAR;
576 
577 #ifdef DEBUG
578   printf("cget: rtdb=%d, mat=%d, nel=%d, name=%s\n", hbuf, typebuf, nelbuf, nbuf);
579   fflush(stdout);
580 #endif
581 
582   if (!rtdb_get(hbuf, nbuf, typebuf, nelbuf, abuf))
583       return FORTRAN_FALSE;	/* Not there */
584 
585   for (i=0, next=strtok(abuf, "\n");
586        next;
587        i++, array+=alen, next=strtok((char *) 0, "\n")) {
588 #if defined(CRAY) && !defined(__crayx1)
589       _fcd element = _cptofcd(array, alen);
590 #elif defined(WIN32) &&! defined(__MINGW32__)
591       _fcd element;
592       element.string = array;
593       element.len = alen;
594 #elif defined(USE_FCD)
595 #error Do something about _fcd
596 #else
597       char *element = array;
598 #endif
599 
600     if (i == *nelem) {
601       (void) fprintf(stderr, "rtdb_cget: array has too few elements\n");
602       (void) fprintf(stderr, "rtdb_cget: name was <<%s>>\n",name);
603       return FORTRAN_FALSE;
604     }
605 
606     if (!string_to_fortchar(element, alen, next)) {
607       (void) fprintf(stderr, "rtdb_cget: array element is too small\n");
608       (void) fprintf(stderr, "rtdb_cget: name was <<%s>>\n",name);
609       return FORTRAN_FALSE;
610     }
611   }
612   return FORTRAN_TRUE;
613 }
614 
615 /**
616 @}
617 */
618 
619 #if (defined(_CRAY) || defined(USE_FCD)) && !defined(__crayx1)
620 Logical FATR rtdb_first_(const Integer *handle, _fcd name)
621 #else
622 Logical FATR rtdb_first_(const Integer *handle, char *name, int nlen)
623 #endif
624 {
625 #if (defined(_CRAY) || defined(USE_FCD)) && !defined(__crayx1)
626   // dummy arg, value reassigned by string_to_fortchar in this case
627   int nlen = _fcdlen(name);
628 #endif
629   char nbuf[256];
630 
631   if (rtdb_first((int) *handle, (int) sizeof(nbuf), nbuf) &&
632       string_to_fortchar(name, nlen, nbuf))
633     return FORTRAN_TRUE;
634   else
635     return FORTRAN_FALSE;
636 }
637 
638 #if (defined(_CRAY) || defined(USE_FCD)) && !defined(__crayx1)
639 Logical FATR rtdb_next_(const Integer *handle, _fcd name)
640 #else
641 Logical FATR rtdb_next_(const Integer *handle, char *name, int nlen)
642 #endif
643 {
644 #if (defined(_CRAY) || defined(USE_FCD)) && !defined(__crayx1)
645   // dummy arg, value reassigned by string_to_fortchar in this case
646   int nlen = _fcdlen(name);
647 #endif
648   char nbuf[256];
649 
650   if (rtdb_next((int) *handle, (int) sizeof(nbuf), nbuf) &&
651       string_to_fortchar(name, nlen, nbuf))
652     return FORTRAN_TRUE;
653   else
654     return FORTRAN_FALSE;
655 }
656 #if (defined(CRAY) || defined(USE_FCD)) && !defined(__crayx1)
657 Logical FATR rtdb_delete_(const Integer *handle, _fcd name)
658 {
659   int nlen = _fcdlen(name);
660 #else
661 Logical FATR rtdb_delete_(const Integer *handle, const char *name, const int nlen)
662 {
663 #endif
664   int hbuf = (int) *handle;
665   char nbuf[256];
666 
667   if (!fortchar_to_string(name, nlen, nbuf, sizeof(nbuf))) {
668     (void) fprintf(stderr, "rtdb_delete: nbuf is too small, need=%d\n",
669 		   nlen);
670     return FORTRAN_FALSE;
671   }
672 
673   if (rtdb_delete(hbuf, nbuf))
674     return FORTRAN_TRUE;
675   else
676     return FORTRAN_FALSE;
677 }
678 
679 extern void rtdb_print_usage(void);
680 
681 void FATR rtdb_print_usage_()
682 {
683   rtdb_print_usage();
684 }
685