/* @(#)tbaload.c 17.1.1.1 (ES0-DMD) 01/25/02 17:47:09 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME tbaload.c .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY table utilities .COMMENTS Routines to load an opened table from an ASCII file and eventual format. .VERSION 1.0 25-Mar-1989 Definition J.D. Ponz .VERSION 1.1 16-May-1990 Change default length of char.strings J.D. Ponz .VERSION 3.0 05-Jul-1990 New version with column arrays F.O. Added tbl_loads (load with tabs) tbl_iload (load table size) 08-Mar-1992 Add the possibility of having null lines in data ------------------------------------------------------------*/ #include #include #include /* String Utilities */ #include #include #define MAXCHAR 4096 #define MAXCOL 256 char *osfsupply(); /* Creates filename from name + defaults */ char *osmsg(); /* Error for file i/o */ tbl_loadl(tid, datafile, n) /*++++++++++++++++++ .PURPOSE Populates an empty table from ASCII file; each column is defined as a single precision floating number. .RETURNS Status ------------------*/ int tid; /* IN: Table Concerned */ char *datafile; /* IN: Filename with data */ int n; /* IN: How many columns */ { int status, fid, nchar, nrow, j, i, lineno; int dummy; char label[1+TBL_LABLEN]; char buffer[MAXCHAR], *p, *errmsg, x; status = ERR_NORMAL; /* create columns by default */ for (i=1; (status == ERR_NORMAL) && (i<=n); i++) { sprintf(label,"LAB%03d",i); status = TCCINI (tid, D_R4_FORMAT, 1, "E15.6", "Unitless",label,&dummy); } if (status) return (status); /* open data file */ fid = osaopen(osfsupply(datafile,".dat"),F_I_MODE); if (fid < 0) fid = osaopen(datafile,F_I_MODE); if (fid < 0) { SCTPUT (osmsg()); return (ERR_FILBAD); } nrow = lineno = 0; while ( (nchar = osaread(fid,buffer,MAXCHAR)) >= 0) { lineno++; if (nchar == 0) continue; if ((*buffer == '#') || (*buffer == '!')) /* Comments... */ continue; if (nchar >= MAXCHAR) SCTPUT ("++++ Truncated record"); nrow++; p = buffer + strspan (buffer, _SPACE_); errmsg = (char *)0; for (j = 1; (!errmsg) && (j <= n) && (*p); j++) { if (*p == '*') p++; /* NULL */ else { i = strscan (p, _SPACE_); x = p[i]; p[i] = '\0'; if (status = TCEWRC (tid, nrow, j, p)) errmsg = "Bad number"; p += i; *p = x; } p += strspan (p, _SPACE_); } if (!*p) errmsg = "too many numbers"; if (j != (n+1)) errmsg = "too few numbers"; if (errmsg) { sprintf (buffer, "**** Datafile line %d, col %d: %s", nrow, j, errmsg); } } osaclose(fid); return (status); } tbl_loads(tid, datafile, col_sep,dtype) /*++++++++++++++++++ .PURPOSE Populates a table from an ASCII file, assuming that the columns have been created. .RETURNS Status ------------------*/ int tid; /* IN: Table Concerned */ char *datafile; /* IN: Filename with data */ char *col_sep; /* IN: char used to separate columns */ int dtype[MAXCOL]; { int status, fid, nrow, ncol, i, lineno, j, nchar, dummy; int find; char buffer[MAXCHAR], *p, *errmsg, x; char newcsep[10],text[80]; int zero, one, ec, el, ed; /* open data file */ newcsep[0] = '"'; strcat(newcsep,col_sep); fid = osaopen(osfsupply(datafile,".dat"),F_I_MODE); if (fid < 0) fid = osaopen(datafile,F_I_MODE); if (fid < 0) { sprintf(text,"**** Problem opening datafile: %s",datafile); SCTPUT (text); SCTPUT (osmsg()); return (ERR_FILBAD); } TCIGET(tid, &ncol, &nrow, &dummy, &dummy, &dummy); nrow = lineno = 0; /* Could in the future have COMMENTS ??? */ SCECNT("GET",&ec,&el,&ed); SCECNT("PUT",&one,&zero,&zero); while ( (nchar = osaread(fid,buffer,MAXCHAR)) >= 0) { lineno++; if (nchar >= MAXCHAR) SCTPUT ("++++ Truncated record"); nrow++; p = buffer; errmsg = (char *)0; if (dtype[0] == D_C_FORMAT && col_sep[strloc(col_sep,' ')]) { i = strspans(p,col_sep); if (p[i] == '"') find = 1; else find = 0; p = p + strspans(p,col_sep) + find; } else p += strspans(p,col_sep); for (j = 1; (!errmsg) && (j <= ncol); j++) { if (dtype[j-1] == D_C_FORMAT && find == 1 ) i = strloc(p,'"'); else i = strscans (p, col_sep); x = p[i]; p[i] = '\0'; status = TCEWRC (tid, nrow, j, p); if (status) { sprintf(text,"****Problems in datafile at line %d",lineno); SCTPUT(text); return(-1); } p += i; *p = x; if ( x == '"' && dtype[j-1] == D_C_FORMAT) p++ ; if (!*p) break; if (dtype[j] == D_C_FORMAT && col_sep[strloc(col_sep,' ')]) { i = strspans(p,col_sep); if (p[i] == '"') find = 1; else find = 0; p = p + strspans(p,col_sep) + find; } else p += strspans(p,col_sep); } if (!*p) errmsg = "too many numbers"; if (j != ncol) errmsg = "too few numbers"; if (errmsg) { sprintf (buffer, "**** Datafile line %d, col %d: %s", nrow, j, errmsg); } } SCECNT("PUT",&ec,&el,&ed); osaclose(fid); return (status); } tbl_load(tid, datafile, format) /*++++++++++++++++++ .PURPOSE Populated a table from ASCII file + FMT file .RETURNS Status .REMARKS If positions of the various fields are not defined, we assume that tabs are used as separators. ------------------*/ int tid; /* IN: Table Concerned */ char *datafile; /* IN: Filename with data */ char *format; /* IN: Name of Format File */ { int status, i, j, fid, gid, i2, i1, ncol, noelem, icc; char buffer[MAXCHAR], text[80], tabname[80], x; char *q; char col_sep[10]; char label[1+TBL_LABLEN], unit[1+TBL_UNILEN], form[10]; int ic, type, icol[MAXCOL], first[MAXCOL], last[MAXCOL]; int dtype[MAXCOL]; int ec,ed,el,zero,one; /* access format file to create columns */ one = 1; zero = 0; gid = osaopen(osfsupply(format, ".fmt"),F_I_MODE); if (gid < 0) { sprintf(text,"**** Problem opening format file: %s",format); SCTPUT (text); SCTPUT (osmsg()); return (ERR_FILBAD); } ncol = 0; while (osaread(gid,buffer,MAXCHAR) >= 0) { if ((stumatch(buffer,"fs")) == 2) { q = buffer + strloc(buffer,'"') + 1; i = strloc(q,'"'); q[i] = '\0'; charconv(q,col_sep); } else { status = tbl_decfmt(buffer,&i1,&i2,&type,&noelem,form,unit,label); if (status) return(status); if (type == 0) continue; status = TCCSER(tid,label,&icc) ; if (icc > 0) { sprintf(text,"*** Label %s specified more than once in the format file ***",label); SCTPUT(text); SCFNAME(tid,tabname,80); TCTCLO(tid); SCFDEL(tabname); SCSEPI(); } /* if ( (type == D_C_FORMAT) && (noelem == 1)) noelem = i2 - i1 + 1; /* added on request */ status = TCCINI(tid,type,noelem,form,unit,label,&ic); if (status) return(status); first[ncol] = i1; last[ncol] = i2; icol[ncol] = ic; dtype[ncol] = type; if (ncol >= MAXCOL) { SCTPUT ("**** Sorry, you've too many columns..."); return (ERR_TBLCOL); } ncol++; } } osaclose(gid); /* If no position parm. Assume tabs */ if (last[0] == 0) { if (col_sep[0] == '\0') strcpy(col_sep,"\t "); return (tbl_loads (tid, datafile, col_sep,dtype)); } /* open data file */ fid = osaopen(osfsupply(datafile,".dat"),F_I_MODE); if (fid < 0) fid = osaopen(datafile,F_I_MODE); if (fid < 0) { sprintf(text,"**** Problem opening datafile: %s",datafile); SCTPUT (text); SCTPUT (osmsg()); return (ERR_FILBAD); } i = 1; oscfill(buffer,MAXCHAR,'\0'); SCECNT("GET",&ec,&el,&ed); SCECNT("PUT",&one,&zero,&zero); while ( (status == ERR_NORMAL) && (osaread(fid,buffer,MAXCHAR) >= 0)) { for (j=0; j < ncol; j++) { x = buffer[last[j]], buffer[last[j]] = '\0'; status = TCEWRC(tid,i,icol[j],buffer-1+first[j]); if (status) { sprintf(text,"****Problems in datafile at line %d",i); SCTPUT(text); return(-1); } buffer[last[j]] = x; } i++; oscfill(buffer,MAXCHAR,'\0'); } SCECNT("PUT",&ec,&el,&ed); osaclose(fid); return (status); } tbl_iload(format, lines, cols) /*++++++++++++++++++ .PURPOSE Retrieve in Format File the Table Size .RETURNS Status .REMARKS Values are specified as "Row[s=]" for number of rows, "Col[umn=]" for number of columns. ------------------*/ char *format; /* IN: Name of Format File */ int *lines; /* OUT: Lines as found */ int *cols; /* OUT: Columns as found */ { int gid; char buffer[80],text[80]; /* access format file to create columns */ *lines = *cols = 0; gid = osaopen(osfsupply(format, ".fmt"),F_I_MODE); if (gid < 0) { sprintf(text,"**** Problem opening format file: %s",format); SCTPUT (text); SCTPUT (osmsg()); return (ERR_FILBAD); } /* Look in formatfile */ while ( (!*lines) && (!*cols) ) { if (osaread(gid, buffer, sizeof(buffer)) < 0) break; if (stumatch(buffer, "row") == 4) *lines = atoi (buffer + strscan (buffer, _SPACE_)); if (stumatch(buffer, "col") == 3) *cols = atoi (buffer + strscan (buffer, _SPACE_)); } osaclose (gid); return (ERR_NORMAL); } int charconv(p,q) char *q; char *p; { char t; int i; while ( *p != '\0') { if (*p == '\\') { p++; switch (t = *p) { case 't': *q++ = '\t'; p++; break; case 'n': *q++ = '\n'; p++; break; case 'r': *q++ = '\r'; p++; break; case 'b': *q++ = '\b'; p++; break; case 'f': *q++ = '\f'; p++; break; } } else *q++ = *p++; } }