Exemple #1
0
/* $Procedure SPCT2B ( SPK and CK, text to binary ) */
/* Subroutine */ int spct2b_(integer *unit, char *binary, ftnlen binary_len)
{
    /* System generated locals */
    integer i__1;
    cilist ci__1;
    olist o__1;
    cllist cl__1;

    /* Builtin functions */
    integer s_rsfe(cilist *), do_fio(integer *, char *, ftnlen), e_rsfe(void),
	     s_cmp(char *, char *, ftnlen, ftnlen), f_open(olist *), s_wsfe(
	    cilist *), e_wsfe(void), f_clos(cllist *);

    /* Local variables */
    char line[1000];
    extern /* Subroutine */ int spcac_(integer *, integer *, char *, char *, 
	    ftnlen, ftnlen), chkin_(char *, ftnlen);
    extern integer ltrim_(char *, ftnlen), rtrim_(char *, ftnlen);
    extern /* Subroutine */ int daft2b_(integer *, char *, integer *, ftnlen);
    integer handle;
    extern /* Subroutine */ int dafcls_(integer *), dafopw_(char *, integer *,
	     ftnlen);
    integer scrtch;
    extern /* Subroutine */ int errfnm_(char *, integer *, ftnlen), sigerr_(
	    char *, ftnlen), chkout_(char *, ftnlen), getlun_(integer *), 
	    setmsg_(char *, ftnlen);
    integer iostat;
    extern /* Subroutine */ int errint_(char *, integer *, ftnlen);
    extern logical return_(void);

/* $ Abstract */

/*     Reconstruct a binary SPK or CK file including comments */
/*     from a text file opened by the calling program. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     SPC */

/* $ Keywords */

/*     FILES */

/* $ Declarations */
/* $ Brief_I/O */

/*     Variable  I/O  Description */
/*     --------  ---  -------------------------------------------------- */
/*     UNIT       I   Logical unit connected to the text format file. */
/*     BINARY     I   Name of a binary SPK or CK file to be created. */

/* $ Detailed_Input */

/*     UNIT        is the logical unit connected to an existing text */
/*                 format SPK or CK file that may contain comments in */
/*                 the appropriate SPC format, as written by SPCB2A or */
/*                 SPCB2T.  This file must be opened for read access */
/*                 using the routine TXTOPR. */

/*                 This file may contain text that precedes and */
/*                 follows the SPK or CK data and comments, however, */
/*                 when calling this routine, the file pointer must be */
/*                 in a position in the file such that the next line */
/*                 returned by a READ statement is */

/*                      ''NAIF/DAF'' */

/*                 which marks the beginning of the data. */

/*     BINARY      is the name of a binary SPK or CK file to be created. */
/*                 The binary file contains the same data and comments */
/*                 as the text file, but in the binary format required */
/*                 for use with the SPICELIB reader subroutines. */

/* $ Detailed_Output */

/*     None. */

/* $ Parameters */

/*     None. */

/* $ Files */

/*     1)  See arguments UNIT and BINARY above. */

/*     2)  This routine uses a Fortran scratch file to temporarily */
/*         store the lines of comments if there are any. */

/* $ Exceptions */

/*     1) If there is a problem opening or writing to the binary */
/*        file, a routine that SPCT2B calls diagnoses and signals */
/*        an error. */

/*     2) If there is a problem reading from the text file, the */
/*        error SPICE(FILEREADFAILED) is signalled. */

/*     3) If there is a problem opening a scratch file, the error */
/*        SPICE(FILEOPENERROR) is signalled. */

/*     4) If there is a problem writing to the scratch file, the */
/*        error SPICE(FILEWRITEFAILED) is signalled. */

/* $ Particulars */

/*     The SPICELIB SPK and CK reader subroutines read binary files. */
/*     However, because different computing environments have different */
/*     binary representations of numbers, you must convert SPK and CK */
/*     files to text format when porting from one system to another. */
/*     After converting the file to text, you can transfer it using */
/*     a transfer protocol program like Kermit or FTP.  Then, convert */
/*     the text file back to binary format. */

/*     The following is a list of the SPICELIB routines that convert */
/*     SPK and CK files between binary and text format: */

/*        SPCA2B    converts text to binary.  It opens the text file, */
/*                  creates a new binary file, and closes both files. */

/*        SPCB2A    converts binary to text.  It opens the binary file, */
/*                  creates a new text file, and closes both files. */

/*        SPCT2B    converts text to binary.  It creates a new binary */
/*                  file and closes it.  The text file is open on */
/*                  entrance and exit. */

/*        SPCB2T    converts binary to text.  It opens the binary */
/*                  file and closes it.  The text file is open on */
/*                  entrance and exit */

/*     See the SPC required reading for more information */
/*     about SPC routines and the SPK and CK file formats. */

/* $ Examples */

/*     1)  The following code fragment creates a text file containing */
/*         text format SPK data and comments preceded and followed */
/*         by a standard label. */

/*         The SPICELIB routine TXTOPN opens a new text file and TXTOPR */
/*         opens an existing text file for read access.  TEXT and */
/*         BINARY are character strings that contain the names of the */
/*         text and binary files. */

/*            CALL TXTOPN ( TEXT, UNIT ) */

/*            (Write header label to UNIT) */

/*            CALL SPCB2T ( BINARY, UNIT ) */

/*            (Write trailing label to UNIT) */

/*            CLOSE ( UNIT ) */


/*         The following code fragment reconverts the text format */
/*         SPK data and comments back into binary format. */

/*            CALL TXTOPR ( TEXT, UNIT ) */

/*            (Read, or just read past, header label from UNIT) */

/*            CALL SPCT2B ( UNIT, BINARY ) */

/*            (Read trailing label from UNIT, if desired ) */

/*            CLOSE ( UNIT ) */


/*     2)  Suppose three text format SPK files have been appended */
/*         together into one text file called THREE.TSP.  The following */
/*         code fragment converts each set of data and comments into */
/*         its own binary file. */

/*            CALL TXTOPR ( 'THREE.TSP', UNIT  ) */

/*            CALL SPCT2B ( UNIT, 'FIRST.BSP'  ) */
/*            CALL SPCT2B ( UNIT, 'SECOND.BSP' ) */
/*            CALL SPCT2B ( UNIT, 'THIRD.BSP'  ) */

/*            CLOSE ( UNIT ) */

/* $ Restrictions */

/*     1)  This routine assumes that the data and comments in the */
/*         text format SPK or CK file come from a binary file */
/*         and were written by one of the routines SPCB2A or SPCB2T. */
/*         Data and/or comments written any other way may not be */
/*         in the correct format and, therefore, may not be handled */
/*         properly. */

/*     2)  Older versions of SPK and CK files did not have a comment */
/*         area.  These files, in text format, may still be converted */
/*         to binary using SPCT2B.  However, upon exit, the file pointer */
/*         will not be in position ready to read the first line of text */
/*         after the data.  Instead, the next READ statement after */
/*         calling SPCT2B will return the second line of text after */
/*         the data.  Therefore, example 1 may not work as desired */
/*         if the trailing label begins on the first line after the */
/*         data.  To solve this problem, use DAFT2B instead of SPCT2B. */

/*     3)  UNIT must be obtained via TXTOPR.  Use TXTOPR to open text */
/*         files for read access and get the logical unit.  System */
/*         dependencies regarding opening text files have been isolated */
/*         in the routines TXTOPN and TXTOPR. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     J.E. McLean    (JPL) */

/* $ Version */

/* -    SPICELIB Version 1.0.1, 10-MAR-1992 (WLT) */

/*        Comment section for permuted index source lines was added */
/*        following the header. */

/* -    SPICELIB Version 1.0.0, 05-APR-1991 (JEM) */

/* -& */
/* $ Index_Entries */

/*     text spk or ck to binary */

/* -& */

/*     SPICELIB functions */


/*     Local parameters */


/*     Local variables */


/*     Standard SPICE error handling. */

    if (return_()) {
	return 0;
    } else {
	chkin_("SPCT2B", (ftnlen)6);
    }

/*     DAFT2B creates the new binary file and writes the data to */
/*     it.  If the 'NAIF/DAF' keyword is not the first line that */
/*     it reads from the text file, it will signal an error. */
/*     Initially, no records are reserved. */

    daft2b_(unit, binary, &c__0, binary_len);

/*     The comments follow the data and are surrounded by markers. */
/*     BMARK should be the next line that we read.  If it isn't, */
/*     then this is an old file, created before the comment area */
/*     existed.  In this case, we've read one line too far, but */
/*     we can't backspace because the file was written using list- */
/*     directed formatting (See the ANSI standard).  All we can do */
/*     is check out, leaving the file pointer where it is, but */
/*     that's better than signalling an error. */

    ci__1.cierr = 1;
    ci__1.ciend = 1;
    ci__1.ciunit = *unit;
    ci__1.cifmt = "(A)";
    iostat = s_rsfe(&ci__1);
    if (iostat != 0) {
	goto L100001;
    }
    iostat = do_fio(&c__1, line, (ftnlen)1000);
    if (iostat != 0) {
	goto L100001;
    }
    iostat = e_rsfe();
L100001:
    if (iostat > 0) {
	setmsg_("Error reading the text file named FNM.  Value of IOSTAT is "
		"#.", (ftnlen)61);
	errint_("#", &iostat, (ftnlen)1);
	errfnm_("FNM", unit, (ftnlen)3);
	sigerr_("SPICE(FILEREADFAILED)", (ftnlen)21);
	chkout_("SPCT2B", (ftnlen)6);
	return 0;
    }
    i__1 = ltrim_(line, (ftnlen)1000) - 1;
    if (s_cmp(line + i__1, "~NAIF/SPC BEGIN COMMENTS~", 1000 - i__1, (ftnlen)
	    25) != 0 || iostat < 0) {
	chkout_("SPCT2B", (ftnlen)6);
	return 0;
    }

/*     We're not at the end of the file, and the line we read */
/*     is BMARK, so we write the comments to a scratch file. */
/*     We do this because we have to use SPCAC to add the comments */
/*     to the comment area of the binary file, and SPCAC rewinds */
/*     the file.  It's okay for SPCAC to rewind a scratch file, */
/*     but it's not okay to rewind the file connected to UNIT -- */
/*     we don't know the initial location of the file pointer. */

    getlun_(&scrtch);
    o__1.oerr = 1;
    o__1.ounit = scrtch;
    o__1.ofnm = 0;
    o__1.orl = 0;
    o__1.osta = "SCRATCH";
    o__1.oacc = "SEQUENTIAL";
    o__1.ofm = "FORMATTED";
    o__1.oblnk = 0;
    iostat = f_open(&o__1);
    if (iostat != 0) {
	setmsg_("Error opening a scratch file.  File name was FNM.  Value of"
		" IOSTAT is #.", (ftnlen)72);
	errint_("#", &iostat, (ftnlen)1);
	errfnm_("FNM", &scrtch, (ftnlen)3);
	sigerr_("SPICE(FILEOPENERROR)", (ftnlen)20);
	chkout_("SPCT2B", (ftnlen)6);
	return 0;
    }
    ci__1.cierr = 1;
    ci__1.ciunit = scrtch;
    ci__1.cifmt = "(A)";
    iostat = s_wsfe(&ci__1);
    if (iostat != 0) {
	goto L100002;
    }
    iostat = do_fio(&c__1, line, rtrim_(line, (ftnlen)1000));
    if (iostat != 0) {
	goto L100002;
    }
    iostat = e_wsfe();
L100002:
    if (iostat != 0) {
	setmsg_("Error writing to scratch file. File name is FNM.  Value of "
		"IOSTAT is #.", (ftnlen)71);
	errint_("#", &iostat, (ftnlen)1);
	errfnm_("FNM", &scrtch, (ftnlen)3);
	sigerr_("SPICE(FILEWRITEFAILED)", (ftnlen)22);
	chkout_("SPCT2B", (ftnlen)6);
	return 0;
    }

/*     Continue reading lines from the text file and storing them */
/*     in the scratch file until we get to the end marker. */

    for(;;) { /* while(complicated condition) */
	i__1 = ltrim_(line, (ftnlen)1000) - 1;
	if (!(s_cmp(line + i__1, "~NAIF/SPC END COMMENTS~", 1000 - i__1, (
		ftnlen)23) != 0))
		break;
	ci__1.cierr = 1;
	ci__1.ciend = 1;
	ci__1.ciunit = *unit;
	ci__1.cifmt = "(A)";
	iostat = s_rsfe(&ci__1);
	if (iostat != 0) {
	    goto L100003;
	}
	iostat = do_fio(&c__1, line, (ftnlen)1000);
	if (iostat != 0) {
	    goto L100003;
	}
	iostat = e_rsfe();
L100003:
	if (iostat != 0) {
	    setmsg_("Error reading the text file named FNM.  Value of IOSTAT"
		    " is #.", (ftnlen)61);
	    errint_("#", &iostat, (ftnlen)1);
	    errfnm_("FNM", unit, (ftnlen)3);
	    sigerr_("SPICE(FILEREADFAILED)", (ftnlen)21);
	    chkout_("SPCT2B", (ftnlen)6);
	    return 0;
	}
	ci__1.cierr = 1;
	ci__1.ciunit = scrtch;
	ci__1.cifmt = "(A)";
	iostat = s_wsfe(&ci__1);
	if (iostat != 0) {
	    goto L100004;
	}
	iostat = do_fio(&c__1, line, rtrim_(line, (ftnlen)1000));
	if (iostat != 0) {
	    goto L100004;
	}
	iostat = e_wsfe();
L100004:
	if (iostat != 0) {
	    setmsg_("Error writing to scratch file.  File name is FNM.  Valu"
		    "e of IOSTAT is #.", (ftnlen)72);
	    errint_("#", &iostat, (ftnlen)1);
	    errfnm_("FNM", &scrtch, (ftnlen)3);
	    sigerr_("SPICE(FILEWRITEFAILED)", (ftnlen)22);
	    chkout_("SPCT2B", (ftnlen)6);
	    return 0;
	}
    }

/*     Open the new binary file and add the comments that have been */
/*     stored temporarily in a scratch file. */

    dafopw_(binary, &handle, binary_len);
    spcac_(&handle, &scrtch, "~NAIF/SPC BEGIN COMMENTS~", "~NAIF/SPC END COM"
	    "MENTS~", (ftnlen)25, (ftnlen)23);

/*     Close the files.  The scratch file is automatically deleted. */

    dafcls_(&handle);
    cl__1.cerr = 0;
    cl__1.cunit = scrtch;
    cl__1.csta = 0;
    f_clos(&cl__1);
    chkout_("SPCT2B", (ftnlen)6);
    return 0;
} /* spct2b_ */
Exemple #2
0
/* $Procedure      WRLINE ( Write Output Line to a Device ) */
/* Subroutine */ int wrline_0_(int n__, char *device, char *line, ftnlen 
	device_len, ftnlen line_len)
{
    /* System generated locals */
    integer i__1;
    cilist ci__1;
    olist o__1;
    cllist cl__1;
    inlist ioin__1;

    /* Builtin functions */
    integer s_cmp(char *, char *, ftnlen, ftnlen), s_wsfe(cilist *), do_fio(
	    integer *, char *, ftnlen), e_wsfe(void), f_inqu(inlist *), 
	    s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen), 
	    e_wsle(void), f_open(olist *);
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
    integer f_clos(cllist *);

    /* Local variables */
    integer unit;
    extern /* Subroutine */ int ucase_(char *, char *, ftnlen, ftnlen);
    extern integer ltrim_(char *, ftnlen);
    char error[240];
    extern integer rtrim_(char *, ftnlen);
    extern /* Subroutine */ int ljust_(char *, char *, ftnlen, ftnlen);
    logical opened;
    extern /* Subroutine */ int fndlun_(integer *);
    char tmpnam[128];
    integer iostat;
    extern /* Subroutine */ int suffix_(char *, integer *, char *, ftnlen, 
	    ftnlen);
    logical exists;
    char errstr[11];
    extern /* Subroutine */ int intstr_(integer *, char *, ftnlen);

    /* Fortran I/O blocks */
    static cilist io___6 = { 0, 6, 0, 0, 0 };
    static cilist io___7 = { 0, 6, 0, 0, 0 };
    static cilist io___8 = { 0, 6, 0, 0, 0 };
    static cilist io___9 = { 0, 6, 0, 0, 0 };
    static cilist io___10 = { 0, 6, 0, 0, 0 };
    static cilist io___11 = { 0, 6, 0, 0, 0 };
    static cilist io___12 = { 0, 6, 0, 0, 0 };
    static cilist io___15 = { 0, 6, 0, 0, 0 };
    static cilist io___16 = { 0, 6, 0, 0, 0 };
    static cilist io___17 = { 0, 6, 0, 0, 0 };
    static cilist io___18 = { 0, 6, 0, 0, 0 };


/* $ Abstract */

/*     Write a character string to an output device. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     None. */

/* $ Keywords */

/*     TEXT */
/*     FILES */
/*     ERROR */

/* $ Declarations */
/* $ Brief_I/O */

/*     VARIABLE  I/O  DESCRIPTION */
/*     --------  ---  -------------------------------------------------- */
/*     DEVICE     I   A string specifying an output device. */
/*     LINE       I   A line of text to be output. */
/*     FILEN      P   Maximum length of a file name. */

/* $ Detailed_Input */

/*     LINE           is a line of text to be written to the output */
/*                    device specified by DEVICE. */

/*     DEVICE         is the output device to which the line of text */
/*                    will be written. */

/*                    Possible values and meanings of DEVICE are: */

/*                       a device name   This may be the name of a */
/*                                       file, or any other name that */
/*                                       is valid in a FORTRAN OPEN */
/*                                       statement.  For example, on a */
/*                                       VAX, a logical name may be */
/*                                       used. */

/*                                       The device name must not */
/*                                       be any of the reserved strings */
/*                                       below. */


/*                       'SCREEN'        The output will go to the */
/*                                       terminal screen. */


/*                       'NULL'          The data will not be output. */


/*                 'SCREEN' and 'NULL' can be written in mixed */
/*                  case.  For example, the following call will work: */

/*                  CALL WRLINE ( 'screEn', LINE ) */

/* $ Detailed_Output */

/*     None. */

/* $ Parameters */

/*     FILEN        is the maximum length of a file name. */

/* $ Exceptions */

/*     This routine is a special case as far as error handling */
/*     is concerned because it is called to output error */
/*     messages resulting from errors detected by other routines. */
/*     In such a case, calling SIGERR would constitute recursion. */
/*     Therefore, this routine prints error messages rather */
/*     than signalling errors via SIGERR and setting the long */
/*     error message via SETMSG. */

/*     The following exceptional cases are treated as errors: */

/*     1)  SPICE(NOFREELOGICALUNIT) -- No logical unit number */
/*         is available to refer to the device. */

/*     2)  SPICE(FILEOPENFAILED) -- General file open error. */

/*     3)  SPICE(FILEWRITEFAILED) -- General file write error. */

/*     4)  SPICE(INQUIREFAILED) -- INQUIRE statement failed. */

/*     5)  Leading blanks in (non-blank) file names are not */
/*         significant.  The file names */

/*             'MYFILE.DAT' */
/*             '   MYFILE.DAT' */

/*         are considered to name the same file. */

/*     6)  If different names that indicate the same file are supplied */
/*         to this routine on different calls, all output associated */
/*         with these calls WILL be written to the file.  For example, */
/*         on a system where logical filenames are supported, if */
/*         ALIAS is a logical name pointing to MYFILE, then the calls */

/*             CALL WRLINE ( 'MYFILE', 'This is the first line'  ) */
/*             CALL WRLINE ( 'ALIAS',  'This is the second line' ) */

/*         will place the lines of text */

/*              'This is the first line' */
/*              'This is the second line' */

/*         in MYFILE.  See $Restrictions for more information on use */
/*         of logical names on VAX systems. */

/* $ Files */

/*     1)  If DEVICE specifies a device other than 'SCREEN' or 'NULL', */
/*         that device is opened (if it's not already open) as a NEW, */
/*         SEQUENTIAL, FORMATTED file.  The logical unit used is */
/*         determined at run time. */

/* $ Particulars */

/*     If the output device is a file that is not open, the file will */
/*     be opened (if possible) as a NEW, sequential, formatted file, */
/*     and the line of text will be written to the file.  If the file */
/*     is already opened as a sequential, formatted file, the line of */
/*     text will be written to the file. */

/*     Use the entry point CLLINE to close files opened by WRLINE. */

/* $ Examples */

/*     1)  Write a message to the screen: */

/*                CALL WRLINE ( 'SCREEN', 'Here''s a message.' ) */

/*         The text */

/*                Here's a message. */

/*         will be written to the screen. */


/*     2)  Write out all of the elements of a character string array */
/*         to a file. */

/*                CHARACTER*(80)          STRING ( ASIZE ) */
/*                             . */
/*                             . */
/*                             . */
/*                DO I = 1, ASIZE */
/*                   CALL WRLINE ( FILE, STRING(I) ) */
/*                END DO */


/*     3)  Set DEVICE to NULL to suppress output: */

/*             C */
/*             C     Ask the user whether verbose program output is */
/*             C     desired.  Set the output device accordingly. */
/*             C */
/*                   WRITE (*,*) 'Do you want to see test results '    // */
/*                  .            'on the screen?' */
/*                   READ  (*,FMT='(A)') VERBOS */

/*                   CALL LJUST ( VERBOS, VERBOS ) */
/*                   CALL UCASE ( VERBOS, VERBOS ) */

/*                   IF ( VERBOS(1:1) .EQ. 'Y' ) THEN */
/*                      DEVICE = 'SCREEN' */
/*                   ELSE */
/*                      DEVICE = 'NULL' */
/*                   ENDIF */
/*                             . */
/*                             . */
/*                             . */
/*             C */
/*             C     Output test results. */
/*             C */
/*                   CALL WRLINE ( DEVICE, STRING ) */
/*                             . */
/*                             . */
/*                             . */

/* $ Restrictions */

/*     1)  File names must not exceed FILEN characters. */

