#include #include #include "io_nc.h" /* getc_nc(), getword_nc() */ /***************************************************************************** * * * COMMON OCEANOGRAPHIC DATA ACCESS SYSTEM (CODAS) * * * * WRITTEN BY: RAMON CABRERA, ERIC FIRING, and JULIE RANADA * * JOINT INSTITUTE FOR MARINE AND ATMOSPHERIC RESEARCH * * 1000 POPE ROAD MSB 404 * * HONOLULU, HI 96822 * * * * VERSION: 3.00 * * * * DATE: APRIL 1989 * * * *****************************************************************************/ /* FILE: io_nc.c Comment-stripping file access routines. And a replacement for gets. */ char *gets_ok(char *buf, int n) { int i; fgets(buf, n, stdin); i = strlen(buf); if (i > 0 && buf[i-1] == '\n') {buf[i-1] = '\0';} return buf; } /*----------------------------------------------------------------------------- FUNCTION: getc_nc This is a routine to read the next character from a file, as getc does, but to skip over any areas that are commented out with "slash star....star slash". PARAMETER: fp = pointer to input file RETURNS: non-comment character if okay EOF on end of file */ int getc_nc(FILE *fp) /* "nc" is for "no comments" */ { int c1, c2; c1 = getc(fp); if (c1 != '/') return(c1); if ((c2 = getc(fp)) == '*') { do { c1 = c2; c2 = getc(fp); } while ( !((c1 == '*') && (c2 == '/')) && (c2 != EOF)); if (c2 == EOF) return(EOF); c1 = getc_nc(fp); } else ungetc(c2, fp); return(c1); } /*----------------------------------------------------------------------------- FUNCTION: getword_nc It reads the next word in the input file, skipping over any areas that are commented out with "slash asterisk...asterisk slash". The word returned is NULL-terminated. PARAMETERS: fp = pointer to input file buf = pointer to storage area for the word to be read (must allow for NULL terminator) bufsize = size in bytes of word storage area RETURNS: word length (excluding NULL terminator) */ int getword_nc(FILE *fp, char *buf, int bufsize) { int i; int c; /* Make sure there is room for a minimal string (1 char plus null) */ if (bufsize < 2) return(0); /* Find the first non-white character. */ while (((c = getc_nc(fp)) != EOF) && (c == ' ' || c == '\t' || c == '\n' || c == '\r')) ; /* Fill the string with non-white characters until white space is found. */ i = 0; while (c != EOF && i < bufsize-1 && c != ' ' && c != '\t' && c != '\n' && c != '\r') { buf[i] = c; i++; c = getc_nc(fp); } /* Append a NULL to the string. */ buf[i] = '\0'; return(i); /* Number of characters in string, excluding NULL. */ } /* getword_nc() */ /*----------------------------------------------------------------------------- FUNCTION: getwords_nc Reads the indicated number of words from an input file, skipping over areas that have been commented out by "slash asterisk... asterisk slash". The words are delimited by spaces. PARAMETERS: fp = pointer to input file buf = pointer to storage area for words to be read bufsize = size in bytes of storage area nwords = no. of words to read RETURNS: no. of words actually read = nwords if okay < nwords if end-of-file or buffer filled */ int getwords_nc(FILE *fp, char *buf, int bufsize, int nwords) { int i, length; char *buf_ptr; buf_ptr = buf; for (i = 0; i < nwords; i++) { length = getword_nc(fp, buf_ptr, bufsize); if (length == 0) return(i); /* number of words read so far */ if ((i + 1) < nwords) { /* Append a space to the buffer and adjust the pointer and remaining size. */ buf_ptr[length] = ' '; buf_ptr += (length + 1); bufsize -= (length + 1); } } buf_ptr[length] = '\0'; /* change last space back to a null */ return(i); /* Number of words requested = number supplied. */ } /* getwords_nc() */ /*----------------------------------------------------------------------------- FUNCTION: get2eol_nc Reads to the end of the current line from a file, skipping over areas that have been commented out by a "slash asterisk... asterisk slash". PARAMETERS: fp = pointer to input file buf = pointer to storage area for line to be read bufsize = size in bytes of storage area RETURNS: no. of bytes stored in buffer */ int get2eol_nc(FILE *fp, char *buf, int bufsize) { int c, i; /* skip over leading spaces/tabs */ while (((c = getc_nc(fp)) != EOF) && (c == ' ' || c == '\t' || c == '\r')) ; i = 0; while ((i < bufsize-1) && (c != EOF) && (c != '\n')) { if (c != '\r') buf[i] = c; i++; c = getc_nc(fp); } /* store to end of current line */ buf[i] = '\0'; return(i); } /*----------------------------------------------------------------------------- FUNCTION: strip_comments It copies the contents of the input file to another file, except for comments enclosed by "slash asterisk" and "asterisk slash". PARAMETERS: fp_in = pointer to input file fp_out = pointer to output file */ void strip_comments(FILE *fp_in, FILE *fp_out) { int c; while ( (c = getc_nc(fp_in)) != EOF) { if (c == '@') { char fn[180]; FILE *fp_incl; if (getword_nc(fp_in, fn, 180) > 0) { fp_incl = fopen(fn, "r"); if (fp_incl != NULL) { strip_comments(fp_incl, fp_out); /* recursive */ putc('\n', fp_out); /* in case the included file lacked LF */ fclose(fp_incl); } else { printf("Error opening include file: %s\n", fn); return; } } else { printf("Error reading include file name.\n"); return; } } /* Use the character only if it is NOT "@". */ else if (putc(c, fp_out) == EOF) { printf("\n Output error in strip_comments.\n"); return; } } return; } /*----------------------------------------------------------------------------- FUNCTION: get_quotation It searches a file for a phrase delimited by double quotes, up to a maximum of n characters. The phrase, minus the quotes, is loaded into the string , which is then NUL terminated. Escape sequences are appropriately accounted for. This function can be used for reading title information from a control file and for reading format strings for structure printing format specifications. PARAMETERS: fp = pointer to input file buf = pointer to storage area for quoted string bufsize = size in bytes of storage area RETURNS: pointer to storage area if okay NULL otherwise (end of file or insufficient buffer size) */ char *get_quotation(FILE *fp, char *buf, int bufsize) { int i, escape_sequence = 0; int c; for (i = 0; i < bufsize; i++) buf[i] = '\0'; /* Clear buffer */ /* search for leading quote */ while ((c = getc_nc(fp)) != '"' && c != EOF) ; /* read every non-comment character until buffer is full or trailing quote is encountered */ for (i = 0; i < bufsize && c != EOF; i++) { if (((c = getc(fp)) == '"') && !escape_sequence) { buf[i] = '\0'; return(buf); /* normal exit */ } else if (escape_sequence) { switch (c) { case 'n' : buf[i] = '\n'; break; case 't' : buf[i] = '\t'; break; case 'b' : buf[i] = '\b'; break; case 'r' : buf[i] = '\r'; break; case 'f' : buf[i] = '\f'; break; case '\\': buf[i] = '\\'; break; case '\'': buf[i] = '\''; break; case '"' : buf[i] = '\"'; break; default : buf[i] = c; } escape_sequence = 0; } else if (c == '\\') { escape_sequence = 1; i--; } else buf[i] = c; } return(NULL); /* EOF or too many characters */ }