/*     2)  On VAX systems, caution should be exercised when using */
/*         multiple logical names to point to the same file.  Logical */
/*         name translation supporting execution of the Fortran */
/*         INQUIRE statement does not appear to work reliably in all */
/*         cases, which may lead this routine to believe that different */
/*         logical names indicate different files.  The specific problem */
/*         that has been observed is that logical names that include */
/*         disk specifications are not always recognized as pointing */
/*         to the file they actually name. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     N.J. Bachman    (JPL) */
/*     H.A. Neilan     (JPL) */

/* $ Version */

/* -    SPICELIB Version 4.25.0, 10-MAR-2014 (BVS) */

/*        Updated for SUN-SOLARIS-64BIT-INTEL. */

/* -    SPICELIB Version 4.24.0, 10-MAR-2014 (BVS) */

/*        Updated for PC-LINUX-64BIT-IFORT. */

/* -    SPICELIB Version 4.23.0, 10-MAR-2014 (BVS) */

/*        Updated for PC-CYGWIN-GFORTRAN. */

/* -    SPICELIB Version 4.22.0, 10-MAR-2014 (BVS) */

/*        Updated for PC-CYGWIN-64BIT-GFORTRAN. */

/* -    SPICELIB Version 4.21.0, 10-MAR-2014 (BVS) */

/*        Updated for PC-CYGWIN-64BIT-GCC_C. */

/* -    SPICELIB Version 4.20.0, 13-MAY-2010 (BVS) */

/*        Updated for SUN-SOLARIS-INTEL. */

/* -    SPICELIB Version 4.19.0, 13-MAY-2010 (BVS) */

/*        Updated for SUN-SOLARIS-INTEL-CC_C. */

/* -    SPICELIB Version 4.18.0, 13-MAY-2010 (BVS) */

/*        Updated for SUN-SOLARIS-INTEL-64BIT-CC_C. */

/* -    SPICELIB Version 4.17.0, 13-MAY-2010 (BVS) */

/*        Updated for SUN-SOLARIS-64BIT-NATIVE_C. */

/* -    SPICELIB Version 4.16.0, 13-MAY-2010 (BVS) */

/*        Updated for PC-WINDOWS-64BIT-IFORT. */

/* -    SPICELIB Version 4.15.0, 13-MAY-2010 (BVS) */

/*        Updated for PC-LINUX-64BIT-GFORTRAN. */

/* -    SPICELIB Version 4.14.0, 13-MAY-2010 (BVS) */

/*        Updated for PC-64BIT-MS_C. */

/* -    SPICELIB Version 4.13.0, 13-MAY-2010 (BVS) */

/*        Updated for MAC-OSX-64BIT-INTEL_C. */

/* -    SPICELIB Version 4.12.0, 13-MAY-2010 (BVS) */

/*        Updated for MAC-OSX-64BIT-IFORT. */

/* -    SPICELIB Version 4.11.0, 13-MAY-2010 (BVS) */

/*        Updated for MAC-OSX-64BIT-GFORTRAN. */

/* -    SPICELIB Version 4.10.0, 18-MAR-2009 (BVS) */

/*        Updated for PC-LINUX-GFORTRAN. */

/* -    SPICELIB Version 4.9.0, 18-MAR-2009 (BVS) */

/*        Updated for MAC-OSX-GFORTRAN. */

/* -    SPICELIB Version 4.8.0, 19-FEB-2008 (BVS) */

/*        Updated for PC-LINUX-IFORT. */

/* -    SPICELIB Version 4.7.0, 14-NOV-2006 (BVS) */

/*        Updated for PC-LINUX-64BIT-GCC_C. */

/* -    SPICELIB Version 4.6.0, 14-NOV-2006 (BVS) */

/*        Updated for MAC-OSX-INTEL_C. */

/* -    SPICELIB Version 4.5.0, 14-NOV-2006 (BVS) */

/*        Updated for MAC-OSX-IFORT. */

/* -    SPICELIB Version 4.4.0, 14-NOV-2006 (BVS) */

/*        Updated for PC-WINDOWS-IFORT. */

/* -    SPICELIB Version 4.3.0, 26-OCT-2005 (BVS) */

/*        Updated for SUN-SOLARIS-64BIT-GCC_C. */

/* -    SPICELIB Version 4.2.0, 03-JAN-2005 (BVS) */

/*        Updated for PC-CYGWIN_C. */

/* -    SPICELIB Version 4.1.0, 03-JAN-2005 (BVS) */

/*        Updated for PC-CYGWIN. */

/* -    SPICELIB Version 4.0.5, 17-JUL-2002 (BVS) */

/*        Added MAC-OSX environments. */

/* -    SPICELIB Version 4.0.4, 08-OCT-1999 (WLT) */

/*        The environment lines were expanded so that the supported */
/*        environments are now explicitely given.  New */
/*        environments are WIN-NT */

/* -    SPICELIB Version 4.0.3, 16-SEP-1999 (NJB) */

/*        CSPICE environments were added.  Some typos were corrected. */

/* -    SPICELIB Version 4.0.2, 28-JUL-1999 (WLT) */

/*        The environment lines were expanded so that the supported */
/*        environments are now explicitly given.  New */
/*        environments are PC-DIGITAL, SGI-O32 and SGI-N32. */

/* -    SPICELIB Version 4.0.1, 18-MAR-1999 (WLT) */

/*        The environment lines were expanded so that the supported */
/*        environments are now explicitly given.  Previously, */
/*        environments such as SUN-SUNOS and SUN-SOLARIS were implied */
/*        by the environment label SUN. */

/* -    SPICELIB Version 4.0.0, 07-APR-1998 (NJB) */

/*        References to the PC-LINUX environment were added.  The */
/*        write format for the case where the output device is the */
/*        screen has been made system-dependent; list-directed output */
/*        format is now used for systems that require a leading carriage */
/*        control character; other systems use character format. The */
/*        write format for the case where the output device is a file */
/*        has been changed from list-directed to character. */


/* -    SPICELIB Version 3.0.0, 11-NOV-1993 (HAN) */

/*        Module was updated to include the value for FILEN */
/*        and the appropriate OPEN statement for the Silicon */
/*        Graphics, DEC Alpha-OSF/1, and NeXT platforms. The previous */
/*        value of 256 for Unix platforms was changed to 255. */

/* -    SPICELIB Version 2.1.0, 13-OCT-1992 (HAN) */

/*       Module was updated to include the value of FILEN for the */
/*       Hewlett Packard UX 9000/750 environment. */

/*       The code was also reformatted so that a utility program can */
/*       create the source file for a specific environment given a */
/*       master source file. */

/* -    SPICELIB Version 2.0.1, 10-MAR-1992 (WLT) */

/*       Comment section for permuted index source lines was added */
/*       following the header. */

/* -    SPICELIB Version 2.0.0, 26-MAR-1991 (NJB) */

/*       This routine now can write to files that have been opened */
/*       by other routines. */

/*       The limit imposed by this routine on the number of files it */
/*       can open has been removed. */

/*       The output file is now opened as a normal text file on */
/*       VAX systems. */

/*       Improper treatment of the case where DEVICE is blank was */
/*       remedied. */

/*       Unneeded variable declarations and references were removed. */

/*       Initialization of SAVED variables was added. */

/*       All occurrences of "PRINT *" have been replaced by */
/*       "WRITE (*,*)". */

/*       Calls to UCASE and LJUST replace in-line code that performed */
/*       these operations. */

/* -    SPICELIB Version 1.0.0, 31-JAN-1990 (NJB) */

/* -& */
/* $ Index_Entries */

/*     write output line to a device */

/* -& */
/* $ Revisions */

/* -    SPICELIB Version 4.0.0, 07-APR-1998 (NJB) */

/*        References to the PC-LINUX environment were added. */

/*        The write format for the case where the output device is the */
/*        screen has been made system-dependent; list-directed output */
/*        format is now used for systems that require a leading carriage */
/*        control character; other systems use character format. The */
/*        write format for the case where the output device is a file */
/*        has been changed from list-directed to character. */

/* -    SPICELIB Version 3.0.0, 11-NOV-1993 (HAN) */

/*         Module was updated to include the value for FILEN */
/*         and the appropriate OPEN statement for the Silicon */
/*         Graphics, DEC Alpha-OSF/1, and NeXT platforms. The previous */
/*         value of 256 for Unix platforms was changed to 255. */

/* -     SPICELIB Version 2.1.0, 13-OCT-1992 (HAN) */

/*        Module was updated to include the value of FILEN for the */
/*        Hewlett Packard UX 9000/750 environment. */

/*        The code was also reformatted so that a utility program can */
/*        create the source file for a specific environment given a */
/*        master source file. */

/* -    SPICELIB Version 2.0.0, 25-MAR-1991 (NJB) */

/*        1)  This routine now can write to files that have been opened */
/*            by other routines.  WRLINE uses an INQUIRE statement to */
/*            determine whether the file indicated by DEVICE is open, */
/*            and if it is, WRLINE does not attempt to open it.  This */
/*            allows use of WRLINE to feed error output into a log file */
/*            opened by another routine. */

/*            The header has been updated accordingly. */

/*            This fix also fixes a bug wherein this routine would treat */
/*            different character strings naming the same file as though */
/*            they indicated different files. */

/*        2)  The limit imposed by this routine on the number of files it */
/*            can open has been removed.  The file database used in */
/*            previous versions of this routine is no longer used. */

/*        3)  On VAX systems, this routine now opens the output file */
/*            (when required to do so) as a normal text file. */

/*        4)  Improper treatment of the case where DEVICE is blank was */
/*            remedied.  Any value of DEVICE that is not equal to */
/*            'SCREEN' or 'NULL' after being left-justified and */
/*            converted to upper case is considered to be a file name. */

/*        5)  Unneeded variable declarations and references were removed. */
/*            The arrays called STATUS and FILES are not needed. */

/*        6)  All instances if "PRINT *" have been replaced by */
/*            "WRITE (*,*)" because Language Systems Fortran on the */
/*            Macintosh interprets "PRINT *" in a non-standard manner. */

/*        7)  Use of the EXIST specifier was added to the INQUIRE */
/*            statement used to determine whether the file named by */
/*            DEVICE is open.  This is a work-around for a rather */
/*            peculiar behavior of at least one version of Sun Fortran: */
/*            files that don't exist may be considered to be open, as */
/*            indicated by the OPENED specifier of the INQUIRE statement. */

/*        8)  One other thing:  now that LJUST and UCASE are error-free, */
/*            WRLINE uses them; this simplifies the code. */


/* -    Beta Version 1.2.0, 27-FEB-1989 (NJB) */

/*        Call to GETLUN replaced by call to FNDLUN, which is error-free. */
/*        Call to IOERR replaced with in-line code to construct long */
/*        error message indicating file open failure. Arrangement of */
/*        declarations changed.  Keywords added. FILEN declaration */
/*        moved to "declarations" section.  Parameters section added. */

/* -    Beta Version 1.1.0, 06-OCT-1988 (NJB) */

/*        Upper bound of written substring changed to prevent use of */
/*        invalid substring bound.  Specifically, LASTNB ( LINE ) was */
/*        replaced by  MAX ( 1, LASTNB (LINE) ).  This upper bound */
/*        now used in the PRINT statement as well. */

/* -& */

/*     SPICELIB functions */


/*     Local variables */


/*     Executable Code: */

    switch(n__) {
	case 1: goto L_clline;
	}

    ljust_(device, tmpnam, device_len, (ftnlen)128);
    ucase_(tmpnam, tmpnam, (ftnlen)128, (ftnlen)128);

/*     TMPNAM is now left justified and is in upper case. */

    if (s_cmp(tmpnam, "NULL", (ftnlen)128, (ftnlen)4) == 0) {
	return 0;
    } else if (s_cmp(tmpnam, "SCREEN", (ftnlen)128, (ftnlen)6) == 0) {
	ci__1.cierr = 1;
	ci__1.ciunit = 6;
	ci__1.cifmt = "(A)";
	iostat = s_wsfe(&ci__1);
	if (iostat != 0) {
	    goto L100001;
	}
	iostat = do_fio(&c__1, line, rtrim_(line, line_len));
	if (iostat != 0) {
	    goto L100001;
	}
	iostat = e_wsfe();
L100001:
	return 0;
    }

/*     Find out whether we'll need to open the file. */

/*     We use the EXIST inquiry specifier because files that don't exist */
/*     may be (possibly due to a Sun compiler bug) deemed to be OPEN by */
/*     Sun Fortran. */

    i__1 = ltrim_(device, device_len) - 1;
    ioin__1.inerr = 1;
    ioin__1.infilen = device_len - i__1;
    ioin__1.infile = device + i__1;
    ioin__1.inex = &exists;
    ioin__1.inopen = &opened;
    ioin__1.innum = &unit;
    ioin__1.innamed = 0;
    ioin__1.inname = 0;
    ioin__1.inacc = 0;
    ioin__1.inseq = 0;
    ioin__1.indir = 0;
    ioin__1.infmt = 0;
    ioin__1.inform = 0;
    ioin__1.inunf = 0;
    ioin__1.inrecl = 0;
    ioin__1.innrec = 0;
    ioin__1.inblank = 0;
    iostat = f_inqu(&ioin__1);
    if (iostat != 0) {

/*        This is weird.  How can an INQUIRE statement fail, */
/*        if the syntax is correct?  But just in case... */

	s_wsle(&io___6);
	do_lio(&c__9, &c__1, "SPICE(INQUIREFAILED)", (ftnlen)20);
	e_wsle();
	s_wsle(&io___7);
	do_lio(&c__9, &c__1, "WRLINE: File = ", (ftnlen)15);
	do_lio(&c__9, &c__1, device, device_len);
	do_lio(&c__9, &c__1, "IOSTAT = ", (ftnlen)9);
	do_lio(&c__3, &c__1, (char *)&iostat, (ftnlen)sizeof(integer));
	e_wsle();
	return 0;
    }
    if (! (opened && exists)) {

/*        We will need a free logical unit.  There is always the chance */
/*        that no units are available. */

	fndlun_(&unit);
	if (unit < 1) {
	    s_wsle(&io___8);
	    do_lio(&c__9, &c__1, "SPICE(NOFREELOGICALUNIT)", (ftnlen)24);
	    e_wsle();
	    s_wsle(&io___9);
	    do_lio(&c__9, &c__1, " ", (ftnlen)1);
	    e_wsle();
	    s_wsle(&io___10);
	    do_lio(&c__9, &c__1, "WRLINE: Maximum number of logical units th"
		    "at can be allocated by SPICELIB has already been reached",
		     (ftnlen)98);
	    e_wsle();
	    return 0;
	}

/*        Okay, we have a unit. Open the file, and hope nothing */
/*        goes awry. (On the VAX, the qualifier */

/*           CARRIAGECONTROL = 'LIST' */

/*        may be inserted into the OPEN statement.) */

	i__1 = ltrim_(device, device_len) - 1;
	o__1.oerr = 1;
	o__1.ounit = unit;
	o__1.ofnmlen = device_len - i__1;
	o__1.ofnm = device + i__1;
	o__1.orl = 0;
	o__1.osta = "NEW";
	o__1.oacc = 0;
	o__1.ofm = 0;
	o__1.oblnk = 0;
	iostat = f_open(&o__1);
	if (iostat != 0) {
	    s_wsle(&io___11);
	    do_lio(&c__9, &c__1, "SPICE(FILEOPENFAILED)", (ftnlen)21);
	    e_wsle();
	    s_wsle(&io___12);
	    do_lio(&c__9, &c__1, " ", (ftnlen)1);
	    e_wsle();
	    s_copy(error, "WRLINE: An error occurred while attempting to open"
		    , (ftnlen)240, (ftnlen)50);
	    suffix_(device, &c__1, error, device_len, (ftnlen)240);
	    suffix_(".", &c__0, error, (ftnlen)1, (ftnlen)240);
	    suffix_("The value of IOSTAT returned was", &c__2, error, (ftnlen)
		    32, (ftnlen)240);
	    suffix_(":", &c__0, error, (ftnlen)1, (ftnlen)240);
	    intstr_(&iostat, errstr, (ftnlen)11);
	    suffix_(errstr, &c__1, error, (ftnlen)11, (ftnlen)240);
	    suffix_(".", &c__0, error, (ftnlen)1, (ftnlen)240);
	    s_wsle(&io___15);
	    do_lio(&c__9, &c__1, error, (ftnlen)240);
	    e_wsle();
	    return 0;
	}

/*        Whew! We're ready to write to this file. */

    }

/*     At this point, either we opened the file, or it was already */
/*     opened by somebody else. */

/*     This is the easy part. Write the next line to the file. */

    ci__1.cierr = 1;
    ci__1.ciunit = unit;
    ci__1.cifmt = "(A)";
    iostat = s_wsfe(&ci__1);
    if (iostat != 0) {
	goto L100002;
    }
    iostat = do_fio(&c__1, line, rtrim_(line, line_len));
    if (iostat != 0) {
	goto L100002;
    }
    iostat = e_wsfe();
L100002:

/*     Well, what happened? Any non-zero value for IOSTAT indicates */
/*     an error. */

    if (iostat != 0) {
	s_copy(error, "WRLINE: An error occurred while attempting to WRITE t"
		"o ", (ftnlen)240, (ftnlen)55);
	suffix_(device, &c__1, error, device_len, (ftnlen)240);
	suffix_(".", &c__0, error, (ftnlen)1, (ftnlen)240);
	suffix_("The value of IOSTAT returned was", &c__2, error, (ftnlen)32, 
		(ftnlen)240);
	suffix_(":", &c__0, error, (ftnlen)1, (ftnlen)240);
	intstr_(&iostat, errstr, (ftnlen)11);
	suffix_(errstr, &c__1, error, (ftnlen)11, (ftnlen)240);
	suffix_(".", &c__0, error, (ftnlen)1, (ftnlen)240);
	s_wsle(&io___16);
	do_lio(&c__9, &c__1, error, (ftnlen)240);
	e_wsle();
	return 0;
    }
    return 0;
/* $Procedure  CLLINE ( Close a device ) */

L_clline:
/* $ Abstract */

/*      Close a device. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*      None. */

/* $ Keywords */

/*      TEXT, FILES, ERROR */

/* $ Declarations */

/*      CHARACTER*(*)        DEVICE */

/* $ Brief_I/O */

/*      VARIABLE  I/O  DESCRIPTION */
/*      --------  ---  -------------------------------------------------- */
/*      DEVICE     I   Device to be closed. */

/* $ Detailed_Input */

/*      DEVICE         is the name of a device which is currently */
/*                     opened for reading or writing. */

/* $ Detailed_Output */

/*      None. */

/* $ Parameters */

/*      None. */

/* $ Exceptions */

/*      This routine is called by SPICELIB error handling routines, so */
/*      it cannot use the normal SPICELIB error signalling mechanism. */
/*      Instead, it writes error messages to the screen if necessary. */

/*      1)  If the device indicated by DEVICE was not opened by WRLINE, */
/*          this routine closes it anyway. */

/*      2)  If the INQUIRE performed by this routine fails, an error */
/*          diagnosis is printed to the screen. */

/* $ Files */

/*      This routin */

/* $ Particulars */

/*      CLLINE closes a device that is currently open. */

/* $ Examples */

/*      1)  Write two lines to the file, SPUD.DAT (VAX file name */
/*          syntax), and then close the file. */

/*          CALL WRLINE ( 'SPUD.DAT', ' This is line 1 ' ) */
/*          CALL WRLINE ( 'SPUD.DAT', ' This is line 2 ' ) */
/*          CALL CLLINE ( 'SPUD.DAT' ) */

/* $ Restrictions */

/*      None. */

/* $ Literature_References */

/*      None. */

/* $ Author_and_Institution */

/*      N.J. Bachman    (JPL) */

/* $ Version */

/* -    SPICELIB Version 4.0.5, 17-JUL-2002 (BVS) */

/*        Added MAC-OSX environments. */

/* -    SPICELIB Version 4.0.4, 08-OCT-1999 (WLT) */

/*        The environment lines were expanded so that the supported */
/*        environments are now explicitely given.  New */
/*        environments are WIN-NT */

/* -    SPICELIB Version 4.0.2, 28-JUL-1999 (WLT) */

/*        The environment lines were expanded so that the supported */
/*        environments are now explicitly given.  New */
/*        environments are PC-DIGITAL, SGI-O32 and SGI-N32. */

/* -    SPICELIB Version 4.0.1, 18-MAR-1999 (WLT) */

/*        The environment lines were expanded so that the supported */
/*        environments are now explicitly given.  Previously, */
/*        environments such as SUN-SUNOS and SUN-SOLARIS were implied */
/*        by the environment label SUN. */

/* -    SPICELIB Version 2.0.1, 10-MAR-1992 (WLT) */

/*        Comment section for permuted index source lines was added */
/*        following the header. */

/* -    SPICELIB Version 2.0.0, 26-MAR-1991 (NJB) */

/*        All occurrences of "PRINT *" have been replaced by */
/*        "WRITE (*,*)". */

/*        Also, this routine now closes the device named by DEVICE */
/*        whether or not the device was opened by WRLINE. */

/* -    SPICELIB Version 1.0.0, 31-JAN-1990 (NJB) */

/* -& */
/* $ Index_Entries */

/*     None. */

/* -& */
/* $ Revisions */

/* -    SPICELIB Version 2.0.0, 26-MAR-1991 (NJB) */

/*        All instances if "PRINT *" have been replaced by "WRITE (*,*)" */
/*        because Language Systems Fortran on the Macintosh interprets */
/*        "PRINT *" in a non-standard manner. */

/*        This routine no longer has to maintain the file database, since */
/*        WRLINE does not use it any more. */

/*        Also, this routine now closes the device named by DEVICE, */
/*        whether or not the device was opened by WRLINE. */

/* -    Beta Version 1.0.1, 08-NOV-1988 (NJB) */

/*        Keywords added. */
/* -& */

/*     Find the unit connected to DEVICE. */

    i__1 = ltrim_(device, device_len) - 1;
    ioin__1.inerr = 1;
    ioin__1.infilen = device_len - i__1;
    ioin__1.infile = device + i__1;
    ioin__1.inex = 0;
    ioin__1.inopen = 0;
    ioin__1.innum = &unit;
    ioin__1.innamed = 0;
    ioin__1.inname = 0;
    ioin__1.inacc = 0;
    ioin__1.inseq = 0;
    ioin__1.indir = 0;
    ioin__1.infmt = 0;
    ioin__1.inform = 0;
    ioin__1.inunf = 0;
    ioin__1.inrecl = 0;
    ioin__1.innrec = 0;
    ioin__1.inblank = 0;
    iostat = f_inqu(&ioin__1);
    if (iostat != 0) {

/*        This is weird.  How can an INQUIRE statement fail, */
/*        if the syntax is correct?  But just in case... */

	s_wsle(&io___17);
	do_lio(&c__9, &c__1, "SPICE(INQUIREFAILED)", (ftnlen)20);
	e_wsle();
	s_wsle(&io___18);
	do_lio(&c__9, &c__1, "CLLINE:  File = ", (ftnlen)16);
	do_lio(&c__9, &c__1, device, device_len);
	do_lio(&c__9, &c__1, "IOSTAT = ", (ftnlen)9);
	do_lio(&c__3, &c__1, (char *)&iostat, (ftnlen)sizeof(integer));
	e_wsle();
	return 0;
    }
    cl__1.cerr = 0;
    cl__1.cunit = unit;
    cl__1.csta = 0;
    f_clos(&cl__1);
    return 0;
} /* wrline_ */
/* $Procedure      M2YEAR ( Determine whether or not a word is a year ) */
logical m2year_(char *word, ftnlen word_len)
{
    /* Initialized data */

    static logical first = TRUE_;

    /* System generated locals */
    integer i__1, i__2, i__3, i__4;
    logical ret_val;

    /* Builtin functions */
    integer s_rnge(char *, integer, char *, integer);

    /* Local variables */
    static integer i__, value;
    extern integer ltrim_(char *, ftnlen);
    static integer i1, i2, i3, i4, length, values[256];
    extern integer qrtrim_(char *, ftnlen);

    /* $ Abstract */

    /*     This function is true if the input string is a year in the */
    /*     sense of META/2. */

    /* $ Disclaimer */

    /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
    /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
    /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
    /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
    /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
    /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
    /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
    /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
    /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
    /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

    /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
    /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
    /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
    /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
    /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
    /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

    /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
    /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
    /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
    /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

    /* $ Required_Reading */

    /*     META/2 a language specification language. */

    /* $ Keywords */

    /*     ALPHANUMERIC */
    /*     ASCII */
    /*     PARSING */
    /*     UTILITY */
    /*     WORD */

    /* $ Declarations */
    /* $ Brief_I/O */

    /*     VARIABLE  I/O  DESCRIPTION */
    /*     --------  ---  -------------------------------------------------- */
    /*     WORD       I   A character string word */

    /*     The function is returned as .TRUE. if word is a META/2 year. */

    /* $ Detailed_Input */

    /*     WORD      is a character string that is assumed to have no */
    /*               spaces between the first and last non-blank characters. */

    /* $ Detailed_Output */

    /*     M2YEAR     returns as .TRUE. if WORD is a META/2 year. */
    /*               Otherwise it is returned .FALSE. */

    /* $ Error_Handling */

    /*     None. */
    /* C */
    /* $ Input_Files */

    /*     None. */

    /* $ Output_Files */

    /*     None. */

    /* $ Particulars */

    /*     This is a utility routine for the subroutine META2.  It */
    /*     determines whether or not a word is a year in the sense */
    /*     of the language META/2. */

    /* $ Examples */

    /*     WORD                                  M2YEAR */
    /*     -------                               ------ */
    /*     SPAM                                  .FALSE. */
    /*     1                                     .TRUE. */
    /*     0.289E19                              .FALSE. */
    /*     0.2728D12                             .FALSE. */
    /*     -12.1892e-5                           .FALSE. */
    /*     12.E29                                .FALSE. */
    /*     12.E291                               .FALSE. */
    /*     1.2E10                                .TRUE. */
    /*     .E12                                  .FALSE. */
    /*     1.2E.12                               .FALSE. */

    /* $ Restrictions */

    /*     None. */

    /* $ Literature_References */

    /*     None. */

    /* $ Author_and_Institution */

    /*     W.L. Taber     (JPL) */
    /*     I.M. Underwood (JPL) */

    /* $ Version */

    /* -     META/2 Configured Version 2.1.0, 29-DEC-1994 (WLT) */

    /*         The computation of the length of the input string */
    /*         was incorrect.  It has been fixed.  It used to be */

    /*            LENGTH = I3 - I1 + 1 */

    /*         Now it is */

    /*            LENGTH = I4 - I1 + 1 */



    /* -     META/2 Configured Version 2.0.0, 9-MAY-1994 (WLT) */

    /*         This is the configured version of the Command Loop */
    /*         software as of May 9, 1994 */


    /* -     META/2 Configured Version 1.0.0, 3-MAY-1994 (WLT) */

    /*         This is the configured version of META/2 */
    /*         software as of May 3, 1994 */


    /*     Version B1.0.0, 22-MAR-1988 (WLT) (IMU) */

    /* -& */

    /*     SPICELIB functions */


    /*     Local variables */

    if (first) {
        first = FALSE_;

        /*        We will construct a value for the string by taking */
        /*        the non-blank portion and computing the value assuming */
        /*        that the first non-blank is a digit with the appropriate */
        /*        power of 10 attached.  Since all non-digit characters */
        /*        will have values of 1000, we will get a value greater */
        /*        than 1000 if any non-digit characters are present. */

        for (i__ = 0; i__ <= 255; ++i__) {
            values[(i__1 = i__) < 256 && 0 <= i__1 ? i__1 : s_rnge("values",
                    i__1, "m2year_", (ftnlen)182)] = 10000;
        }
        values[(i__1 = '0') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)185)] = 0;
        values[(i__1 = '1') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)186)] = 1;
        values[(i__1 = '2') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)187)] = 2;
        values[(i__1 = '3') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)188)] = 3;
        values[(i__1 = '4') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)189)] = 4;
        values[(i__1 = '5') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)190)] = 5;
        values[(i__1 = '6') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)191)] = 6;
        values[(i__1 = '7') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)192)] = 7;
        values[(i__1 = '8') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)193)] = 8;
        values[(i__1 = '9') < 256 && 0 <= i__1 ? i__1 : s_rnge("values", i__1,
                "m2year_", (ftnlen)194)] = 9;
    }

    /*     Make sure the string has the right length. */

    i1 = ltrim_(word, word_len);
    i4 = qrtrim_(word, word_len);
    length = i4 - i1 + 1;

    /*     Rule out the goofy cases that NPARSD will allow. */

    if (length != 4) {
        value = 10000;
    } else {
        i2 = i1 + 1;
        i3 = i2 + 1;
        value = values[(i__1 = *(unsigned char *)&word[i1 - 1]) < 256 && 0 <=
                       i__1 ? i__1 : s_rnge("values", i__1, "m2year_", (ftnlen)218)]
                * 1000 + values[(i__2 = *(unsigned char *)&word[i2 - 1]) <
                                256 && 0 <= i__2 ? i__2 : s_rnge("values", i__2, "m2year_", (
                                            ftnlen)218)] * 100 + values[(i__3 = *(unsigned char *)&word[
                                                    i3 - 1]) < 256 && 0 <= i__3 ? i__3 : s_rnge("values", i__3,
                                                            "m2year_", (ftnlen)218)] * 10 + values[(i__4 = *(unsigned
                                                                    char *)&word[i4 - 1]) < 256 && 0 <= i__4 ? i__4 : s_rnge(
                                                                            "values", i__4, "m2year_", (ftnlen)218)];
    }

    /*     That's all just make sure that the value is within the */
    /*     bound required of a year. */

    ret_val = value >= 1000 && value <= 3000;
    return ret_val;
} /* m2year_ */
Exemple #4
0
/* $Procedure ZZSPKZP0 ( S/P Kernel, easy position ) */
/* Subroutine */ int zzspkzp0_(integer *targ, doublereal *et, char *ref, char 
	*abcorr, integer *obs, doublereal *ptarg, doublereal *lt, ftnlen 
	ref_len, ftnlen abcorr_len)
{
    /* Initialized data */

    static logical first = TRUE_;

    /* System generated locals */
    doublereal d__1;

    /* Local variables */
    static integer fj2000;
    extern /* Subroutine */ int zzrefch0_(integer *, integer *, doublereal *, 
	    doublereal *), zzspkpa0_(integer *, doublereal *, char *, 
	    doublereal *, char *, doublereal *, doublereal *, ftnlen, ftnlen);
    static doublereal temp[3], sobs[6];
    extern /* Subroutine */ int zzspkgp0_(integer *, doublereal *, char *, 
	    integer *, doublereal *, doublereal *, ftnlen), zzspksb0_(integer 
	    *, doublereal *, char *, doublereal *, ftnlen);
    static integer type__;
    static logical xmit;
    static integer i__;
    extern /* Subroutine */ int chkin_(char *, ftnlen);
    extern logical eqchr_(char *, char *, ftnlen, ftnlen);
    extern /* Subroutine */ int errch_(char *, char *, ftnlen, ftnlen);
    static logical found;
    extern integer ltrim_(char *, ftnlen);
    static doublereal xform[9]	/* was [3][3] */;
    extern logical eqstr_(char *, char *, ftnlen, ftnlen);
    static doublereal postn[3];
    extern logical failed_(void);
    static integer center;
    extern /* Subroutine */ int namfrm_(char *, integer *, ftnlen), frinfo_(
	    integer *, integer *, integer *, integer *, logical *);
    static doublereal ltcent;
    extern /* Subroutine */ int sigerr_(char *, ftnlen);
    static integer reqfrm, typeid;
    extern /* Subroutine */ int chkout_(char *, ftnlen), setmsg_(char *, 
	    ftnlen);
    extern logical return_(void);
    extern /* Subroutine */ int mxv_(doublereal *, doublereal *, doublereal *)
	    ;

/* $ Abstract */

/*     SPICE Private routine intended solely for the support of SPICE */
/*     routines.  Users should not call this routine directly due */
/*     to the volatile nature of this routine. */

/*     Return the position of a target body relative to an observing */
/*     body, optionally corrected for light time (planetary aberration) */
/*     and stellar aberration. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     SPK */
/*     NAIF_IDS */
/*     FRAMES */
/*     TIME */

/* $ Keywords */

/*     EPHEMERIS */

/* $ Declarations */
/* $ Abstract */

/*     The parameters below form an enumerated list of the recognized */
/*     frame types.  They are: INERTL, PCK, CK, TK, DYN.  The meanings */
/*     are outlined below. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Parameters */

/*     INERTL      an inertial frame that is listed in the routine */
/*                 CHGIRF and that requires no external file to */
/*                 compute the transformation from or to any other */
/*                 inertial frame. */

/*     PCK         is a frame that is specified relative to some */
/*                 INERTL frame and that has an IAU model that */
/*                 may be retrieved from the PCK system via a call */
/*                 to the routine TISBOD. */

/*     CK          is a frame defined by a C-kernel. */

/*     TK          is a "text kernel" frame.  These frames are offset */
/*                 from their associated "relative" frames by a */
/*                 constant rotation. */

/*     DYN         is a "dynamic" frame.  These currently are */
/*                 parameterized, built-in frames where the full frame */
/*                 definition depends on parameters supplied via a */
/*                 frame kernel. */

/* $ Author_and_Institution */

/*     N.J. Bachman    (JPL) */
/*     W.L. Taber      (JPL) */

/* $ Literature_References */

/*     None. */

/* $ Version */

/* -    SPICELIB Version 3.0.0, 28-MAY-2004 (NJB) */

/*       The parameter DYN was added to support the dynamic frame class. */

/* -    SPICELIB Version 2.0.0, 12-DEC-1996 (WLT) */

/*        Various unused frames types were removed and the */
/*        frame time TK was added. */

/* -    SPICELIB Version 1.0.0, 10-DEC-1995 (WLT) */

/* -& */
/* $ Brief_I/O */

/*     Variable  I/O  Description */
/*     --------  ---  -------------------------------------------------- */
/*     TARG       I   Target body NAIF ID code. */
/*     ET         I   Observer epoch. */
/*     REF        I   Reference frame of output position vector. */
/*     ABCORR     I   Aberration correction flag. */
/*     OBS        I   Observing body NAIF ID code. */
/*     PTARG      O   Position of target. */
/*     LT         O   One way light time between observer and target. */

/* $ Detailed_Input */

/*     TARG        is the NAIF ID code for a target body.  The target */
/*                 and observer define a position vector which points */
/*                 from the observer to the target. */

/*     ET          is the ephemeris time, expressed as seconds past */
/*                 J2000 TDB, at which the position of the target body */
/*                 relative to the observer is to be computed.  ET */
/*                 refers to time at the observer's location. */

/*     REF         is the name of the reference frame relative to which */
/*                 the output position vector should be expressed. This */
/*                 may be any frame supported by the SPICE system, */
/*                 including built-in frames (documented in the Frames */
/*                 Required Reading) and frames defined by a loaded */
/*                 frame kernel (FK). */

/*                 When REF designates a non-inertial frame, the */
/*                 orientation of the frame is evaluated at an epoch */
/*                 dependent on the selected aberration correction. See */
/*                 the description of the output position vector PTARG */
/*                 for details. */

/*     ABCORR      indicates the aberration corrections to be applied to */
/*                 the position of the target body to account for */
/*                 one-way light time and stellar aberration.  See the */
/*                 discussion in the Particulars section for */
/*                 recommendations on how to choose aberration */
/*                 corrections. */

/*                 ABCORR may be any of the following: */

/*                    'NONE'     Apply no correction. Return the */
/*                               geometric position of the target body */
/*                               relative to the observer. */

/*                 The following values of ABCORR apply to the */
/*                 "reception" case in which photons depart from the */
/*                 target's location at the light-time corrected epoch */
/*                 ET-LT and *arrive* at the observer's location at ET: */

/*                    'LT'       Correct for one-way light time (also */
/*                               called "planetary aberration") using a */
/*                               Newtonian formulation. This correction */
/*                               yields the position of the target at */
/*                               the moment it emitted photons arriving */
/*                               at the observer at ET. */

/*                               The light time correction uses an */
/*                               iterative solution of the light time */
/*                               equation (see Particulars for details). */
/*                               The solution invoked by the 'LT' option */
/*                               uses one iteration. */

/*                    'LT+S'     Correct for one-way light time and */
/*                               stellar aberration using a Newtonian */
/*                               formulation. This option modifies the */
/*                               position obtained with the 'LT' option */
/*                               to account for the observer's velocity */
/*                               relative to the solar system */
/*                               barycenter. The result is the apparent */
/*                               position of the target---the position */
/*                               as seen by the observer. */

/*                    'CN'       Converged Newtonian light time */
/*                               correction.  In solving the light time */
/*                               equation, the 'CN' correction iterates */
/*                               until the solution converges (three */
/*                               iterations on all supported platforms). */

/*                               The 'CN' correction typically does not */
/*                               substantially improve accuracy because */
/*                               the errors made by ignoring */
/*                               relativistic effects may be larger than */
/*                               the improvement afforded by obtaining */
/*                               convergence of the light time solution. */
/*                               The 'CN' correction computation also */
/*                               requires a significantly greater number */
/*                               of CPU cycles than does the */
/*                               one-iteration light time correction. */

/*                    'CN+S'     Converged Newtonian light time */
/*                               and stellar aberration corrections. */


/*                 The following values of ABCORR apply to the */
/*                 "transmission" case in which photons *depart* from */
/*                 the observer's location at ET and arrive at the */
/*                 target's location at the light-time corrected epoch */
/*                 ET+LT: */

/*                    'XLT'      "Transmission" case:  correct for */
/*                               one-way light time using a Newtonian */
/*                               formulation. This correction yields the */
/*                               position of the target at the moment it */
/*                               receives photons emitted from the */
/*                               observer's location at ET. */

/*                    'XLT+S'    "Transmission" case:  correct for */
/*                               one-way light time and stellar */
/*                               aberration using a Newtonian */
/*                               formulation  This option modifies the */
/*                               position obtained with the 'XLT' option */
/*                               to account for the observer's velocity */
/*                               relative to the solar system */
/*                               barycenter. The position component of */
/*                               the computed target position indicates */
/*                               the direction that photons emitted from */
/*                               the observer's location must be "aimed" */
/*                               to hit the target. */

/*                    'XCN'      "Transmission" case:  converged */
/*                               Newtonian light time correction. */

/*                    'XCN+S'    "Transmission" case:  converged */
/*                               Newtonian light time and stellar */
/*                               aberration corrections. */


/*                 Neither special nor general relativistic effects are */
/*                 accounted for in the aberration corrections applied */
/*                 by this routine. */

/*                 Case and blanks are not significant in the string */
/*                 ABCORR. */

/*     OBS         is the NAIF ID code for the observing body. */

/* $ Detailed_Output */

/*     PTARG       is a Cartesian 3-vector representing the position of */
/*                 the target body relative to the specified observer. */
/*                 PTARG is corrected for the specified aberrations, and */
/*                 is expressed with respect to the reference frame */
/*                 specified by REF.  The three components of PTARG */
/*                 represent the x-, y- and z-components of the target's */
/*                 position. */

/*                 PTARG points from the observer's location at ET to */
/*                 the aberration-corrected location of the target. */
/*                 Note that the sense of this position vector is */
/*                 independent of the direction of radiation travel */
/*                 implied by the aberration correction. */

/*                 Units are always km. */

/*                 Non-inertial frames are treated as follows: letting */
/*                 LTCENT be the one-way light time between the observer */
/*                 and the central body associated with the frame, the */
/*                 orientation of the frame is evaluated at ET-LTCENT, */
/*                 ET+LTCENT, or ET depending on whether the requested */
/*                 aberration correction is, respectively, for received */
/*                 radiation, transmitted radiation, or is omitted. */
/*                 LTCENT is computed using the method indicated by */
/*                 ABCORR. */

/*     LT          is the one-way light time between the observer and */
/*                 target in seconds.  If the target position is */
/*                 corrected for aberrations, then LT is the one-way */
/*                 light time between the observer and the light time */
/*                 corrected target location. */

/* $ Parameters */

/*     None. */

/* $ Exceptions */

/*     1) If name of target or observer cannot be translated to its */
/*        NAIF ID code, the error SPICE(IDCODENOTFOUND) is signaled. */

/*     2) If the reference frame REF is not a recognized reference */
/*        frame the error 'SPICE(UNKNOWNFRAME)' is signaled. */

/*     3) If the loaded kernels provide insufficient data to */
/*        compute the requested position vector, the deficiency will */
/*        be diagnosed by a routine in the call tree of this routine. */

/*     4) If an error occurs while reading an SPK or other kernel file, */
/*        the error  will be diagnosed by a routine in the call tree */
/*        of this routine. */

/* $ Files */

/*     This routine computes positions using SPK files that have been */
/*     loaded into the SPICE system, normally via the kernel loading */
/*     interface routine FURNSH. See the routine FURNSH and the SPK */
/*     and KERNEL Required Reading for further information on loading */
/*     (and unloading) kernels. */

/*     If the output position PTARG is to be expressed relative to a */
/*     non-inertial frame, or if any of the ephemeris data used to */
/*     compute PTARG are expressed relative to a non-inertial frame in */
/*     the SPK files providing those data, additional kernels may be */
/*     needed to enable the reference frame transformations required to */
/*     compute the position.  Normally these additional kernels are PCK */
/*     files or frame kernels.  Any such kernels must already be loaded */
/*     at the time this routine is called. */

/* $ Particulars */

/*     This routine is part of the user interface to the SPICE ephemeris */
/*     system.  It allows you to retrieve position information for any */
/*     ephemeris object relative to any other in a reference frame that */
/*     is convenient for further computations. */


/*     Aberration corrections */
/*     ====================== */

/*     In space science or engineering applications one frequently */
/*     wishes to know where to point a remote sensing instrument, such */
/*     as an optical camera or radio antenna, in order to observe or */
/*     otherwise receive radiation from a target.  This pointing problem */
/*     is complicated by the finite speed of light:  one needs to point */
/*     to where the target appears to be as opposed to where it actually */
/*     is at the epoch of observation.  We use the adjectives */
/*     "geometric," "uncorrected," or "true" to refer to an actual */
/*     position or state of a target at a specified epoch.  When a */
/*     geometric position or state vector is modified to reflect how it */
/*     appears to an observer, we describe that vector by any of the */
/*     terms "apparent," "corrected," "aberration corrected," or "light */
/*     time and stellar aberration corrected." The SPICE Toolkit can */
/*     correct for two phenomena affecting the apparent location of an */
/*     object:  one-way light time (also called "planetary aberration") */
/*     and stellar aberration. */

/*     One-way light time */
/*     ------------------ */

/*     Correcting for one-way light time is done by computing, given an */
/*     observer and observation epoch, where a target was when the */
/*     observed photons departed the target's location.  The vector from */
/*     the observer to this computed target location is called a "light */
/*     time corrected" vector.  The light time correction depends on the */
/*     motion of the target relative to the solar system barycenter, but */
/*     it is independent of the velocity of the observer relative to the */
/*     solar system barycenter. Relativistic effects such as light */
/*     bending and gravitational delay are not accounted for in the */
/*     light time correction performed by this routine. */

/*     Stellar aberration */
/*     ------------------ */

/*     The velocity of the observer also affects the apparent location */
/*     of a target:  photons arriving at the observer are subject to a */
/*     "raindrop effect" whereby their velocity relative to the observer */
/*     is, using a Newtonian approximation, the photons' velocity */
/*     relative to the solar system barycenter minus the velocity of the */
/*     observer relative to the solar system barycenter.  This effect is */
/*     called "stellar aberration."  Stellar aberration is independent */
/*     of the velocity of the target.  The stellar aberration formula */
/*     used by this routine does not include (the much smaller) */
/*     relativistic effects. */

/*     Stellar aberration corrections are applied after light time */
/*     corrections:  the light time corrected target position vector is */
/*     used as an input to the stellar aberration correction. */

/*     When light time and stellar aberration corrections are both */
/*     applied to a geometric position vector, the resulting position */
/*     vector indicates where the target "appears to be" from the */
/*     observer's location. */

/*     As opposed to computing the apparent position of a target, one */
/*     may wish to compute the pointing direction required for */
/*     transmission of photons to the target.  This also requires */
/*     correction of the geometric target position for the effects of */
/*     light time and stellar aberration, but in this case the */
/*     corrections are computed for radiation traveling *from* the */
/*     observer to the target. */

/*     The "transmission" light time correction yields the target's */
/*     location as it will be when photons emitted from the observer's */
/*     location at ET arrive at the target.  The transmission stellar */
/*     aberration correction is the inverse of the traditional stellar */
/*     aberration correction:  it indicates the direction in which */
/*     radiation should be emitted so that, using a Newtonian */
/*     approximation, the sum of the velocity of the radiation relative */
/*     to the observer and of the observer's velocity, relative to the */
/*     solar system barycenter, yields a velocity vector that points in */
/*     the direction of the light time corrected position of the target. */

/*     One may object to using the term "observer" in the transmission */
/*     case, in which radiation is emitted from the observer's location. */
/*     The terminology was retained for consistency with earlier */
/*     documentation. */

/*     Below, we indicate the aberration corrections to use for some */
/*     common applications: */

/*        1) Find the apparent direction of a target for a remote-sensing */
/*           observation. */

/*              Use 'LT+S':  apply both light time and stellar */
/*              aberration corrections. */

/*           Note that using light time corrections alone ('LT') is */
/*           generally not a good way to obtain an approximation to an */
/*           apparent target vector:  since light time and stellar */
/*           aberration corrections often partially cancel each other, */
/*           it may be more accurate to use no correction at all than to */
/*           use light time alone. */


/*        2) Find the corrected pointing direction to radiate a signal */
/*           to a target.  This computation is often applicable for */
/*           implementing communications sessions. */

/*              Use 'XLT+S':  apply both light time and stellar */
/*              aberration corrections for transmission. */


/*        3) Compute the apparent position of a target body relative */
/*           to a star or other distant object. */

/*              Use 'LT' or 'LT+S' as needed to match the correction */
/*              applied to the position of the distant object.  For */
/*              example, if a star position is obtained from a catalog, */
/*              the position vector may not be corrected for stellar */
/*              aberration.  In this case, to find the angular */
/*              separation of the star and the limb of a planet, the */
/*              vector from the observer to the planet should be */
/*              corrected for light time but not stellar aberration. */


/*        4) Obtain an uncorrected position vector derived directly from */
/*           data in an SPK file. */

/*              Use 'NONE'. */


/*        5) Use a geometric position vector as a low-accuracy estimate */
/*           of the apparent position for an application where execution */
/*           speed is critical. */

/*              Use 'NONE'. */


/*        6) While this routine cannot perform the relativistic */
/*           aberration corrections required to compute positions */
/*           with the highest possible accuracy, it can supply the */
/*           geometric positions required as inputs to these */
/*           computations. */

/*              Use 'NONE', then apply high-accuracy aberration */
/*              corrections (not available in the SPICE Toolkit). */


/*     Below, we discuss in more detail how the aberration corrections */
/*     applied by this routine are computed. */

/*        Geometric case */
/*        ============== */

/*        ZZSPKZP0 begins by computing the geometric position T(ET) of */
/*        the target body relative to the solar system barycenter (SSB). */
/*        Subtracting the geometric position of the observer O(ET) gives */
/*        the geometric position of the target body relative to the */
/*        observer. The one-way light time, LT, is given by */

/*                  | T(ET) - O(ET) | */
/*           LT = ------------------- */
/*                          c */

/*        The geometric relationship between the observer, target, and */
/*        solar system barycenter is as shown: */


/*           SSB ---> O(ET) */
/*            |      / */
/*            |     / */
/*            |    / */
/*            |   /  T(ET) - O(ET) */
/*            V  V */
/*           T(ET) */


/*        The returned position vector is */

/*           T(ET) - O(ET) */



/*        Reception case */
/*        ============== */

/*        When any of the options 'LT', 'CN', 'LT+S', 'CN+S' is selected */
/*        for ABCORR, ZZSPKZP0 computes the position of the target body */
/*        at epoch ET-LT, where LT is the one-way light time.  Let T(t) */
/*        and O(t) represent the positions of the target and observer */
/*        relative to the solar system barycenter at time t; then LT is */
/*        the solution of the light-time equation */

/*                  | T(ET-LT) - O(ET) | */
/*           LT = ------------------------                            (1) */
/*                           c */

/*        The ratio */

/*            | T(ET) - O(ET) | */
/*          ---------------------                                     (2) */
/*                    c */

/*        is used as a first approximation to LT; inserting (2) into the */
/*        right hand side of the light-time equation (1) yields the */
/*        "one-iteration" estimate of the one-way light time ("LT"). */
/*        Repeating the process until the estimates of LT converge */
/*        yields the "converged Newtonian" light time estimate ("CN"). */

/*        Subtracting the geometric position of the observer O(ET) gives */
/*        the position of the target body relative to the observer: */
/*        T(ET-LT) - O(ET). */

/*           SSB ---> O(ET) */
/*            | \     | */
/*            |  \    | */
/*            |   \   | T(ET-LT) - O(ET) */
/*            |    \  | */
/*            V     V V */
/*           T(ET)  T(ET-LT) */

/*        The light time corrected position vector is */

/*           T(ET-LT) - O(ET) */

/*        If correction for stellar aberration is requested, the target */
/*        position is rotated toward the solar system barycenter- */
/*        relative velocity vector of the observer.  The rotation is */
/*        computed as follows: */

/*           Let r be the light time corrected vector from the observer */
/*           to the object, and v be the velocity of the observer with */
/*           respect to the solar system barycenter. Let w be the angle */
/*           between them. The aberration angle phi is given by */

/*              sin(phi) = v sin(w) / c */

/*           Let h be the vector given by the cross product */

/*              h = r X v */

/*           Rotate r by phi radians about h to obtain the apparent */
/*           position of the object. */


/*        Transmission case */
/*        ================== */

/*        When any of the options 'XLT', 'XCN', 'XLT+S', 'XCN+S' is */
/*        selected, ZZSPKZP0 computes the position of the target body T */
/*        at epoch ET+LT, where LT is the one-way light time.  LT is the */
/*        solution of the light-time equation */

/*                  | T(ET+LT) - O(ET) | */
/*           LT = ------------------------                            (3) */
/*                            c */

/*        Subtracting the geometric position of the observer, O(ET), */
/*        gives the position of the target body relative to the */
/*        observer: T(ET-LT) - O(ET). */

/*                   SSB --> O(ET) */
/*                  / |    * */
/*                 /  |  *  T(ET+LT) - O(ET) */
/*                /   |* */
/*               /   *| */
/*              V  V  V */
/*          T(ET+LT)  T(ET) */

/*        The light-time corrected position vector is */

/*           T(ET+LT) - O(ET) */

/*        If correction for stellar aberration is requested, the target */
/*        position is rotated away from the solar system barycenter- */
/*        relative velocity vector of the observer. The rotation is */
/*        computed as in the reception case, but the sign of the */
/*        rotation angle is negated. */


/*     Precision of light time corrections */
/*     =================================== */

/*        Corrections using one iteration of the light time solution */
/*        ---------------------------------------------------------- */

/*        When the requested aberration correction is 'LT', 'LT+S', */
/*        'XLT', or 'XLT+S', only one iteration is performed in the */
/*        algorithm used to compute LT. */

/*        The relative error in this computation */

/*           | LT_ACTUAL - LT_COMPUTED |  /  LT_ACTUAL */

/*        is at most */

/*            (V/C)**2 */
/*           ---------- */
/*            1 - (V/C) */

/*        which is well approximated by (V/C)**2, where V is the */
/*        velocity of the target relative to an inertial frame and C is */
/*        the speed of light. */

/*        For nearly all objects in the solar system V is less than 60 */
/*        km/sec.  The value of C is 300000 km/sec.  Thus the one */
/*        iteration solution for LT has a potential relative error of */
/*        not more than 4*10**-8.  This is a potential light time error */
/*        of approximately 2*10**-5 seconds per astronomical unit of */
/*        distance separating the observer and target.  Given the bound */
/*        on V cited above: */

/*           As long as the observer and target are */
/*           separated by less than 50 astronomical units, */
/*           the error in the light time returned using */
/*           the one-iteration light time corrections */
/*           is less than 1 millisecond. */


/*        Converged corrections */
/*        --------------------- */

/*        When the requested aberration correction is 'CN', 'CN+S', */
/*        'XCN', or 'XCN+S', three iterations are performed in the */
/*        computation of LT.  The relative error present in this */
/*        solution is at most */

/*            (V/C)**4 */
/*           ---------- */
/*            1 - (V/C) */

/*        which is well approximated by (V/C)**4.  Mathematically the */
/*        precision of this computation is better than a nanosecond for */
/*        any pair of objects in the solar system. */

/*        However, to model the actual light time between target and */
/*        observer one must take into account effects due to general */
/*        relativity.  These may be as high as a few hundredths of a */
/*        millisecond for some objects. */

/*        When one considers the extra time required to compute the */
/*        converged Newtonian light time (the state of the target */
/*        relative to the solar system barycenter is looked up three */
/*        times instead of once) together with the real gain in */
/*        accuracy, it seems unlikely that you will want to request */
/*        either the "CN" or "CN+S" light time corrections.  However, */
/*        these corrections can be useful for testing situations where */
/*        high precision (as opposed to accuracy) is required. */


/*     Relativistic Corrections */
/*     ========================= */

/*     This routine does not attempt to perform either general or */
/*     special relativistic corrections in computing the various */
/*     aberration corrections.  For many applications relativistic */
/*     corrections are not worth the expense of added computation */
/*     cycles.  If however, your application requires these additional */
/*     corrections we suggest you consult the astronomical almanac (page */
/*     B36) for a discussion of how to carry out these corrections. */


/* $ Examples */

/*     1)  Load a planetary ephemeris SPK, then look up a series of */
/*         geometric positions of the moon relative to the earth, */
/*         referenced to the J2000 frame. */


/*               IMPLICIT NONE */
/*         C */
/*         C     Local constants */
/*         C */
/*               CHARACTER*(*)         FRAME */
/*               PARAMETER           ( FRAME  = 'J2000' ) */

/*               CHARACTER*(*)         ABCORR */
/*               PARAMETER           ( ABCORR = 'NONE' ) */

/*         C */
/*         C     The name of the SPK file shown here is fictitious; */
/*         C     you must supply the name of an SPK file available */
/*         C     on your own computer system. */
/*         C */
/*               CHARACTER*(*)         SPK */
/*               PARAMETER           ( SPK    = 'planet.bsp' ) */

/*         C */
/*         C     ET0 represents the date 2000 Jan 1 12:00:00 TDB. */
/*         C */
/*               DOUBLE PRECISION      ET0 */
/*               PARAMETER           ( ET0    = 0.0D0 ) */

/*         C */
/*         C     Use a time step of 1 hour; look up 100 positions. */
/*         C */
/*               DOUBLE PRECISION      STEP */
/*               PARAMETER           ( STEP   = 3600.0D0 ) */

/*               INTEGER               MAXITR */
/*               PARAMETER           ( MAXITR = 100 ) */

/*         C */
/*         C     The NAIF IDs of the earth and moon are 399 and 301 */
/*         C     respectively. */
/*         C */
/*               INTEGER               OBSRVR */
/*               PARAMETER           ( OBSRVR = 399 ) */

/*               INTEGER               TARGET */
/*               PARAMETER           ( TARGET = 301 ) */

/*         C */
/*         C     Local variables */
/*         C */
/*               DOUBLE PRECISION      ET */
/*               DOUBLE PRECISION      LT */
/*               DOUBLE PRECISION      POS ( 3 ) */

/*               INTEGER               I */

/*         C */
/*         C     Load the SPK file. */
/*         C */
/*               CALL FURNSH ( SPK ) */

/*         C */
/*         C     Step through a series of epochs, looking up a */
/*         C     position vector at each one. */
/*         C */
/*               DO I = 1, MAXITR */

/*                  ET = ET0 + (I-1)*STEP */

/*                  CALL ZZSPKZP0 ( TARGET, ET, FRAME, ABCORR, OBSRVR, */
/*              .                 POS,    LT                        ) */

/*                  WRITE (*,*) 'ET = ', ET */
/*                  WRITE (*,*) 'J2000 x-position (km):   ', POS(1) */
/*                  WRITE (*,*) 'J2000 y-position (km):   ', POS(2) */
/*                  WRITE (*,*) 'J2000 z-position (km):   ', POS(3) */
/*                  WRITE (*,*) ' ' */

/*               END DO */

/*               END */


/* $ Restrictions */

/*     1) SPICE Private routine. */

/* $ Literature_References */

/*     SPK Required Reading. */

/* $ Author_and_Institution */

/*     C.H. Acton      (JPL) */
/*     B.V. Semenov    (JPL) */
/*     N.J. Bachman    (JPL) */
/*     W.L. Taber      (JPL) */

/* $ Version */

/* -    SPICELIB Version 1.0.0, 05-JAN-2005 (NJB) */

/*        Based on SPICELIB Version 3.1.0, 05-JAN-2005 (NJB) */

/* -& */
/* $ Index_Entries */

/*     using body names get position relative to an observer */
/*     get position relative observer corrected for aberrations */
/*     read ephemeris data */
/*     read trajectory data */

/* -& */
/* $ Revisions */

/* -& */


/*     SPICELIB functions */


/*     Local parameters */


/*     Local variables */


/*     Saved variables */


/*     Initial values */


/*     Standard SPICE error handling. */

    if (return_()) {
	return 0;
    } else {
	chkin_("ZZSPKZP0", (ftnlen)8);
    }

/*     Get the frame id for J2000 on the first call to this routine. */

    if (first) {
	first = FALSE_;
	namfrm_("J2000", &fj2000, (ftnlen)5);
    }

/*     Decide whether the aberration correction is for received or */
/*     transmitted radiation. */

    i__ = ltrim_(abcorr, abcorr_len);
    xmit = eqchr_(abcorr + (i__ - 1), "X", (ftnlen)1, (ftnlen)1);

/*     If we only want geometric positions, then compute just that. */

/*     Otherwise, compute the state of the observer relative to */
/*     the SSB.  Then feed that position into ZZSPKPA0 to compute the */
/*     apparent position of the target body relative to the observer */
/*     with the requested aberration corrections. */

    if (eqstr_(abcorr, "NONE", abcorr_len, (ftnlen)4)) {
	zzspkgp0_(targ, et, ref, obs, ptarg, lt, ref_len);
    } else {

/*        Get the auxiliary information about the requested output */
/*        frame. */

	namfrm_(ref, &reqfrm, ref_len);
	if (reqfrm == 0) {
	    setmsg_("The requested output frame '#' is not recognized by the"
		    " reference frame subsystem.  Please check that the appro"
		    "priate kernels have been loaded and that you have correc"
		    "tly entered the name of the output frame. ", (ftnlen)209);
	    errch_("#", ref, (ftnlen)1, ref_len);
	    sigerr_("SPICE(UNKNOWNFRAME)", (ftnlen)19);
	    chkout_("ZZSPKZP0", (ftnlen)8);
	    return 0;
	}
	frinfo_(&reqfrm, &center, &type__, &typeid, &found);

/*        If we are dealing with an inertial frame, we can simply */
/*        call ZZSPKSB0, ZZSPKPA0 and return. */

	if (type__ == 1) {
	    zzspksb0_(obs, et, ref, sobs, ref_len);
	    zzspkpa0_(targ, et, ref, sobs, abcorr, ptarg, lt, ref_len, 
		    abcorr_len);
	    chkout_("ZZSPKZP0", (ftnlen)8);
	    return 0;
	}

/*        Still here? */

/*        We are dealing with a non-inertial frame.  But we need to */
/*        do light time and stellar aberration in an inertial frame. */
/*        Get the "apparent" position of TARG in the intermediary */
/*        inertial reference frame J2000. */

/*        We also need the light time to the center of the frame. */

	zzspksb0_(obs, et, "J2000", sobs, (ftnlen)5);
	zzspkpa0_(targ, et, "J2000", sobs, abcorr, postn, lt, (ftnlen)5, 
		abcorr_len);
	if (failed_()) {
	    chkout_("ZZSPKZP0", (ftnlen)8);
	    return 0;
	}
	if (center == *obs) {
	    ltcent = 0.;
	} else if (center == *targ) {
	    ltcent = *lt;
	} else {
	    zzspkpa0_(&center, et, "J2000", sobs, abcorr, temp, &ltcent, (
		    ftnlen)5, abcorr_len);
	}

/*        If something went wrong (like we couldn't get the position of */
/*        the center relative to the observer) now it is time to quit. */

	if (failed_()) {
	    chkout_("ZZSPKZP0", (ftnlen)8);
	    return 0;
	}

/*        If the aberration corrections are for transmission, negate */
/*        the light time, since we wish to compute the orientation */
/*        of the non-inertial frame at an epoch later than ET by */
/*        the one-way light time. */

	if (xmit) {
	    ltcent = -ltcent;
	}

/*        Get the rotation from J2000 to the requested frame */
/*        and convert the position. */

	d__1 = *et - ltcent;
	zzrefch0_(&fj2000, &reqfrm, &d__1, xform);
	if (failed_()) {
	    chkout_("ZZSPKZP0", (ftnlen)8);
	    return 0;
	}
	mxv_(xform, postn, ptarg);
    }
    chkout_("ZZSPKZP0", (ftnlen)8);
    return 0;
} /* zzspkzp0_ */
/* $Procedure      M2ALPH ( Determine if a word starts with a letter) */
logical m2alph_(char *word, ftnlen word_len)
{
    /* System generated locals */
    logical ret_val;

    /* Builtin functions */
    logical l_le(char *, char *, ftnlen, ftnlen), l_ge(char *, char *, ftnlen,
	     ftnlen);

    /* Local variables */
    static integer i__;
    extern integer ltrim_(char *, ftnlen);

/* $ Abstract */

/*     This function is true if the input string begins with an */
/*     alphabetic character. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     META/2 a language specification language. */

/* $ Keywords */

/*     ALPHANUMERIC */
/*     ASCII */
/*     PARSING */
/*     UTILITY */
/*     WORD */

/* $ Declarations */
/* $ Brief_I/O */

/*     VARIABLE  I/O  DESCRIPTION */
/*     --------  ---  -------------------------------------------------- */
/*     WORD       I   A character string word */

/*     The function is returned as .TRUE. if word is an META/2 alpha */
/*     word. */

/* $ Detailed_Input */

/*     WORD      is a character string that is assumed to have no */
/*               spaces between the first and last non-blank characters. */

/* $ Detailed_Output */

/*     M2ALPH    returns as .TRUE. if WORD starts with an alphabetic */
/*               character.  Otherwise it is returned .FALSE. */

/* $ Error_Handling */

/*     None. */
/* C */
/* $ Input_Files */

/*     None. */

/* $ Output_Files */

/*     None. */

/* $ Particulars */

/*     This is a utility routine for the subroutine META2.  It */
/*     determines whether or not a word is an alpha word in the sense */
/*     of the language META/2. */

/* $ Examples */

/*     WORD                                  M2ALPH */
/*     -------                               ------ */
/*     SPAM                                  .TRUE. */
/*     _SPUD                                 .FALSE. */
/*     THE_QUICK_BROWN_FOX                   .TRUE. */
/*     THE_FIRST_TIME_EVERY_I_SAW_YOUR_FACE  .TRUE. */
/*     WHO?_ME?                              .TRUE. */
/*     D!#@!@#!                              .TRUE. */

/* $ Restrictions */

/*     None. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     W.L. Taber     (JPL) */
/*     I.M. Underwood (JPL) */

/* $ Version */

/* -     META/2 Configured Version 2.0.0, 9-MAY-1994 (WLT) */

/*         This is the configured version of the Command Loop */
/*         software as of May 9, 1994 */


/* -     META/2 Configured Version 1.0.0, 3-MAY-1994 (WLT) */

/*         This is the configured version of META/2 */
/*         software as of May 3, 1994 */


/*     Version B1.0.0, 22-MAR-1988 (WLT) (IMU) */

/* -& */

/*     SPICELIB functions */


/*     Local variables */


/*     Make sure the string has the right length. */

    i__ = ltrim_(word, word_len);
    ret_val = l_le("A", word + (i__ - 1), (ftnlen)1, (ftnlen)1) && l_ge("Z", 
	    word + (i__ - 1), (ftnlen)1, (ftnlen)1) || l_le("a", word + (i__ 
	    - 1), (ftnlen)1, (ftnlen)1) && l_ge("z", word + (i__ - 1), (
	    ftnlen)1, (ftnlen)1);
    return ret_val;
} /* m2alph_ */
/* Subroutine */ int kerman_0_(int n__, char *commnd, char *infile__, char *
	error, ftnlen commnd_len, ftnlen infile_len, ftnlen error_len)
{
    /* Initialized data */

    static integer nfiles = 0;
    static logical first = TRUE_;
    static char synval[80*9] = "                                            "
	    "                                    " "                         "
	    "                                                       " "      "
	    "                                                                "
	    "          " "                                                   "
	    "                             " "                                "
	    "                                                " "             "
	    "                                                                "
	    "   " "EK #word[ekfile]                                          "
	    "                      " "LEAPSECONDS #word[leapfile]            "
	    "                                         " "SCLK KERNEL #word[sc"
	    "lkfile]                                                     ";

    /* System generated locals */
    integer i__1, i__2, i__3;

    /* Builtin functions */
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
    integer s_rnge(char *, integer, char *, integer), s_cmp(char *, char *, 
	    ftnlen, ftnlen);

    /* Local variables */
    static integer need;
    static char file[127], name__[32];
    static integer clen;
    extern logical have_(char *, ftnlen);
    static integer left, reqd, nseg;
    static char indx[4], pval[32*4];
    static integer hits;
    static char size[32], type__[32];
    static logical quit;
    extern /* Subroutine */ int zzeksinf_(integer *, integer *, char *, 
	    integer *, char *, integer *, ftnlen, ftnlen);
    static integer i__, j, k;
    extern integer cardc_(char *, ftnlen);
    static integer l, n;
    extern /* Subroutine */ int clgai_(integer *, char *, integer *, integer *
	    , ftnlen), clgac_(integer *, char *, char *, ftnlen, ftnlen);
    static integer r__;
    static char cname[80], break__[80];
    static integer headr[5];
    extern /* Subroutine */ int eklef_(char *, integer *, ftnlen), clnid_(
	    integer *, integer *, logical *);
    static integer space;
    extern logical match_(char *, char *, ftnlen, ftnlen);
    extern /* Subroutine */ int chkin_(char *, ftnlen);
    static integer tcode, ncomc;
    extern /* Subroutine */ int ekuef_(integer *);
    static char rname[6], tname[32];
    extern /* Subroutine */ int repmc_(char *, char *, char *, char *, ftnlen,
	     ftnlen, ftnlen, ftnlen), clnew_(char *, integer *, integer *, 
	    integer *, integer *, integer *, logical *, logical *, integer *, 
	    ftnlen);
    static logical found;
    static integer csize, ncols, ncomr;
    static logical cnull;
    static integer right, width[5], ctype;
    extern integer ltrim_(char *, ftnlen);
    static integer count;
    extern integer rtrim_(char *, ftnlen);
    static integer sizes[5];
    static char style[80];
    extern /* Subroutine */ int clnum_(integer *);
    static logical justr[5];
    extern /* Subroutine */ int m2chck_(char *, char *, integer *, char *, 
	    char *, ftnlen, ftnlen, ftnlen, ftnlen), m2getc_(char *, char *, 
	    logical *, char *, ftnlen, ftnlen, ftnlen), m2ints_(integer *, 
	    char *, integer *, char *, ftnlen, ftnlen);
    static integer id, nb;
    static char bs[1];
    extern logical m2xist_(char *, ftnlen);
    static integer nh, sb, handle;
    static char ifname[60], tabnam[64], tabcol[80*506], rnamec[7], cnames[64*
	    100];
    static integer handls[20], segdsc[24];
    extern integer isrchc_(char *, integer *, char *, ftnlen, ftnlen), 
	    eknseg_(integer *);
    extern /* Subroutine */ int gcolmn_();
    extern integer isrchi_(integer *, integer *, integer *);
    extern /* Subroutine */ int pagput_(char *, ftnlen);
    extern logical return_(void);
    extern /* Subroutine */ int nspwln_(char *, ftnlen);
    static char synkey[32*9];
    static integer synptr[9];
    static char ekfils[127*20], thisfl[127], messge[300], idword[8];
    static integer cdscrs[1100]	/* was [11][100] */, widest, totalc, nresvr, 
	    nresvc;
    static logical cindxd;
    static char spcial[4*5], lsttab[32];
    static integer colids[506], lmarge, ordvec[500];
    static logical presrv[5];
    extern /* Subroutine */ int replch_(char *, char *, char *, char *, 
	    ftnlen, ftnlen, ftnlen, ftnlen), prefix_(char *, integer *, char *
	    , ftnlen, ftnlen), chkout_(char *, ftnlen), expool_(char *, 
	    logical *, ftnlen), repmct_(char *, char *, integer *, char *, 
	    char *, ftnlen, ftnlen, ftnlen, ftnlen), clunld_(integer *), 
	    ldpool_(char *, ftnlen);
    static integer nid;
    extern /* Subroutine */ int dasfnh_(char *, integer *, ftnlen);
    static integer col, seg, ids[5];
    extern /* Subroutine */ int remlac_(integer *, integer *, char *, integer 
	    *, ftnlen), nspglr_(integer *, integer *), nspmrg_(char *, ftnlen)
	    , suffix_(char *, integer *, char *, ftnlen, ftnlen), pagrst_(
	    void), pagset_(char *, integer *, ftnlen), ssizec_(integer *, 
	    char *, ftnlen), ssizei_(integer *, integer *), appndc_(char *, 
	    char *, ftnlen, ftnlen), appndi_(integer *, integer *), pagscn_(
	    char *, ftnlen), scolmn_(integer *, integer *, char *, ftnlen), 
	    tabrpt_(integer *, integer *, integer *, integer *, logical *, 
	    logical *, char *, integer *, integer *, U_fp, ftnlen), orderc_(
	    char *, integer *, integer *, ftnlen);
    extern integer pos_(char *, char *, integer *, ftnlen, ftnlen);
    extern /* Subroutine */ int pagsft_(void), dasrfr_(integer *, char *, 
	    char *, integer *, integer *, integer *, integer *, ftnlen, 
	    ftnlen), nspshc_(integer *, logical *), bbputc_1__(char *, char *,
	     integer *, char *, ftnlen, ftnlen, ftnlen), nicepr_1__(char *, 
	    char *, S_fp, ftnlen, ftnlen);


/*     Version 2.4.0, 26-SEP-2005 */

/*        Minor bug fix: replaced FILE with INFILE in the RTRIM call */
/*        constructing "The file # is not listed ..." error message. */

/*     Version 2.3.0, 21-JUN-1999 */

/*        Added RETURN before first entry points. */

/*     Version 2.2.0, 22-APR-1997 */

/*        Declared PAGPUT external */

/*     Version 2.1.0  14-SEP-1995 */

/*        Variable INDEX removed. */

/*     Version 2.0.0  23-AUG-1995 */

/*        The widest string in a string column is no longer supplied */
/*        by the EK summary stuff.  We just set the value WIDEST */
/*        to 24. */


/*     This routine handles the loading of E-kernels, leapsecond and */
/*     SCLK kernels. */


/*     Passable routines */


/*     Parameters that contain the routine name for use in check-in, */
/*     check-out, and error messages. */


/*     SPICELIB functions */


/*     E-kernel functions */


/*     Meta/2 Functions */


/*     Interface to the SPICELIB error handling. */


/*     Ek include files. */

/* +============================================================== */
/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */


/*     Include Section:  EK Column Descriptor Parameters */

/*        ekcoldsc.inc Version 6    23-AUG-1995 (NJB) */


/*     Note:  The column descriptor size parameter CDSCSZ  is */
/*     declared separately in the include section CDSIZE$INC.FOR. */

/*     Offset of column descriptors, relative to start of segment */
/*     integer address range.  This number, when added to the last */
/*     integer address preceding the segment, yields the DAS integer */
/*     base address of the first column descriptor.  Currently, this */
/*     offset is exactly the size of a segment descriptor.  The */
/*     parameter SDSCSZ, which defines the size of a segment descriptor, */
/*     is declared in the include file eksegdsc.inc. */


/*     Size of column descriptor */


/*     Indices of various pieces of column descriptors: */


/*     CLSIDX is the index of the column's class code.  (We use the */
/*     word `class' to distinguish this item from the column's data */
/*     type.) */


/*     TYPIDX is the index of the column's data type code (CHR, INT, DP, */
/*     or TIME).  The type is actually implied by the class, but it */
/*     will frequently be convenient to look up the type directly. */



/*     LENIDX is the index of the column's string length value, if the */
/*     column has character type.  A value of IFALSE in this element of */
/*     the descriptor indicates that the strings have variable length. */


/*     SIZIDX is the index of the column's element size value.  This */
/*     descriptor element is meaningful for columns with fixed-size */
/*     entries.  For variable-sized columns, this value is IFALSE. */


/*     NAMIDX is the index of the base address of the column's name. */


/*     IXTIDX is the data type of the column's index.  IXTIDX */
/*     contains a type value only if the column is indexed. For columns */
/*     that are not indexed, the location IXTIDX contains the boolean */
/*     value IFALSE. */


/*     IXPIDX is a pointer to the column's index.  IXTPDX contains a */
/*     meaningful value only if the column is indexed.  The */
/*     interpretation of the pointer depends on the data type of the */
/*     index. */


/*     NFLIDX is the index of a flag indicating whether nulls are */
/*     permitted in the column.  The value at location NFLIDX is */
/*     ITRUE if nulls are permitted and IFALSE otherwise. */


/*     ORDIDX is the index of the column's ordinal position in the */
/*     list of columns belonging to the column's parent segment. */


/*     METIDX is the index of the column's integer metadata pointer. */
/*     This pointer is a DAS integer address. */


/*     The last position in the column descriptor is reserved.  No */
/*     parameter is defined to point to this location. */


/*     End Include Section:  EK Column Descriptor Parameters */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */


/*     Include Section:  EK Segment Descriptor Parameters */

/*        eksegdsc.inc  Version 8  06-NOV-1995 (NJB) */


/*     All `base addresses' referred to below are the addresses */
/*     *preceding* the item the base applies to.  This convention */
/*     enables simplied address calculations in many cases. */

/*     Size of segment descriptor.  Note:  the include file ekcoldsc.inc */
/*     must be updated if this parameter is changed.  The parameter */
/*     CDOFF in that file should be kept equal to SDSCSZ. */


/*     Index of the segment type code: */


/*     Index of the segment's number.  This number is the segment's */
/*     index in the list of segments contained in the EK to which */
/*     the segment belongs. */


/*     Index of the DAS integer base address of the segment's integer */
/*     meta-data: */


/*     Index of the DAS character base address of the table name: */


/*     Index of the segment's column count: */


/*     Index of the segment's record count: */


/*     Index of the root page number of the record tree: */


/*     Index of the root page number of the character data page tree: */


/*     Index of the root page number of the double precision data page */
/*     tree: */


/*     Index of the root page number of the integer data page tree: */


/*     Index of the `modified' flag: */


/*     Index of the `initialized' flag: */


/*     Index of the shadowing flag: */


/*     Index of the companion file handle: */


/*     Index of the companion segment number: */


/*     The next three items are, respectively, the page numbers of the */
/*     last character, d.p., and integer data pages allocated by the */
/*     segment: */


/*     The next three items are, respectively, the page-relative */
/*     indices of the last DAS word in use in the segment's */
/*     last character, d.p., and integer data pages: */


/*     Index of the DAS character base address of the column name list: */


/*     The last descriptor element is reserved for future use.  No */
/*     parameter is defined to point to this location. */


/*     End Include Section:  EK Segment Descriptor Parameters */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */


/*     Include Section:  EK Boolean Enumerated Type */


/*        ekbool.inc Version 1   21-DEC-1994 (NJB) */


/*     Within the EK system, boolean values sometimes must be */
/*     represented by integer or character codes.  The codes and their */
/*     meanings are listed below. */

/*     Integer code indicating `true': */


/*     Integer code indicating `false': */


/*     Character code indicating `true': */


/*     Character code indicating `false': */


/*     End Include Section:  EK Boolean Enumerated Type */

/* +============================================================== */

/*     Meta/2 syntax definition variables. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */


/*     Include Section:  EK Data Types */

/*        ektype.inc Version 1  27-DEC-1994 (NJB) */


/*     Within the EK system, data types of EK column contents are */
/*     represented by integer codes.  The codes and their meanings */
/*     are listed below. */

/*     Integer codes are also used within the DAS system to indicate */
/*     data types; the EK system makes no assumptions about compatibility */
/*     between the codes used here and those used in the DAS system. */


/*     Character type: */


/*     Double precision type: */


/*     Integer type: */


/*     `Time' type: */

/*     Within the EK system, time values are represented as ephemeris */
/*     seconds past J2000 (TDB), and double precision numbers are used */
/*     to store these values.  However, since time values require special */
/*     treatment both on input and output, and since the `TIME' column */
/*     has a special role in the EK specification and code, time values */
/*     are identified as a type distinct from double precision numbers. */


/*     End Include Section:  EK Data Types */


/*     E-kernel column type definitions */


/*     INTEGER               CH */
/*     PARAMETER           ( CH   = 1 ) */

/*     INTEGER               DP */
/*     PARAMETER           ( DP   = 2 ) */

/*     INTEGER               INT */
/*     PARAMETER           ( INT  = 3 ) */

/*     INTEGER               TIME */
/*     PARAMETER           ( TIME = 4 ) */

/*     Local Parameters */

/*     FILSIZ   is the maximum number of characters allowed for a */
/*              filename */

/*     LNGSIZ   is the maximum number of characters allowed for */
/*              use in reporting the columns associated with a given */
/*              file. */

/*     MAXFIL   is the maximum number of E-kernels that can be loaded */
/*              at any one time. */

/*     NNAMES   is the maximum number of names/headings that can appear */
/*              in a report of loaded files and columns. */

/*     MAXCOL   is the maximum number of columns that may be present */
/*              in any segment of an E-kernel */

/*     LNSIZE   is the standard text line length. */


/*     Initialization logical */


/*     Loaded file database (shared between entry points) */


/*     Local Variables */


/*     INTEGER               IFALSE */
/*     PARAMETER           ( IFALSE = -1 ) */


/*     Variables needed by NSPEKS */


/*     Save everything. */


/*     Initial Values */

    /* Parameter adjustments */
    if (error) {
	}

    /* Function Body */
    switch(n__) {
	case 1: goto L_nspld;
	case 2: goto L_nspuld;
	case 3: goto L_nspeks;
	case 4: goto L_nspekc;
	}

    return 0;

/*  Load an E-, leapsecond, or sclk kernel. */


L_nspld:

/*     Standard Spicelib error handling. */

    s_copy(rname, "NSPLD", (ftnlen)6, (ftnlen)5);
    s_copy(rnamec, "NSPLD:", (ftnlen)7, (ftnlen)6);
    if (return_()) {
	return 0;
    }
    chkin_(rname, (ftnlen)6);

/*     On the first pass establish the syntax that this routine */
/*     is responsible for recognizing. */

    if (first) {
	first = FALSE_;
	*(unsigned char *)bs = '@';
	for (i__ = 1; i__ <= 100; ++i__) {
	    s_copy(cnames + (((i__1 = i__ - 1) < 100 && 0 <= i__1 ? i__1 : 
		    s_rnge("cnames", i__1, "kerman_", (ftnlen)361)) << 6), 
		    " ", (ftnlen)64, (ftnlen)1);
	}
	for (i__ = 1; i__ <= 3; ++i__) {
	    replch_(synval + ((i__1 = i__ + 5) < 9 && 0 <= i__1 ? i__1 : 
		    s_rnge("synval", i__1, "kerman_", (ftnlen)366)) * 80, 
		    "#", bs, synval + ((i__2 = i__ + 5) < 9 && 0 <= i__2 ? 
		    i__2 : s_rnge("synval", i__2, "kerman_", (ftnlen)366)) * 
		    80, (ftnlen)80, (ftnlen)1, (ftnlen)1, (ftnlen)80);
	}
	m2ints_(&c__3, synkey, synptr, synval, (ftnlen)32, (ftnlen)80);
    }

/*     See if this command matches a known syntax.  If it doesn't */
/*     there is no point in hanging around. */

    m2chck_(commnd, synkey, synptr, synval, error, commnd_len, (ftnlen)32, (
	    ftnlen)80, error_len);
    if (have_(error, error_len)) {
	prefix_(rnamec, &c__1, error, (ftnlen)7, error_len);
	chkout_(rname, (ftnlen)6);
	return 0;
    }
    if (m2xist_("ekfile", (ftnlen)6)) {

/*        We need to have a leapseconds kernel loaded before */
/*        we can load an E-kernel. */

	expool_("DELTET/DELTA_AT", &found, (ftnlen)15);
	if (! found) {
	    s_copy(error, "Before an E-kernel can be loaded, you must load a"
		    " leapseconds kernel.  ", error_len, (ftnlen)71);
	    chkout_(rname, (ftnlen)6);
	    return 0;
	}
	m2getc_("ekfile", commnd, &found, file, (ftnlen)6, commnd_len, (
		ftnlen)127);

/*        See if we already have this file. */

	if (isrchc_(file, &nfiles, ekfils, (ftnlen)127, (ftnlen)127) > 0) {
	    chkout_(rname, (ftnlen)6);
	    return 0;
	}

/*        Make sure there is room for this file. */

	if (nfiles == 20) {
	    s_copy(error, "The maximum number of E-kernels that can loaded a"
		    "t open by INSPEKT at one time is #.  That number has alr"
		    "eady been reached. You will need to unload one of the fi"
		    "les that have already been loaded before you will be abl"
		    "e to load any other files. ", error_len, (ftnlen)244);
	    repmct_(error, "#", &c__20, "L", error, error_len, (ftnlen)1, (
		    ftnlen)1, error_len);
	    prefix_(rnamec, &c__1, error, (ftnlen)7, error_len);
	    chkout_(rname, (ftnlen)6);
	    return 0;
	}

/*        Load the file as an e-kernel. */

	eklef_(file, &handle, rtrim_(file, (ftnlen)127));
	if (have_(error, error_len)) {
	    prefix_(rnamec, &c__1, error, (ftnlen)7, error_len);
	    chkout_(rname, (ftnlen)6);
	    return 0;
	}

/*        Store the name of this file. */

	++nfiles;
	s_copy(ekfils + ((i__1 = nfiles - 1) < 20 && 0 <= i__1 ? i__1 : 
		s_rnge("ekfils", i__1, "kerman_", (ftnlen)442)) * 127, file, (
		ftnlen)127, (ftnlen)127);

/*        Determine how many segments are in the file we just loaded. */

	nseg = eknseg_(&handle);

/*        For each segment in the newly loaded file ... */

	i__1 = nseg;
	for (seg = 1; seg <= i__1; ++seg) {
	    s_copy(tabnam, " ", (ftnlen)64, (ftnlen)1);
	    for (i__ = 1; i__ <= 100; ++i__) {
		s_copy(cnames + (((i__2 = i__ - 1) < 100 && 0 <= i__2 ? i__2 :
			 s_rnge("cnames", i__2, "kerman_", (ftnlen)457)) << 6)
			, " ", (ftnlen)64, (ftnlen)1);
	    }
	    zzeksinf_(&handle, &seg, tabnam, segdsc, cnames, cdscrs, (ftnlen)
		    64, (ftnlen)64);

/*           Add each column name to the list of columns held by the */
/*           column manager. */

	    ncols = segdsc[4];
	    i__2 = ncols;
	    for (col = 1; col <= i__2; ++col) {

/*              We need to make the column name include table it */
/*              belongs to (a fully qualified column name). */

		prefix_(".", &c__0, cnames + (((i__3 = col - 1) < 100 && 0 <= 
			i__3 ? i__3 : s_rnge("cnames", i__3, "kerman_", (
			ftnlen)475)) << 6), (ftnlen)1, (ftnlen)64);
		prefix_(tabnam, &c__0, cnames + (((i__3 = col - 1) < 100 && 0 
			<= i__3 ? i__3 : s_rnge("cnames", i__3, "kerman_", (
			ftnlen)476)) << 6), (ftnlen)64, (ftnlen)64);
		cindxd = cdscrs[(i__3 = col * 11 - 6) < 1100 && 0 <= i__3 ? 
			i__3 : s_rnge("cdscrs", i__3, "kerman_", (ftnlen)478)]
			 != -1;
		cnull = cdscrs[(i__3 = col * 11 - 4) < 1100 && 0 <= i__3 ? 
			i__3 : s_rnge("cdscrs", i__3, "kerman_", (ftnlen)479)]
			 != -1;
		ctype = cdscrs[(i__3 = col * 11 - 10) < 1100 && 0 <= i__3 ? 
			i__3 : s_rnge("cdscrs", i__3, "kerman_", (ftnlen)481)]
			;
		clen = cdscrs[(i__3 = col * 11 - 9) < 1100 && 0 <= i__3 ? 
			i__3 : s_rnge("cdscrs", i__3, "kerman_", (ftnlen)482)]
			;
		csize = cdscrs[(i__3 = col * 11 - 8) < 1100 && 0 <= i__3 ? 
			i__3 : s_rnge("cdscrs", i__3, "kerman_", (ftnlen)483)]
			;

/*              This is what used to be here, but the item NBLIDX */
/*              vanished by design.  We now just set this so something */
/*              reasonable.  24 seemed like the reasonable thing at */
/*              the time.  (See the column manager and do a bit of */
/*              code diving to see what this is used for.) */

/*              WIDEST    = CDSCRS ( NBLIDX, COL ) */

		widest = 24;
		clnew_(cnames + (((i__3 = col - 1) < 100 && 0 <= i__3 ? i__3 :
			 s_rnge("cnames", i__3, "kerman_", (ftnlen)496)) << 6)
			, &handle, &ctype, &clen, &widest, &csize, &cindxd, &
			cnull, &id, (ftnlen)64);
	    }
	}

/*        If anything went wrong, unload the file. */

	if (have_(error, error_len)) {
	    prefix_(rnamec, &c__1, error, (ftnlen)7, error_len);
	    ekuef_(&handle);
	    clunld_(&handle);
	    --nfiles;
	    chkout_(rname, (ftnlen)6);
	    return 0;
	}
    } else if (m2xist_("leapfile", (ftnlen)8)) {
	m2getc_("leapfile", commnd, &found, file, (ftnlen)8, commnd_len, (
		ftnlen)127);
	ldpool_(file, (ftnlen)127);
	bbputc_1__("POST", "LEAPSECONDS", &c__1, file, (ftnlen)4, (ftnlen)11, 
		(ftnlen)127);
    } else if (m2xist_("sclkfile", (ftnlen)8)) {
	m2getc_("sclkfile", commnd, &found, file, (ftnlen)8, commnd_len, (
		ftnlen)127);
	ldpool_(file, (ftnlen)127);
	bbputc_1__("APPEND", "SCLK", &c__1, file, (ftnlen)6, (ftnlen)4, (
		ftnlen)127);
    } else {
	s_copy(error, "The input command was unrecognized and somehow got to"
		" an \"impossible\" place in KERMAN.FOR", error_len, (ftnlen)
		89);
    }
    if (have_(error, error_len)) {
	prefix_(rnamec, &c__1, error, (ftnlen)7, error_len);
	chkout_(rname, (ftnlen)6);
	return 0;
    }
    chkout_(rname, (ftnlen)6);
    return 0;

/*  Unload an E-kernel from the list of known files. */


L_nspuld:
    s_copy(rname, "NSPULD", (ftnlen)6, (ftnlen)6);
    s_copy(rnamec, "NSPULD:", (ftnlen)7, (ftnlen)7);
    if (return_()) {
	return 0;
    }
    chkin_(rname, (ftnlen)6);
    j = isrchc_(infile__, &nfiles, ekfils, infile_len, (ftnlen)127);
    if (j == 0) {
	s_copy(error, "The file # is not listed among those files that have "
		"been loaded. ", error_len, (ftnlen)66);
	repmc_(error, "#", infile__, error, error_len, (ftnlen)1, rtrim_(
		infile__, infile_len), error_len);
	chkout_(rname, (ftnlen)6);
	return 0;
    }

/*     Get the handle associated with this file. */

    dasfnh_(infile__, &handle, rtrim_(infile__, infile_len));
    if (have_(error, error_len)) {
	chkout_(rname, (ftnlen)6);
	return 0;
    }

/*     Now unload the file, and detach its handle from any columns to */
/*     which it might be attached. */

    ekuef_(&handle);
    clunld_(&handle);

/*     Finally remove this file from our internal list of files. */

    remlac_(&c__1, &j, ekfils, &nfiles, (ftnlen)127);
    chkout_(rname, (ftnlen)6);
    return 0;

/*  Create a report regarding currently loaded kernels/columns. */


L_nspeks:

/*     Version 2.0  Aug 3, 1995 */

/*        This routine was rewritten to provide a more friendly */
/*        kernel summary. */

/*     ---B. Taber */

/*     This routine displays the currently loaded E-kernels. */

    s_copy(rname, "NSPEKS", (ftnlen)6, (ftnlen)6);
    s_copy(rnamec, "NSPEKS:", (ftnlen)7, (ftnlen)7);
    if (return_()) {
	return 0;
    }

/*     write (*,*) 'Checking in:' */

    chkin_(rname, (ftnlen)6);
    if (nfiles <= 0) {
	nspwln_(" ", (ftnlen)1);
	nspwln_("There are no E-kernels loaded now.", (ftnlen)34);
	nspwln_(" ", (ftnlen)1);
	chkout_(rname, (ftnlen)6);
	return 0;
    }

/*     First thing we do is set up the NICEPR_1 style string */
/*     to be used in creation of summary headers. */

/*     write (*,*) 'Fetching margins: ' */
    nspglr_(&left, &right);
    nspmrg_(style, (ftnlen)80);
    suffix_("FLAG", &c__1, style, (ftnlen)4, (ftnlen)80);
    suffix_("E-kernel:", &c__1, style, (ftnlen)9, (ftnlen)80);

/*     Reset the output page, title frequency and header frequency */
/*     values. */

/*     write (*,*) 'Resetting page and setting up page attributes:' */

    pagrst_();
    pagset_("TITLEFREQUENCY", &c__0, (ftnlen)14);
    pagset_("HEADERFREQUENCY", &c__0, (ftnlen)15);
    pagset_("NOSPACEFOOTER", &c__1, (ftnlen)13);
    pagset_("FOOTERFREQUENCY", &c_n1, (ftnlen)15);
    s_copy(pval, "CH", (ftnlen)32, (ftnlen)2);
    s_copy(pval + 32, "D.P.", (ftnlen)32, (ftnlen)4);
    s_copy(pval + 64, "INTEGER", (ftnlen)32, (ftnlen)7);
    s_copy(pval + 96, "TIME", (ftnlen)32, (ftnlen)4);
    lmarge = 1;
    space = 1;

/*     Next we set up the the column id codes, sizes, */
/*     default widths, justifications, component preservation, */
/*     and special marker attributes for each column. */

    headr[0] = 1;
    headr[1] = 2;
    headr[2] = 3;
    headr[3] = 4;
    headr[4] = 5;
    sizes[0] = 1;
    sizes[1] = 1;
    sizes[2] = 1;
    sizes[3] = 1;
    sizes[4] = 1;
    width[0] = 16;
    width[1] = 16;
    width[2] = 8;
    width[3] = 8;
    width[4] = 6;
    need = width[0] + width[1] + width[2] + width[3] + width[4] + 4;
    right = min(right,need);
    pagset_("PAGEWIDTH", &right, (ftnlen)9);
    reqd = width[2] + width[3] + width[4] + 4;

/*     If the page width is less than default needed, we reset the */
/*     widths of the first two columns so they will fit in available */
/*     space. */

    if (right < need) {
	width[0] = (right - reqd) / 2;
	width[1] = width[0];
    }
    justr[0] = FALSE_;
    justr[1] = FALSE_;
    justr[2] = FALSE_;
    justr[3] = TRUE_;
    justr[4] = TRUE_;
    presrv[0] = TRUE_;
    presrv[1] = TRUE_;
    presrv[2] = TRUE_;
    presrv[3] = TRUE_;
    presrv[4] = TRUE_;
    s_copy(spcial, " ", (ftnlen)4, (ftnlen)1);
    s_copy(spcial + 4, " ", (ftnlen)4, (ftnlen)1);
    s_copy(spcial + 8, " ", (ftnlen)4, (ftnlen)1);
    s_copy(spcial + 12, " ", (ftnlen)4, (ftnlen)1);
    s_copy(spcial + 16, " ", (ftnlen)4, (ftnlen)1);

/*     write (*,*) 'Starting file loop:' */

    i__1 = nfiles;
    for (i__ = 1; i__ <= i__1; ++i__) {

/*        Get the handle associated with this file, and get the */
/*        number of ID's currently known. */

	dasfnh_(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? i__2 : s_rnge(
		"ekfils", i__2, "kerman_", (ftnlen)738)) * 127, &handle, (
		ftnlen)127);
	clnum_(&nid);
/*        write (*,*) 'File: ', I, 'Handle: ', HANDLE */

/*        Now empty out the table/column data for this file. */

/*        write (*,*) 'Empty out the column collector.' */
	ssizec_(&c__500, tabcol, (ftnlen)80);
	ssizei_(&c__500, colids);

/*        Cycle over all column id's to determine if they */
/*        are attached to this particular file. */

/*        write (*,*) 'Beginning Column search:  ', NID, ' Columns' */
	i__2 = nid;
	for (j = 1; j <= i__2; ++j) {
	    clnid_(&j, &id, &found);
	    clgai_(&id, "HANDLES", &nh, handls, (ftnlen)7);
	    if (isrchi_(&handle, &nh, handls) > 0) {

/*              This column is associated with this file.  Store */
/*              its name and id-code for the next section of code. */

/*              write (*,*) 'Column id and associated handle match.' */

		clgac_(&id, "NAME", cname, (ftnlen)4, (ftnlen)80);
		appndc_(cname, tabcol, (ftnlen)80, (ftnlen)80);
		appndi_(&id, colids);
	    }
	}

/*        Layout the pages.  We perform a soft page reset */
/*        so that the various sections will be empty. */
/*        Note this doesn't affect frequency parameter */
/*        or other geometry attributes of pages. */

/*        write (*,*) 'Creating page: Title:' */

	pagscn_("TITLE", (ftnlen)5);
	pagput_(" ", (ftnlen)1);
	pagput_("Summary of Loaded E-kernels", (ftnlen)27);
	pagput_(" ", (ftnlen)1);

/*        write (*,*) 'Creating page: Header' */

/*        Set up the various items needed for the report header. */

	pagscn_("HEADER", (ftnlen)6);
	pagput_(" ", (ftnlen)1);
	nicepr_1__(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? i__2 : 
		s_rnge("ekfils", i__2, "kerman_", (ftnlen)791)) * 127, style, 
		(S_fp)pagput_, (ftnlen)127, (ftnlen)80);
	pagput_(" ", (ftnlen)1);
	scolmn_(&c__1, &c__1, "Table Name", (ftnlen)10);
	scolmn_(&c__2, &c__1, "Column Name", (ftnlen)11);
	scolmn_(&c__3, &c__1, "Type", (ftnlen)4);
	scolmn_(&c__4, &c__1, "Size", (ftnlen)4);
	scolmn_(&c__5, &c__1, "Index", (ftnlen)5);

/*        write (*,*) 'Creating page: Column headings' */

	tabrpt_(&c__5, headr, sizes, width, justr, presrv, spcial, &lmarge, &
		space, (U_fp)gcolmn_, (ftnlen)4);
	s_copy(break__, "==================================================="
		"=============================", (ftnlen)80, (ftnlen)80);
	pagput_(break__, right);

/*        Now set the page section to the body portion for */
/*        preparing to fill in the e-kernel summary. */

/*        write (*,*) 'Creating page: Body of report:' */
	pagscn_("BODY", (ftnlen)4);
	n = cardc_(tabcol, (ftnlen)80);
	orderc_(tabcol + 480, &n, ordvec, (ftnlen)80);
	s_copy(lsttab, " ", (ftnlen)32, (ftnlen)1);
	i__2 = n;
	for (j = 1; j <= i__2; ++j) {
	    k = ordvec[(i__3 = j - 1) < 500 && 0 <= i__3 ? i__3 : s_rnge(
		    "ordvec", i__3, "kerman_", (ftnlen)826)];
	    clgac_(&colids[(i__3 = k + 5) < 506 && 0 <= i__3 ? i__3 : s_rnge(
		    "colids", i__3, "kerman_", (ftnlen)828)], "TABLE", tname, 
		    (ftnlen)5, (ftnlen)32);
	    clgac_(&colids[(i__3 = k + 5) < 506 && 0 <= i__3 ? i__3 : s_rnge(
		    "colids", i__3, "kerman_", (ftnlen)829)], "NAME", cname, (
		    ftnlen)4, (ftnlen)80);
	    clgac_(&colids[(i__3 = k + 5) < 506 && 0 <= i__3 ? i__3 : s_rnge(
		    "colids", i__3, "kerman_", (ftnlen)830)], "SIZE", size, (
		    ftnlen)4, (ftnlen)32);
	    clgac_(&colids[(i__3 = k + 5) < 506 && 0 <= i__3 ? i__3 : s_rnge(
		    "colids", i__3, "kerman_", (ftnlen)831)], "INDEXED", indx,
		     (ftnlen)7, (ftnlen)4);

/*           Note:  There is only one type associated with each */
/*           handle.  Thus TCODE does not need to be an array. */

	    clgai_(&colids[(i__3 = k + 5) < 506 && 0 <= i__3 ? i__3 : s_rnge(
		    "colids", i__3, "kerman_", (ftnlen)836)], "TYPE", &count, 
		    &tcode, (ftnlen)4);
	    if (s_cmp(tname, lsttab, (ftnlen)32, (ftnlen)32) == 0) {
		s_copy(tname, " ", (ftnlen)32, (ftnlen)1);
	    } else if (s_cmp(lsttab, " ", (ftnlen)32, (ftnlen)1) != 0) {
		pagput_(" ", (ftnlen)1);
		s_copy(lsttab, tname, (ftnlen)32, (ftnlen)32);
	    } else {
		s_copy(lsttab, tname, (ftnlen)32, (ftnlen)32);
	    }
	    nb = pos_(cname, ".", &c__1, (ftnlen)80, (ftnlen)1) + 1;
	    s_copy(name__, cname + (nb - 1), (ftnlen)32, 80 - (nb - 1));
	    if (tcode == 1) {
		clgac_(&colids[(i__3 = k + 5) < 506 && 0 <= i__3 ? i__3 : 
			s_rnge("colids", i__3, "kerman_", (ftnlen)852)], 
			"TYPE", type__, (ftnlen)4, (ftnlen)32);
		sb = pos_(type__, "*", &c__1, (ftnlen)32, (ftnlen)1);
		s_copy(pval, "CH", (ftnlen)32, (ftnlen)2);
		suffix_(type__ + (sb - 1), &c__0, pval, 32 - (sb - 1), (
			ftnlen)32);
	    }
	    scolmn_(&c__6, &c__1, tname, (ftnlen)32);
	    scolmn_(&c__7, &c__1, name__, (ftnlen)32);
	    scolmn_(&c__8, &c__1, pval + (((i__3 = tcode - 1) < 4 && 0 <= 
		    i__3 ? i__3 : s_rnge("pval", i__3, "kerman_", (ftnlen)860)
		    ) << 5), (ftnlen)32);
	    scolmn_(&c__9, &c__1, size, (ftnlen)32);
	    scolmn_(&c__10, &c__1, indx, (ftnlen)4);
	    ids[0] = 6;
	    ids[1] = 7;
	    ids[2] = 8;
	    ids[3] = 9;
	    ids[4] = 10;

/*           write (*,*) 'Creating next row:' */
/*           write (*,*) TNAME */
/*           write (*,*) NAME */
/*           write (*,*) PVAL(TCODE) */
/*           write (*,*) SIZE */
/*           write (*,*) INDX */

	    tabrpt_(&c__5, ids, sizes, width, justr, presrv, spcial, &lmarge, 
		    &space, (U_fp)gcolmn_, (ftnlen)4);
/*           write (*,*) 'Row created.' */

	}

/*        Do a soft page reset so for the next file to be displayed */

/*        write (*,*) 'Performing soft page reset.' */
	pagsft_();
	pagrst_();
	pagset_("TITLEFREQUENCY", &c_n1, (ftnlen)14);
	pagset_("HEADERFREQUENCY", &c__0, (ftnlen)15);
	pagset_("NOSPACEFOOTER", &c__1, (ftnlen)13);
	pagset_("FOOTERFREQUENCY", &c_n1, (ftnlen)15);
    }
    chkout_(rname, (ftnlen)6);
    return 0;
/* $Procedure      NSPEKC ( Inspekt the comments from EK files ) */

L_nspekc:
/*     This entry point examines each file that matches the */
/*     template given by INFILE and if comments exist for the */
/*     file, they are displayed. */
/*     Version 1.0.0 25-AUG-1995 (WLT) */
    chkin_("NSPEKC", (ftnlen)6);
    totalc = 0;
    s_copy(thisfl, " ", (ftnlen)127, (ftnlen)1);
/*     We might not need the style string, but it doesn't hurt to */
/*     get it. */
    nspmrg_(style, (ftnlen)80);
/*     If there are no loaded E-kernels say so and return. */
    if (nfiles == 0) {
	s_copy(messge, "There are no E-kernels loaded now. ", (ftnlen)300, (
		ftnlen)35);
	nicepr_1__(messge, style, (S_fp)nspwln_, (ftnlen)300, (ftnlen)80);
	chkout_("NSPEKC", (ftnlen)6);
	return 0;
    }
/*     Count the number of characters present in the files */
/*     that match the template. */
    r__ = rtrim_(infile__, infile_len);
    l = ltrim_(infile__, infile_len);
    i__1 = nfiles;
    for (i__ = 1; i__ <= i__1; ++i__) {
	if (match_(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? i__2 : 
		s_rnge("ekfils", i__2, "kerman_", (ftnlen)945)) * 127, 
		infile__ + (l - 1), (ftnlen)127, r__ - (l - 1))) {
	    dasfnh_(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? i__2 : 
		    s_rnge("ekfils", i__2, "kerman_", (ftnlen)947)) * 127, &
		    handle, (ftnlen)127);
	    dasrfr_(&handle, idword, ifname, &nresvr, &nresvc, &ncomr, &ncomc,
		     (ftnlen)8, (ftnlen)60);
	    totalc += ncomc;
	    ++hits;
	    s_copy(thisfl, ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? 
		    i__2 : s_rnge("ekfils", i__2, "kerman_", (ftnlen)955)) * 
		    127, (ftnlen)127, (ftnlen)127);
	}
    }
/*     If we didn't get any characters there several possible */
/*     reasons.  We can look at HITS to see why and form a */
/*     grammatically reasonable message. */
    if (totalc == 0) {
	if (hits == 0) {
	    s_copy(messge, "There are no E-kernels loaded whose file name ma"
		    "tches the supplied template '#'.", (ftnlen)300, (ftnlen)
		    80);
	    repmc_(messge, "#", infile__ + (l - 1), messge, (ftnlen)300, (
		    ftnlen)1, r__ - (l - 1), (ftnlen)300);
	} else if (hits == 1) {
	    s_copy(messge, "There are no comments present in the file '#'. ", 
		    (ftnlen)300, (ftnlen)47);
	    repmc_(messge, "#", thisfl, messge, (ftnlen)300, (ftnlen)1, (
		    ftnlen)127, (ftnlen)300);
	} else if (hits == 2) {
	    s_copy(messge, "There are no comments present in either of the #"
		    " files that match the supplied template. ", (ftnlen)300, (
		    ftnlen)89);
	    repmct_(messge, "#", &hits, "L", messge, (ftnlen)300, (ftnlen)1, (
		    ftnlen)1, (ftnlen)300);
	} else {
	    s_copy(messge, "There are no comments present in any of the # fi"
		    "les that match the supplied template. ", (ftnlen)300, (
		    ftnlen)86);
	    repmct_(messge, "#", &hits, "L", messge, (ftnlen)300, (ftnlen)1, (
		    ftnlen)1, (ftnlen)300);
	}
	nicepr_1__(messge, style, (S_fp)nspwln_, (ftnlen)300, (ftnlen)80);
	chkout_("NSPEKC", (ftnlen)6);
	return 0;
    }
/*     Ok. We've got something.  Set up the output page to receive */
/*     the comments a file at a time. */
    suffix_("FLAG E-kernel:", &c__1, style, (ftnlen)14, (ftnlen)80);
    i__1 = nfiles;
    for (i__ = 1; i__ <= i__1; ++i__) {
	if (match_(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? i__2 : 
		s_rnge("ekfils", i__2, "kerman_", (ftnlen)1012)) * 127, 
		infile__ + (l - 1), (ftnlen)127, r__ - (l - 1))) {
	    dasfnh_(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? i__2 : 
		    s_rnge("ekfils", i__2, "kerman_", (ftnlen)1014)) * 127, &
		    handle, (ftnlen)127);
	    dasrfr_(&handle, idword, ifname, &nresvr, &nresvc, &ncomr, &ncomc,
		     (ftnlen)8, (ftnlen)60);
	    if (ncomc == 0) {
		s_copy(messge, "# contains no comments.", (ftnlen)300, (
			ftnlen)23);
		repmc_(messge, "#", ekfils + ((i__2 = i__ - 1) < 20 && 0 <= 
			i__2 ? i__2 : s_rnge("ekfils", i__2, "kerman_", (
			ftnlen)1023)) * 127, messge, (ftnlen)300, (ftnlen)1, (
			ftnlen)127, (ftnlen)300);
		nspwln_(" ", (ftnlen)1);
		nicepr_1__(messge, style, (S_fp)nspwln_, (ftnlen)300, (ftnlen)
			80);
	    } else {
		pagrst_();
		pagscn_("HEADER", (ftnlen)6);
		pagset_("TITLEFREQUENCY", &c__0, (ftnlen)14);
		pagset_("HEADERFREQUENCY", &c__0, (ftnlen)15);
		pagset_("NOSPACEFOOTER", &c__1, (ftnlen)13);
		pagset_("FOOTERFREQUENCY", &c_n1, (ftnlen)15);
		pagput_(" ", (ftnlen)1);
		nicepr_1__(ekfils + ((i__2 = i__ - 1) < 20 && 0 <= i__2 ? 
			i__2 : s_rnge("ekfils", i__2, "kerman_", (ftnlen)1038)
			) * 127, style, (S_fp)pagput_, (ftnlen)127, (ftnlen)
			80);
		pagput_(" ", (ftnlen)1);
		nspshc_(&handle, &quit);
		if (quit) {
		    nspwln_(" ", (ftnlen)1);
		    chkout_("NSPEKC", (ftnlen)6);
		    return 0;
		}
	    }
	}
    }
    nspwln_(" ", (ftnlen)1);
    chkout_("NSPEKC", (ftnlen)6);
    return 0;
} /* kerman_ */
/* Subroutine */ int chunk_(char *buffer, integer *first, integer *last, 
	ftnlen buffer_len)
{
    /* Initialized data */

    static char terms[32*24] = "|endliteral                     " "!endliter"
	    "al                     " "@chapter                        " "@se"
	    "ction                        " "@setvarsize                     " 
	    "@var                            " "@setparamsize               "
	    "    " "@param                          " "@literal              "
	    "          " "@literalitem                    " "@literalparam   "
	    "                " "@literalvar                     " "@exliteral"
	    "                      " "@exliteralitem                  " "@exl"
	    "iteralparam                 " "@exliteralvar                   " 
	    "@newlist                        " "@newpage                    "
	    "    " "@numitem                        " "@paritem              "
	    "          " "@symitem                        " "@moreparam      "
	    "                " "@morevar                        " "          "
	    "                      ";

    /* System generated locals */
    integer i__1, i__2;

    /* Builtin functions */
    integer s_cmp(char *, char *, ftnlen, ftnlen);
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
    integer s_rnge(char *, integer, char *, integer);

    /* Local variables */
    char cseq[32];
    extern integer cpos_(char *, char *, integer *, ftnlen, ftnlen);
    integer term, i__, j;
    extern integer cardc_(char *, ftnlen);
    integer begin;
    extern /* Subroutine */ int chkin_(char *, ftnlen);
    integer index;
    extern integer ncpos_(char *, char *, integer *, ftnlen, ftnlen);
    integer nterm;
    extern integer ltrim_(char *, ftnlen);
    integer endbuf;
    extern integer isrchc_(char *, integer *, char *, ftnlen, ftnlen), 
	    touchi_(integer *);
    extern /* Subroutine */ int chkout_(char *, ftnlen);
    extern logical return_(void);
    integer end;


/*     Find the next `chunk' of a FORTeX source buffer. The chunk begins */
/*     sometime after BUFFER(FIRST), and ends at BUFFER(LAST). */


/* $ Revisions */

/* -    Faketex version 1.3.0 5-DEC-1995  WLT */

/*        Set I = TOUCHI( I ) in the IF ( RETURN() ) block so that buggy */
/*        compilers won't complain that it isn't used. */

/* -    Faketex version 1.2.0 17-NOV-1995 NJB */

/*        Data statement for TERMS broken up into multiple statements */
/*        to avoid violation of continuation limit on Sun. */

/* -    Faketex version 1.1.0 16-MAY-1994 NJB */

/*        Substring bounds on line 106 safeguarded to stay in range. */

/* -& */

/*     SPICELIB functions */


/*     Local variables */


/*     Standard SPICE error handling */

    if (return_()) {
	i__ = 0;
	i__ = touchi_(&i__);
	return 0;
    } else {
	chkin_("CHUNK", (ftnlen)5);
    }

/*     Because we can safely assume that the first line of the chunk */
/*     is not inside a literal section, we can skip blank lines and */
/*     @newpage directives with impunity to find the beginning of the */
/*     chunk. */

    endbuf = cardc_(buffer, buffer_len);
    j = ltrim_(buffer + (*first + 5) * buffer_len, buffer_len);
    while(*first < endbuf && (s_cmp(buffer + (*first + 5) * buffer_len, " ", 
	    buffer_len, (ftnlen)1) == 0 || s_cmp(buffer + ((*first + 5) * 
	    buffer_len + (j - 1)), "@newpage", buffer_len - (j - 1), (ftnlen)
	    8) == 0)) {
	++(*first);
    }
    *last = *first;

/*     A literal chunk may be terminated only by an explicit end marker */
/*     (|endliteral or !endliteral) or the end of the buffer. A normal */
/*     chunk is terminated by the beginning of another chunk, a */
/*     blank line, or a @newpage. */

/* Computing MAX */
    i__1 = 1, i__2 = ncpos_(buffer + (*first + 5) * buffer_len, "  ", &c__1, 
	    buffer_len, (ftnlen)2);
    begin = max(i__1,i__2);
/* Computing MAX */
    i__1 = begin, i__2 = cpos_(buffer + (*first + 5) * buffer_len, " {", &
	    begin, buffer_len, (ftnlen)2) - 1;
    end = max(i__1,i__2);
    s_copy(cseq, buffer + ((*first + 5) * buffer_len + (begin - 1)), (ftnlen)
	    32, end - (begin - 1));
    if (s_cmp(cseq, "@literal", (ftnlen)8, (ftnlen)8) == 0) {
	term = 1;
	nterm = 1;
    } else if (s_cmp(cseq, "@exliteral", (ftnlen)10, (ftnlen)10) == 0) {
	term = 2;
	nterm = 1;
    } else {
	term = 3;
	nterm = 22;
    }

/*     Check subsequent lines until the proper terminator or the end */
/*     of the buffer is reached. */

    index = 0;
    while(index == 0 && *last < endbuf) {
	++(*last);
	if (s_cmp(buffer + (*last + 5) * buffer_len, " ", buffer_len, (ftnlen)
		1) == 0) {
	    s_copy(cseq, " ", (ftnlen)32, (ftnlen)1);
	} else {
	    begin = ncpos_(buffer + (*last + 5) * buffer_len, "  ", &c__1, 
		    buffer_len, (ftnlen)2);
/* Computing MAX */
	    i__1 = begin, i__2 = cpos_(buffer + (*last + 5) * buffer_len, 
		    " {", &begin, buffer_len, (ftnlen)2) - 1;
	    end = max(i__1,i__2);
	    s_copy(cseq, buffer + ((*last + 5) * buffer_len + (begin - 1)), (
		    ftnlen)32, end - (begin - 1));
	}
	index = isrchc_(cseq, &nterm, terms + (((i__1 = term - 1) < 24 && 0 <=
		 i__1 ? i__1 : s_rnge("terms", i__1, "chunk_", (ftnlen)193)) 
		<< 5), (ftnlen)32, (ftnlen)32);
    }

/*     Only a literal section retains the line that terminates it. */

    if (term > 2 && *last != endbuf) {
	--(*last);
    }
    chkout_("CHUNK", (ftnlen)5);
    return 0;
} /* chunk_ */
/* $ Procedure ZZCONVTB ( Convert kernel file from text to binary ) */
/* Subroutine */ int zzconvtb_(char *txtfil, char *arch, char *type__, char *
	binfil, integer *number, ftnlen txtfil_len, ftnlen arch_len, ftnlen 
	type_len, ftnlen binfil_len)
{
    /* System generated locals */
    integer i__1;
    cilist ci__1;
    olist o__1;
    cllist cl__1;
    alist al__1;

    /* Builtin functions */
    integer s_cmp(char *, char *, ftnlen, ftnlen), f_clos(cllist *), f_back(
	    alist *), s_rsfe(cilist *), do_fio(integer *, char *, ftnlen), 
	    e_rsfe(void), f_open(olist *), s_wsfe(cilist *), e_wsfe(void);

    /* Local variables */
    char line[255];
    extern /* Subroutine */ int daftb_(integer *, char *, ftnlen), spcac_(
	    integer *, integer *, char *, char *, ftnlen, ftnlen), chkin_(
	    char *, ftnlen), dastb_(integer *, char *, ftnlen), errch_(char *,
	     char *, ftnlen, ftnlen);
    extern integer ltrim_(char *, ftnlen), rtrim_(char *, ftnlen);
    extern /* Subroutine */ int daft2b_(integer *, char *, integer *, ftnlen);
    extern logical failed_(void);
    integer handle;
    extern /* Subroutine */ int dafcls_(integer *);
    logical havcom;
    extern /* Subroutine */ int dafopw_(char *, integer *, ftnlen), sigerr_(
	    char *, ftnlen), chkout_(char *, ftnlen), getlun_(integer *), 
	    setmsg_(char *, ftnlen);
    integer iostat;
    extern /* Subroutine */ int errint_(char *, integer *, ftnlen);
    integer scrlun;
    extern logical return_(void);
    logical eoc;

/* $ Abstract */

/*     Convert a SPICE text file into its equivalent binary format. */

/*     NOTE: This routine is currently for use ONLY with the SPACIT */
/*           utility program. Use it at your own risk. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     None. */

/* $ Keywords */

/*     FILES */

/* $ Declarations */
/* $ Brief_I/O */

/*     Variable  I/O  Description */
/*     --------  ---  -------------------------------------------------- */
/*     TXTFIL     I   Name of text file to be converted. */
/*     BINARY     I   Name of a binary file to be created. */

/* $ Detailed_Input */

/*     None. */

/* $ Detailed_Output */

/*     None. */

/* $ Parameters */

/*     None. */

/* $ Files */

/*     1)  This routine uses a Fortran scratch file to temporarily */
/*         store any lines of comments. */

/* $ Exceptions */

/*     1) If there is a problem opening or writing to the binary */
/*        file, a routine that ZZCONVTB calls diagnoses and signals */
/*        an error. */

/*     2) If there is a problem reading from the text file, the */
/*        error SPICE(FILEREADFAILED) is signalled. */

/*     3) If there is a problem opening the scratch file, the error */
/*        SPICE(FILEOPENERROR) is signalled. */

/*     4) If there is a problem writing to the scratch file, the */
/*        error SPICE(FILEWRITEFAILED) is signalled. */

/*     5) If the binary file archictecture is not recognized, the error */
/*        SPICE(UNSUPPBINARYARCH) will be signalled. */

/*     7) If the transfer file format is not recognized, the error */
/*        SPICE(NOTATRANSFERFILE) will be signalled. */

/*     8) If the input file format cannot be identified, the error */
/*        SPICE(UNRECOGNIZABLEFILE) will be signalled.. */

/* $ Particulars */

/*     This routine is currently only for use with the SPACIT program. */

/* $ Examples */



/* $ Restrictions */

/*     1)  This routine assumes that the data and comments in the */
/*         text format SPK, PCK or CK file come from a binary file */
/*         and were written by one of the SPICELIB binary to text */
/*         conversion routines. Data and/or comments written any */
/*         other way may not be in the correct format and, therefore, */
/*         may not be handled properly. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     K.R. Gehringer  (JPL) */
/*     E.D. Wright     (JPL) */

/* $ Version */

/* -    Beta Version 1.0.0, 20-MAR-1999 (EDW) */

/*        This routine is a modification of the CONVTB routine. */
/*        Both have the same basic functionality, but this routine */
/*        takes the unit number of the text file opened by ZZGETFAT, */
/*        the architecture, and file type as input.  ZZCONVTB does */
/*        not open the file, ZZGETFAT performs that function. */

/* -& */
/* $ Index_Entries */

/*     convert text SPICE files to binary */

/* -& */

/*     SPICELIB functions */


/*     Local parameters */

/*     Begin and end markers in the file for the comment area. */


/*     Maximum length of an input text line. */


/*     Maximum length of a file architecture. */


/*     Maximum length of a file type. */


/*     Number of reserved records to use when creating a binar DAF file. */


/*     Local variables */


/*     Standard SPICE error handling. */

    if (return_()) {
	return 0;
    } else {
	chkin_("ZZCONVTB", (ftnlen)8);
    }

/*     Process the file based on the derived architecture and type. */

    if (s_cmp(arch, "XFR", arch_len, (ftnlen)3) == 0 && s_cmp(type__, "DAF", 
	    type_len, (ftnlen)3) == 0) {

/*        We got a DAF file. */

/*        Convert the data portion of the text file to binary. At this */
/*        point, we know that we have a current DAF text file format. */

/*        We expect to have comments. */

	havcom = TRUE_;

/*        Convert it. */

	daftb_(number, binfil, binfil_len);
	if (failed_()) {

/*           If there was an error then we need to close the */
/*           text file, and then check out and return to the */
/*           caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}
    } else if (s_cmp(arch, "XFR", arch_len, (ftnlen)3) == 0 && s_cmp(type__, 
	    "DAS", type_len, (ftnlen)3) == 0) {

/*        We got a DAS file. So we should begin converting it to binary. */
/*        DAS files are easier: all we do is call one routine. */

/*        We do not have comments. Actually, we might but they are */
/*        included as part of the DAS file conversion process. */

	havcom = FALSE_;

/*        Convert it. */

	dastb_(number, binfil, binfil_len);
	if (failed_()) {

/*           If there was an error then we need to close the */
/*           text file, and then check out and return to the */
/*           caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}
    } else if (s_cmp(arch, "DAS", arch_len, (ftnlen)3) == 0) {

/*        This is an error case, most likely caused by reading a binary */
/*        DAS file by accident. So signal an appropriate error. */

	setmsg_("The file '#' appears to be a binary DAS file and not a tran"
		"sfer file.", (ftnlen)69);
	errch_("#", txtfil, (ftnlen)1, txtfil_len);
	sigerr_("SPICE(NOTATRANSFERFILE)", (ftnlen)23);
	chkout_("ZZCONVTB", (ftnlen)8);
	return 0;
    } else if (s_cmp(arch, "DAS", arch_len, (ftnlen)3) == 0 && s_cmp(type__, 
	    "PRE", type_len, (ftnlen)3) == 0) {

/*        This is an error case, most likely caused by reading a binary */
/*        DAS file by accident. So signal an appropriate error. */

	cl__1.cerr = 0;
	cl__1.cunit = *number;
	cl__1.csta = 0;
	f_clos(&cl__1);
	setmsg_("The file '#' appears to be a pre-release binary DAS file an"
		"d not a transfer file.", (ftnlen)81);
	errch_("#", txtfil, (ftnlen)1, txtfil_len);
	sigerr_("SPICE(NOTATRANSFERFILE)", (ftnlen)23);
	chkout_("ZZCONVTB", (ftnlen)8);
	return 0;
    } else if (s_cmp(arch, "DAF", arch_len, (ftnlen)3) == 0) {

/*        This is an error case, most likely caused by reading a binary */
/*        DAF file by accident. So signal an appropriate error. */

	setmsg_("The file '#' appears to be a binary DAF file and not a tran"
		"sfer file.", (ftnlen)69);
	errch_("#", txtfil, (ftnlen)1, txtfil_len);
	sigerr_("SPICE(NOTATRANSFERFILE)", (ftnlen)23);
	chkout_("ZZCONVTB", (ftnlen)8);
	return 0;
    } else if (s_cmp(arch, "DEC", arch_len, (ftnlen)3) == 0 && s_cmp(type__, 
	    "DAF", type_len, (ftnlen)3) == 0) {

/*        This is the case for the old text file format. It has no */
/*        identifying marks whatsoever, so we simply have to try and */
/*        convert it. */

/*        We expect to have comments. */

	havcom = TRUE_;

/*        Back up one record so that we are positioned in the file where */
/*        we were when this routine was entered. */

	al__1.aerr = 0;
	al__1.aunit = *number;
	f_back(&al__1);

/*        Convert it. */

	daft2b_(number, binfil, &c__0, binfil_len);
	if (failed_()) {

/*           If there was an error then we need to close the text */
/*           file, and then check out and return to the caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}
    } else {

/*        This is the catch all error case. At this point, we didn't */
/*        match any of the files whose architecture and types are */
/*        recognized. So, we toss our hands in the air and signal an */
/*        error. */

	setmsg_("The architecture and type of the file '#'could not be deter"
		"mined.", (ftnlen)65);
	errch_("#", txtfil, (ftnlen)1, txtfil_len);
	sigerr_("SPICE(UNRECOGNIZABLEFILE)", (ftnlen)25);
	chkout_("ZZCONVTB", (ftnlen)8);
	return 0;
    }

/*     If we have comments to process, then process them. */

    if (havcom) {

/*        There are three situations that we need to consider here: */

/*           1) We have a SPICE text file with comments. This implies */
/*              that we have a bunch of comments to be put into the */
/*              comment area that are surrounded by the begin comments */
/*              marker, BCMARK, and the end comemnts marker, ECMARK. */

/*           2) We are at the end of the file. This means that we have */
/*              an old SPICE kernel file, from the good old days before */
/*              the comment area was implemented, or we ahve a plain old */
/*              ordinary DAF file. */

/*           3) We are not at the end of the file, but there are no */
/*              comments. This means a text DAF file may be embedded */
/*              in a larger text file or something. PDS does things like */
/*              this: SFDUs and such. */

/*        So, we need to look out for and deal with each of these */
/*        possibilities. */

	ci__1.cierr = 1;
	ci__1.ciend = 1;
	ci__1.ciunit = *number;
	ci__1.cifmt = "(A)";
	iostat = s_rsfe(&ci__1);
	if (iostat != 0) {
	    goto L100001;
	}
	iostat = do_fio(&c__1, line, (ftnlen)255);
	if (iostat != 0) {
	    goto L100001;
	}
	iostat = e_rsfe();
L100001:
	if (iostat > 0) {

/*           If there was an error then we need to close the text */
/*           file, and then check out and return to the caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    setmsg_("Error reading the text file: #. IOSTAT = #.", (ftnlen)43)
		    ;
	    errch_("#", txtfil, (ftnlen)1, txtfil_len);
	    errint_("#", &iostat, (ftnlen)1);
	    sigerr_("SPICE(FILEREADFAILED)", (ftnlen)21);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}

/*        If we encountered the end of the file, just check out and */
/*        return. This is not an error. */

	if (iostat < 0) {
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}

/*        We got a line, so left justify it and see if it matches the */
/*        begin comments marker. If not, then use the Fortran BACKSPACE */
/*        command to reposition the file pointer to be ready to read the */
/*        line we just read. */

	i__1 = ltrim_(line, (ftnlen)255) - 1;
	if (s_cmp(line + i__1, "~NAIF/SPC BEGIN COMMENTS~", 255 - i__1, (
		ftnlen)25) != 0) {
	    al__1.aerr = 0;
	    al__1.aunit = *number;
	    f_back(&al__1);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}

/*        We're not at the end of the file, and the line we read */
/*        is BCMARK, so we write the comments to a scratch file. */
/*        We do this because we have to use SPCAC to add the comments */
/*        to the comment area of the binary file, and SPCAC rewinds */
/*        the file. It's okay for SPCAC to rewind a scratch file, since */
/*        it will probably not be very big, but it's not okay to rewind */
/*        the file connected to NUMBER -- we don't know the initial */
/*        location of the file pointer or how big the file is. */

	getlun_(&scrlun);
	o__1.oerr = 1;
	o__1.ounit = scrlun;
	o__1.ofnm = 0;
	o__1.orl = 0;
	o__1.osta = "SCRATCH";
	o__1.oacc = "SEQUENTIAL";
	o__1.ofm = "FORMATTED";
	o__1.oblnk = 0;
	iostat = f_open(&o__1);
	if (iostat != 0) {

/*           If there was an error then we need to close the text */
/*           file, and then check out and return to the caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = scrlun;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    setmsg_("Error opening temporary file. IOSTAT = #.", (ftnlen)41);
	    errint_("#", &iostat, (ftnlen)1);
	    sigerr_("SPICE(FILEOPENERROR)", (ftnlen)20);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}

/*        Continue reading lines from the text file and storing them */
/*        in the scratch file until we get to the end marker. We do not */
/*        write the begin and end markers to the scratch file. We do not */
/*        need them. */

	eoc = FALSE_;
	while(! eoc) {
	    ci__1.cierr = 1;
	    ci__1.ciend = 1;
	    ci__1.ciunit = *number;
	    ci__1.cifmt = "(A)";
	    iostat = s_rsfe(&ci__1);
	    if (iostat != 0) {
		goto L100002;
	    }
	    iostat = do_fio(&c__1, line, (ftnlen)255);
	    if (iostat != 0) {
		goto L100002;
	    }
	    iostat = e_rsfe();
L100002:
	    if (iostat != 0) {

/*              If there was an error then we need to close the */
/*              scratch file, the text file, and then check out */
/*              and return to the caller. */

		cl__1.cerr = 0;
		cl__1.cunit = scrlun;
		cl__1.csta = 0;
		f_clos(&cl__1);
		cl__1.cerr = 0;
		cl__1.cunit = *number;
		cl__1.csta = 0;
		f_clos(&cl__1);
		setmsg_("Error reading the text file: #. IOSTAT = #.", (
			ftnlen)43);
		errch_("#", txtfil, (ftnlen)1, txtfil_len);
		errint_("#", &iostat, (ftnlen)1);
		sigerr_("SPICE(FILEREADFAILED)", (ftnlen)21);
		chkout_("ZZCONVTB", (ftnlen)8);
		return 0;
	    }

/*           If we are not at the end of the comments, then write the */
/*           line ot the scratch file. Otherwise set the end of comments */
/*           flag to .TRUE.. */

	    i__1 = ltrim_(line, (ftnlen)255) - 1;
	    if (s_cmp(line + i__1, "~NAIF/SPC END COMMENTS~", 255 - i__1, (
		    ftnlen)23) != 0) {
		ci__1.cierr = 1;
		ci__1.ciunit = scrlun;
		ci__1.cifmt = "(A)";
		iostat = s_wsfe(&ci__1);
		if (iostat != 0) {
		    goto L100003;
		}
		iostat = do_fio(&c__1, line, rtrim_(line, (ftnlen)255));
		if (iostat != 0) {
		    goto L100003;
		}
		iostat = e_wsfe();
L100003:
		if (iostat != 0) {

/*                 If there was an error then we need to close the */
/*                 scratch file, the text file, and then check out */
/*                 and return to the caller. */

		    cl__1.cerr = 0;
		    cl__1.cunit = scrlun;
		    cl__1.csta = 0;
		    f_clos(&cl__1);
		    cl__1.cerr = 0;
		    cl__1.cunit = *number;
		    cl__1.csta = 0;
		    f_clos(&cl__1);
		    setmsg_("Error writing to temporary file. IOSTAT = #.", (
			    ftnlen)44);
		    errint_("#", &iostat, (ftnlen)1);
		    sigerr_("SPICE(FILEWRITEFAILED)", (ftnlen)22);
		    chkout_("ZZCONVTB", (ftnlen)8);
		    return 0;
		}
	    } else {
		eoc = TRUE_;
	    }
	}

/*        Open the new binary file and add the comments that have been */
/*        stored temporarily in a scratch file. */

	dafopw_(binfil, &handle, binfil_len);
	if (failed_()) {

/*           If there was an error then we need to close the scratch */
/*           file and the text file, and then check out and return to */
/*           the caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = scrlun;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}
	spcac_(&handle, &scrlun, " ", " ", (ftnlen)1, (ftnlen)1);
	if (failed_()) {

/*           If there was an error then we need to close the scratch */
/*           file and the text file, and then check out and return to */
/*           the caller. */

	    cl__1.cerr = 0;
	    cl__1.cunit = scrlun;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    cl__1.cerr = 0;
	    cl__1.cunit = *number;
	    cl__1.csta = 0;
	    f_clos(&cl__1);
	    dafcls_(&handle);
	    chkout_("ZZCONVTB", (ftnlen)8);
	    return 0;
	}

/*        We succeeded, so close the files we opened to deal with the */
/*        comments. The scratch file is automatically deleted. */

	cl__1.cerr = 0;
	cl__1.cunit = scrlun;
	cl__1.csta = 0;
	f_clos(&cl__1);
	dafcls_(&handle);
    }

/*     Close the transfer file. We know it is open, because we got here. */

    cl__1.cerr = 0;
    cl__1.cunit = *number;
    cl__1.csta = 0;
    f_clos(&cl__1);
    chkout_("ZZCONVTB", (ftnlen)8);
    return 0;
} /* zzconvtb_ */
/* $Procedure      M2NUMB ( Determine whether or not a word is a number ) */
logical m2numb_(char *word, ftnlen word_len)
{
    /* System generated locals */
    logical ret_val;

    /* Builtin functions */
    logical l_le(char *, char *, ftnlen, ftnlen), l_ge(char *, char *, ftnlen,
	     ftnlen);
    integer s_cmp(char *, char *, ftnlen, ftnlen);
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);

    /* Local variables */
    static doublereal x;
    extern integer ltrim_(char *, ftnlen);
    static char error[80];
    static integer start, length;
    extern /* Subroutine */ int nparsd_(char *, doublereal *, char *, integer 
	    *, ftnlen, ftnlen);
    static integer pointr;
    extern integer qrtrim_(char *, ftnlen);
    static integer end;

/* $ Abstract */

/*     This function is true if the input string is a number in the */
/*     sense of META/2. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     META/2 a language specification language. */

/* $ Keywords */

/*     ALPHANUMERIC */
/*     ASCII */
/*     PARSING */
/*     UTILITY */
/*     WORD */

/* $ Declarations */
/* $ Brief_I/O */

/*     VARIABLE  I/O  DESCRIPTION */
/*     --------  ---  -------------------------------------------------- */
/*     WORD       I   A character string word */

/*     The function is returned as .TRUE. if word is an META/2 number. */

/* $ Detailed_Input */

/*     WORD      is a character string that is assumed to have no */
/*               spaces between the first and last non-blank characters. */

/* $ Detailed_Output */

/*     M2NUMB    returns as .TRUE. if WORD is a parsable number. */
/*               Otherwise it is returned .FALSE. */

/* $ Error_Handling */

/*     None. */
/* C */
/* $ Input_Files */

/*     None. */

/* $ Output_Files */

/*     None. */

/* $ Particulars */

/*     This is a utility routine for the subroutine META2.  It */
/*     determines whether or not a word is a number in the sense */
/*     of the language META/2. */

/* $ Examples */

/*     WORD                                  M2NUMB */
/*     -------                               ------ */
/*     SPAM                                  .FALSE. */
/*     1                                     .TRUE. */
/*     0.289E19                              .TRUE. */
/*     0.2728D12                             .TRUE. */
/*     -12.1892e-5                           .TRUE. */
/*     12.E29                                .TRUE. */
/*     12.E291                               .FALSE. */
/*     .E12                                  .FALSE. */
/*     1.2E.12                               .FALSE. */

/* $ Restrictions */

/*     None. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     W.L. Taber     (JPL) */
/*     I.M. Underwood (JPL) */

/* $ Version */

/* -     META/2 Configured Version 2.0.0, 9-MAY-1994 (WLT) */

/*         This is the configured version of the Command Loop */
/*         software as of May 9, 1994 */


/* -     META/2 Configured Version 1.0.0, 3-MAY-1994 (WLT) */

/*         This is the configured version of META/2 */
/*         software as of May 3, 1994 */


/*     Version B1.0.0, 22-MAR-1988 (WLT) (IMU) */

/* -& */

/*     SPICELIB functions */


/*     Local variables */


/*     Make sure the string has the right length. */

    start = ltrim_(word, word_len);
    end = qrtrim_(word, word_len);
    length = end - start + 1;

/*     Rule out the goofy cases that NPARSD will allow. */

    if (length == 1) {
	ret_val = l_le("0", word, (ftnlen)1, word_len) && l_ge("9", word, (
		ftnlen)1, word_len);
	return ret_val;
    }
    if (length >= 2) {
	if (*(unsigned char *)&word[start - 1] == 'E' || *(unsigned char *)&
		word[start - 1] == 'e' || *(unsigned char *)&word[start - 1] 
		== 'D' || *(unsigned char *)&word[start - 1] == 'd') {
	    ret_val = FALSE_;
	    return ret_val;
	}
	if (s_cmp(word + (start - 1), "+E", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "-E", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "+D", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "-D", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "-e", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "+e", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "-d", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), "+d", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), ".E", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), ".D", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), ".e", (ftnlen)2, (ftnlen)2) == 0 || 
		s_cmp(word + (start - 1), ".d", (ftnlen)2, (ftnlen)2) == 0) {
	    ret_val = FALSE_;
	    return ret_val;
	}
    }
    if (length >= 3) {
	if (s_cmp(word + (start - 1), "+.E", (ftnlen)3, (ftnlen)3) == 0 || 
		s_cmp(word + (start - 1), "-.E", (ftnlen)3, (ftnlen)3) == 0 ||
		 s_cmp(word + (start - 1), "+.D", (ftnlen)3, (ftnlen)3) == 0 
		|| s_cmp(word + (start - 1), "-.D", (ftnlen)3, (ftnlen)3) == 
		0) {
	    ret_val = FALSE_;
	    return ret_val;
	}
    }

/*     Ok.  Now just hit the word with NPARSD. */

    s_copy(error, " ", (ftnlen)80, (ftnlen)1);
    nparsd_(word, &x, error, &pointr, word_len, (ftnlen)80);

/*     Any errors indicate we don't have a number. */

    if (s_cmp(error, " ", (ftnlen)80, (ftnlen)1) != 0) {
	ret_val = FALSE_;
    } else {
	ret_val = TRUE_;
    }
    return ret_val;
} /* m2numb_ */
/* Subroutine */ int cmloop_(char *delim, char *prompt, char *lognam, char *
	versn, S_fp greet, S_fp preprc, S_fp action, ftnlen delim_len, ftnlen 
	prompt_len, ftnlen lognam_len, ftnlen versn_len)
{
    /* Initialized data */

    static char spcial[8*2] = "        " "?       ";

    /* System generated locals */
    address a__1[2], a__2[7], a__3[3];
    integer i__1[2], i__2[7], i__3[3], i__4;

    /* Builtin functions */
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen), s_cat(char *,
	     char **, integer *, integer *, ftnlen);
    integer s_rnge(char *, integer, char *, integer);

    /* Local variables */
    extern /* Subroutine */ int echo_(char *, char *, ftnlen, ftnlen);
    extern logical have_(char *, ftnlen);
    static integer from;
    static logical trap;
    static integer rest, l;
    static logical dolog;
    extern integer ltrim_(char *, ftnlen);
    static char error[1760*2], com2do[1024];
    extern logical no_(char *, ftnlen);
    extern /* Subroutine */ int logchk_(char *, char *, logical *, ftnlen, 
	    ftnlen), cmredo_(char *, integer *, logical *, ftnlen);
    extern integer isrchc_(char *, integer *, char *, ftnlen, ftnlen);
    static char commnd[1024], errflg[32];
    extern logical cmmore_(char *, ftnlen);
    extern /* Subroutine */ int setdel_(char *, ftnlen), erract_(char *, char 
	    *, ftnlen, ftnlen);
    static char usenam[255];
    extern /* Subroutine */ int errdev_(char *, char *, ftnlen, ftnlen);
    static logical problm;
    extern /* Subroutine */ int setdap_(char *, char *, ftnlen, ftnlen), 
	    getcom_(char *, integer *, ftnlen), edtcom_(char *, char *, char *
	    , integer *, ftnlen, ftnlen, ftnlen), builtn_(char *, logical *, 
	    char *, ftnlen, ftnlen), nsplog_(char *, logical *, ftnlen), 
	    nspend_(void), trnlat_(char *, char *, ftnlen, ftnlen), nsplgs_(
	    char *, char *, char *, ftnlen, ftnlen, ftnlen);
    static char hstyle[120];
    extern /* Subroutine */ int nsperr_(char *, char *, ftnlen, ftnlen), 
	    nspopl_(char *, char *, ftnlen, ftnlen);
    static char lstyle[120];
    extern /* Subroutine */ int cmstup_(void);
    extern integer qrtrim_(char *, ftnlen);
    extern /* Subroutine */ int nspslr_(integer *, integer *);
    static char sstyle[120];
    extern /* Subroutine */ int ressym_(char *, char *, ftnlen, ftnlen);
    static char vstyle[120];
    extern /* Subroutine */ int nspsty_(char *, char *, ftnlen, ftnlen);
    static logical log__[4], hit;


/* $ Abstract */

/*     This routine handles the main processing loop of a */
/*     command driven program. */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Required_Reading */

/*     None. */

/* $ Keywords */

/*     INTERFACE */

/* $ Declarations */
/* $ Brief_I/O */

/*     Variable  I/O  Description */
/*     --------  ---  -------------------------------------------------- */
/*     DELIM      I   Non-blank character used to delimit commands */
/*     PROMPT     I   Prompt to let the user know input is expected */
/*     LOGNAM     I   Name pattern of file where commands will be logged */
/*     VERSN      I   Program name and version */
/*     INTIZE     S   Subroutine that initializes I/O facilities */
/*     GREET      S   Displays a banner at program startup */
/*     ACTION     S   The command parser and processor. */

/* $ Detailed_Input */

/*     DELIM     is a character that will be used to tell the */
/*               program that a command has ended. Commands may */
/*               extend over as many lines as allowed by the */
/*               configuration include file.  They end on the */
/*               first line on which the delimiter character is */
/*               encountered. THIS CHARACTER MUST NOT BE "?" */

/*     PROMPT    is a string used to prompt the user for commands. */
/*               Typically, this is the name of the program that */
/*               calles CMLOOP. */

/*     LOGNAM    is a pattern to use when creating the name of */
/*               a file to which all commands will be written. */
/*               This can be hard coded in the calling */
/*               program, or may be determined by a file naming */
/*               convention such as is provided by Christen */
/*               and NOMEN. */

/*     VERSN     is a string that may contain anything you would */
/*               like to appear as descriptive text in the first */
/*               line of the log file (and possibly in the greeting */
/*               presented by the program)  Something like */
/*               '<program name> --- Version X.Y' would be appropriate. */
/*               For example if your programs name is KINDLE and you */
/*               are at version 4.2.3 of your program a good value for */
/*               VERSN would be */

/*               'KINDLE --- Version 4.2.3' */

/*               Your greeting routine can make use of this when */
/*               displaying your program's greeting.  In this way */
/*               you can centralize the name and version number of */
/*               your program at a high level or in a subroutine and */
/*               simply make the information available to CMLOOP so */
/*               that the automatic aspects of presenting this */
/*               information can be handled for you. */


/*     GREET     is a routine that displays a message at program */
/*               startup.  This should contain the version number */
/*               of the program, any general instructions such */
/*               as how to get help and who the author or organization */
/*               is that is responsible for this program. GREET */
/*               takes a single argument VERSN which you supply in */
/*               your call to CMLOOP.  It may also have */
/*               initializations that override various items set */
/*               up prior to the call to GREET such as the style */
/*               used for displaying error messages.  GREET */
/*               is the action taken by CMLOOP  before commencing the */
/*               loop of fetching and processing commands. */

/*     PREPRC    is a command preprocessor.  It might remove */
/*               non-printing characters such as TABS, resolve */
/*               symbols and convert units to expected ranges. */

/*     ACTION    is a routine responsible for action upon the commands */
/*               entered by a user at the keyboard. ACTION has two */
/*               arguments COMMAND a string input and ERROR a two */
/*               dimensional array for error and diagnostic output. */
/*               The first message should point to the the problem */
/*               assuming the user is aware of the context in which */
/*               the problem occurred.  The second message will */
/*               have more detailed information including trace */
/*               and other technical information. */

/* $ Detailed_Output */

/*     None. */

/* $ Parameters */

/*     The parameters COMSIZ and ERRSIZ are given in the include */
/*     file commdpar.inc. */

/*     COMSIZ  is maximum number of characters that can be present */
/*             in a command. */

/*     ERRSIZ  is the maximum number of characters that can be used */
/*             when creating a diagnostic message. */

/* $ Exceptions */

/*     None.  This routine cannot detect any errors in its inputs */
/*     and all commands are regarded as legal input at this level. */
/*     Some can be acted on while others cannot.  Commands that */
/*     can not be exercised are expected to return diagnostics */
/*     in the array ERROR.  These are then reported by the */
/*     program to the user via his/her terminal. */

/* $ Files */

/*     The file specified by LOGFIL will be opened if possible */
/*     and all user commands and messages will be written to this */
/*     file. */

/*     Other files may be used a run time by "STARTing" a command */
/*     sequence file. Or by some result of the activity of the */
/*     user supplied routines ACTION, GREET, PREPRC. */

/* $ Particulars */

/*     This routine organizes the main loop of a command line */
/*     program so that the calling program can automatically */
/*     log files that a user enters, report errors in a uniform */
/*     manner and make use of sequences of commands stored in */
/*     files. The calling program supplies routines that handle */
/*     the chores of greeting the user and performing special */
/*     program initializations and performing actions based upon */
/*     the commands supplied by the user.  By making use of this */
/*     routine and its subordinates, the user inherits a flexible */
/*     I/O system and command interface freeing him/her to concentrate */
/*     on the actions of the program. */

/*     However, there is a minor price incurred by making use of */
/*     this routine.  Several commands have specific meanings that */
/*     the user cannot override.  They are commands that start with: */

/*        start */
/*        exit */
/*        stop */
/*        quit */
/*        echo */
/*        no echo */
/*        demo on */
/*        demo off */
/*        wait on */
/*        wait off */
/*        pause */
/*        ? */
/*     These commands are case insensitive with respect to the */
/*     words presented above. */


/* $ Examples */

/*     None. */

/* $ Restrictions */

/*     None. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     W.L. Taber    (JPL) */

/* $ Version */

/* -     Command Loop Configured Version 6.0.0, 20-JUN-2000 (WLT) */

/*         Added the ability to run the loop without logging */
/*         of inputs. */

/* -     Command Loop Configured Version 5.0.0, 23-MAR-2000 (WLT) */

/*         Modified the routine to call NSPEND instead of FINISH */
/*         now that NSPIO has been redone. */

/* -     Command Loop Configured Version 4.0.0, 20-NOV-1995 (WLT) */

/*         Added ability to run programs in batch mode and to */
/*         start procedures at program startup. */

/* -     Command Loop Configured Version 3.0.0, 1-AUG-1995 (WLT) */

/*         The routine was modified to better support command */
/*         pre-processing.  In particular symbol definition */
/*         and resolution is now supported. */

/* -     Command Loop Configured Version 2.0.0, 19-JUL-1995 (WLT) */

/*         A slight change was made so that the command delimiter */
/*         is now stored in the routine GETDEL.  Also errors */
/*         are now checked after command pre-processing has */
/*         been performed. */

/* -     Command Loop Configured Version 1.0.0, 3-MAY-1994 (WLT) */

/*         This is the configured version of the Command Loop */
/*         software as of May 4, 1994 */


/* -    Beta Version 1.0.0, 8-OCT-1993 (WLT) */

/* -& */

/*     Language Sensitive Strings */

/* $ Disclaimer */

/*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
/*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
/*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
/*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
/*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
/*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
/*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
/*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
/*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
/*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */

/*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
/*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
/*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
/*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
/*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
/*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */

/*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
/*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
/*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
/*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */

/* $ Version */

/* -     Command Loop Configured Version 1.0.0, 3-MAY-1994 (WLT) */

/*         This is the configured version of the Command Loop */
/*         software as of May 4, 1994 */


/*     The following parameters are the system parameters required */
/*     by PERCY.  Be sure to read any notes before adjusting these */


/*     The maximum number of commands that can be buffered is */
/*     determined by the value of MAXCOM.  This parameter is */
/*     used primarily by NXTCOM. */


/*     The parameter FILEN is the maximum length of a file name */
/*     on a particular system. */


/*     The parameter COMSIZ is the maximum length allowed for a */
/*     command. */


/*     The parameter ERRSIZ is the maximum length allowed for */
/*     error messages. */


/*     The parameter STYSIZ is the maximum length expected for */
/*     a NICEPR style string. */


/*     The following are for special commands that will not be */
/*     processed by ACTION. */


/*     Store the delimiter used by the program incase someone */
/*     else needs to know later on. */

    setdel_(delim, delim_len);

/*     First, set up the SPICELIB error handling. */

    s_copy(error, " ", (ftnlen)1760, (ftnlen)1);
    s_copy(error + 1760, " ", (ftnlen)1760, (ftnlen)1);
    s_copy(commnd, " ", (ftnlen)1024, (ftnlen)1);
    log__[0] = FALSE_;
    log__[1] = FALSE_;
    log__[2] = TRUE_;
    log__[3] = TRUE_;
    erract_("SET", "RETURN", (ftnlen)3, (ftnlen)6);
    errdev_("SET", "NULL", (ftnlen)3, (ftnlen)4);

/*     Set the prompt for the program. */

    setdap_(delim, prompt, delim_len, prompt_len);

/*     The following styles are for reporting errors to the */
/*     screen and log file respectively. */

    trnlat_("ERRFLAG", errflg, (ftnlen)7, (ftnlen)32);
/* Writing concatenation */
    i__1[0] = 38, a__1[0] = "HARDSPACE ^ NEWLINE /cr VTAB /vt FLAG ";
    i__1[1] = 32, a__1[1] = errflg;
    s_cat(sstyle, a__1, i__1, &c__2, (ftnlen)120);
/* Writing concatenation */
    i__2[0] = 38, a__2[0] = "HARDSPACE ^ NEWLINE /cr VTAB /vt FLAG ";
    i__2[1] = 1, a__2[1] = delim;
    i__2[2] = qrtrim_(errflg, (ftnlen)32), a__2[2] = errflg;
    i__2[3] = 8, a__2[3] = " LEADER ";
    i__2[4] = 1, a__2[4] = delim;
    i__2[5] = 3, a__2[5] = "-- ";
    i__2[6] = 16, a__2[6] = "LEFT 1 RIGHT 72 ";
    s_cat(lstyle, a__2, i__2, &c__7, (ftnlen)120);

/*     The following styles will be used for logging of */
/*     commands and for commenting them out. */

    s_copy(vstyle, "LEFT 1 RIGHT 78 ", (ftnlen)120, (ftnlen)16);
/* Writing concatenation */
    i__3[0] = 23, a__3[0] = "LEFT 1 RIGHT 78 LEADER ";
    i__3[1] = 1, a__3[1] = delim;
    i__3[2] = 3, a__3[2] = "-- ";
    s_cat(hstyle, a__3, i__3, &c__3, (ftnlen)120);
    nspsty_(sstyle, lstyle, (ftnlen)120, (ftnlen)120);
    nsplgs_(vstyle, hstyle, delim, (ftnlen)120, (ftnlen)120, delim_len);
    nspslr_(&c__1, &c__78);

/*     See whether or not a log file should be used and if so */
/*     what it's name should be. */

    logchk_(lognam, usenam, &dolog, lognam_len, (ftnlen)255);

/*     Open a log file. */

    if (dolog) {
	nspopl_(usenam, versn, (ftnlen)255, versn_len);
    }
    if (have_(error, (ftnlen)1760)) {
	nsperr_(commnd, error, (ftnlen)1024, (ftnlen)1760);
    }

/*     Present a greeting to the user and perform any override */
/*     or special initializations that need to be local to this */
/*     routine. */

    (*greet)(versn, versn_len);

/*     Get the input command line.  This may have */
/*     several useful bits of information to tell us how */
/*     to run the program. */

/*     -b      means run the program in batch mode.  In this case */
/*             we should never prompt the user for information. */

/*     -start  means we have a startup file to use and we want to */
/*             use the name of that file to determine how to */
/*             proceed. */

    cmstup_();

/*     Fetch and log the first command. */

    trap = TRUE_;

/*     Get the next command and resolve any symbols or */
/*     queries that might show up in it, */

    while(trap) {
	getcom_(com2do, &from, (ftnlen)1024);
	edtcom_(delim, prompt, com2do, &from, delim_len, prompt_len, (ftnlen)
		1024);
	if (no_(error, (ftnlen)1760) && log__[(i__4 = from) < 4 && 0 <= i__4 ?
		 i__4 : s_rnge("log", i__4, "cmloop_", (ftnlen)430)]) {
	    nsplog_(com2do, &c_false, (ftnlen)1024);
	}
	if (no_(error, (ftnlen)1760)) {
	    ressym_(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
	    echo_(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
	}
	if (no_(error, (ftnlen)1760)) {
	    cmredo_(commnd, &from, &trap, (ftnlen)1024);
	}
	if (have_(error, (ftnlen)1760)) {
	    trap = FALSE_;
	}
    }

/*     Now apply the user's preprocessing software */
/*     to the comman. */

    s_copy(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
    (*preprc)(com2do, commnd, (ftnlen)1024, (ftnlen)1024);

/*     Now process commands until we get an EXIT command. */

    while(cmmore_(commnd, (ftnlen)1024)) {

/*        Perform any preprocessing that can be performed easily */
/*        on this command. */

	if (no_(error, (ftnlen)1760)) {
	    builtn_(commnd, &hit, error, (ftnlen)1024, (ftnlen)1760);
	}
	if (no_(error, (ftnlen)1760) && ! hit) {
	    l = ltrim_(commnd, (ftnlen)1024);
	    rest = qrtrim_(commnd, (ftnlen)1024) + 1;
	    if (isrchc_(commnd + (l - 1), &c__2, spcial, rest - (l - 1), (
		    ftnlen)8) == 0) {
		(*action)(commnd, error, (ftnlen)1024, (ftnlen)1760);
	    }
	}
	problm = have_(error, (ftnlen)1760);

/*        Process any errors that were diagnosed. */

	nsperr_(commnd, error, (ftnlen)1024, (ftnlen)1760);

/*        Fetch and log the next command. */

	trap = TRUE_;
	while(trap) {
	    getcom_(com2do, &from, (ftnlen)1024);
	    edtcom_(delim, prompt, com2do, &from, delim_len, prompt_len, (
		    ftnlen)1024);
	    if (no_(error, (ftnlen)1760) && log__[(i__4 = from) < 4 && 0 <= 
		    i__4 ? i__4 : s_rnge("log", i__4, "cmloop_", (ftnlen)496)]
		    ) {
		nsplog_(com2do, &c_false, (ftnlen)1024);
	    }
	    if (no_(error, (ftnlen)1760)) {
		ressym_(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
		echo_(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
	    }
	    if (no_(error, (ftnlen)1760)) {
		cmredo_(commnd, &from, &trap, (ftnlen)1024);
	    }
	    if (have_(error, (ftnlen)1760)) {
		trap = FALSE_;
	    }
	}

/*        Now apply the user's preprocessing software */
/*        to the comman. */

	s_copy(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
	(*preprc)(com2do, commnd, (ftnlen)1024, (ftnlen)1024);
    }

/*     Take care of closing files and so on. */

    if (log__[(i__4 = from) < 4 && 0 <= i__4 ? i__4 : s_rnge("log", i__4, 
	    "cmloop_", (ftnlen)526)]) {
	nspend_();
    }
    return 0;
} /* cmloop_ */