/* @(#)catal.c 17.1.1.2 (ESO-DMD) 02/25/02 17:52:56 */ /*=========================================================================== 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 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence 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 ===========================================================================*/ /*+++++++++++++++++++++ CATAL.C +++++++++++++++++++++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION Module CATAL.C .COMMENTS Support all MIDAS catalog commands .AUTHOR K. Banse ESO - Garching .KEYWORDS: MIDAS catalogue .PURPOSE: manage the MIDAS catalogues .ALGORITHM: use the SCC catalog interfaces to handle the different functions .INPUT/OUTPUT: the following keys are used: DEFAULT/C/1/1 DEFAULT(1:1) = Y, we have a directory file = T, we have table input + must build `directory.dat' ACTION/C/1/3 action to perform, CREATE, LIST, SEARCH or SHOW IN_A/C/1/60 cat. name P4/C/1/1 display flag for SEARCH INPUTC/C/1/60 frame list the following keys are written OUT_A/C/1/20 matching frame for SEARCH OUTPUTI/I/11/1 no. of entries fo SHOW .VERSION [1.00] 880714: from FORTRAN version 3.50 as of 870910 020220 last modif -------------------------------------------------------------------------*/ #include #include #include /* */ int main() { int fid, ity, oty, iflag, iav, nulo; int out[3], fno; int n, jj, ll, clen, begin, kcount, stat; int cimno, uni; int *ipntr; int idum; unsigned int nbytes; register int nr; char action[4]; char ident[80], def[2]; char catfile[84], output[84]; char cbuf[80]; char *adr0, *adr1, *adr2, *cpntr, *fpntr; static char badguy[] = "+-*^()$"; static char blank[] = " "; /* 5 blanks (+ \0) */ void sortit(); (void) SCSPRO("catal"); (void) SCKRDC("ACTION",1,1,3,&iav,action,&uni,&nulo); /* what to do */ action[3] = '\0'; CGN_UPSTR(action); stat = SCKRDC("DEFAULT",1,1,2,&iav,def,&uni,&nulo); /* dirfile flag */ /* read name of catalog (length = CATALINFO(11)) */ (void) SCKGETC("IN_A",1,80,&iav,catfile); (void) SCKRDI("INPUTI",1,3,&iav,out,&uni,&nulo); /* get type_no + range */ ity = out[0]; /********************************************************* CREATE/xCATAL catalog *********************************************************/ if (strcmp(action,"CRE") == 0) { register int mr; if (def[0] == 'Y') iflag = 1; else if (def[0] == 'T') iflag = 2; else iflag = 0; for (nr=0; nr<(int)strlen(catfile); nr++) /* check for bad chars. */ { for (mr=0; mr<7; mr++) { if (badguy[mr] == catfile[nr]) { (void) sprintf(output,"Invalid char: `%c' in catalog name %s", badguy[mr],catfile); SCETER(11,output); } } } if (iflag == 2) /* we read a table + build `directory.dat' */ { char *cpntr; stat = SCKGETC("IN_B",1,60,&iav,ident); /* table,column spec */ n = CGN_INDEXS(ident,",:"); if (n < 1) n = CGN_INDEXS(ident,",#"); ident [n] = '\0'; n ++; /* n must be > 0 ... */ stat = TCTOPN(ident,F_I_MODE,&cimno); stat = TCCSER(cimno,&ident[n],&fno); if (fno < 0) { (void) sprintf(output,"Could not find column %s",&ident[n]); SCETER(10,output); } stat = TCIGET(cimno,&iav,&clen,&iav,&iav,&iav); stat = TCBGET(cimno,fno,&jj,&iav,&iav); if (jj != D_C_FORMAT) SCETER(11,"column not of type CHARACTER..."); fid = osaopen("dirfile.ascii",WRITE); if (fid < 0) SCETER(3,"Could not create `dirfile.ascii' ..."); for (nr=1; nr<=clen; nr++) { stat = TCSGET(cimno,nr,&jj); /* check selection flag */ if (jj) { stat = TCEMAP(cimno,nr,fno,&cpntr,&jj); if (!jj) osawrite(fid,cpntr,(int)strlen(cpntr)); /* write, if != NULL */ } } osaclose(fid); TCTCLO(cimno); iflag = 1; } (void) SCKGETC("P3",1,60,&iav,ident); stat = SCCCRA(catfile,ity,iflag,ident); stat = SCKRDI("OUTPUTI",10,1,&iav,out,&uni,&nulo); if (out[0] > 1) (void) strcpy(ident,"entries"); else (void) strcpy(ident,"entry"); if (ity == F_TBL_TYPE) (void) sprintf(output,"Table catalog %s with %d %s created...", catfile,out[0],ident); else if (ity == F_FIT_TYPE) (void) sprintf(output,"Fit file catalog %s with %d %s created...", catfile,out[0],ident); else if (ity == F_IMA_TYPE) (void) sprintf(output,"Image catalog %s with %d %s created...", catfile,out[0],ident); else (void) sprintf(output,"ASCII file catalog %s with %d %s created...", catfile,out[0],ident); SCTPUT(output); } else { stat = MID_COPN(catfile,&jj,&cimno); if (stat != ERR_NORMAL) { (void) sprintf(output,"Could not open catalog file %s",catfile); SCETER(1,output); } oty = jj; if (oty != ity) SCETER(4,"Command qualifier and catalog type do not match..."); /********************************************************* SHOW/xCATAL catal disp_option *********************************************************/ if (strcmp(action,"SHO") == 0) { stat = SCCSHO(catfile,out,&out[1]); stat = SCKWRI("OUTPUTI",out,1,2,&uni); /* save in key OUTPUTI(1,2) */ fid = osaopen(catfile,READ); (void) osaread(fid,cbuf,80); jj = CGN_INDEXC(cbuf,',') + 2; if (jj < 3) (void) strcpy(cbuf,"IDENT"); else (void) strcpy(cbuf,cbuf+jj); (void) osaclose(fid); stat = SCKGETC("P2",1,2,&iav,output); /* get display flag */ if ( (output[0] == 'D') || (output[0] == 'd') ) { if (ity == F_TBL_TYPE) (void) sprintf(output,"Table Catalog: %s ",catfile); else if (ity == F_FIT_TYPE) (void) sprintf(output,"FitFile Catalog: %s ",catfile); else if (ity == F_IMA_TYPE) (void) sprintf(output,"Image Catalog: %s ",catfile); else (void) sprintf(output,"ASCII File Catalog: %s ",catfile); SCTPUT(output); (void) sprintf(output,"descriptor used for `Ident' is: %s",cbuf); SCTPUT(output); (void) sprintf(output,"No. of entries = %d, last entry = %d",out[0],out[1]); SCTPUT(output); } } /********************************************************* READ,PRINT/xCATAL catal range *********************************************************/ else if ((strcmp(action,"REA") == 0) || (strcmp(action,"PRI") == 0) ) { if ((out[1] < 1) || (out[2] < 1) || (out[2] < out[1])) SCETER(2,"invalid catalog entry range ..."); stat = SCKGETC("P3",1,5,&iav,cbuf); CGN_UPSTR(cbuf); if (strncmp(cbuf,"BRIEF",5) == 0) stat = outcat(catfile,1,&out[1]); /* just filenames */ else stat = SCCLIS(catfile,&out[1]); /* full display */ } /********************************************************* SORT/xCATAL catal ident *********************************************************/ else if (strcmp(action,"SOR") == 0) { if (ity == F_ASC_TYPE) SCETER(13,"Sorting not supported for ASCII catalogs..."); stat = SCCSHO(catfile,out,&out[1]); /* get no. of entries */ if (out[0] < 2) { if (out[0] < 1) (void) printf("No entries in catalog %s ...\n",catfile); else (void) printf( "Only 1 entry in catalog %s - nothing to sort ...\n",catfile); goto end_of_it; } ll = out[0] + 1; /* for the sorting we need 1 elem more */ clen = 60; /* filenames max. 60 chars */ nbytes = ll*clen; adr0 = malloc(nbytes); /* space for file names */ fpntr = adr0+clen; /* point to actual 2. elem */ jj = CATIDENT_LEN; nbytes = (ll*jj)+4; /* + 4 because of trailing `\0' in Ident field of catalog-rec. */ adr1 = malloc(nbytes); /* space for idents */ cpntr = adr1+jj; nbytes = ll*sizeof(int); adr2 = malloc(nbytes); /* space for entry numbers */ ipntr = ((int *) adr2) + 1; idum = 0; /* to start the catalog search */ for (nr=0; nr= 0) { if ((*action == 'D') || (*action == 'd')) { (void) sprintf(output,"first match for frame: %s",cbuf); SCTPUT(output); } (void) SCKWRC("OUT_A",1,cbuf,1,60,&uni); goto end_of_it; } else { idum ++; /* count no. of valid returns */ if (idum>= out[0]) break; } } } } else { /* we go from the beginning up */ for (nr=0; nr= 0) { if ((*action == 'D') || (*action == 'd')) { (void) sprintf(output,"first match for frame: %s",cbuf); SCTPUT(output); } (void) SCKWRC("OUT_A",1,cbuf,1,60,&uni); goto end_of_it; } } } CGN_FILL(cbuf,' ',60); (void) SCKWRC("OUT_A",1,cbuf,1,60,&uni); /* save in key OUT_A */ } } /* that's it folks... */ end_of_it: return SCSEPI(); } /* */ void sortit(field,flen,ika,ndim) /* ndim = dimension of array ika for sorting but we pass the arrays with 1 element in front, so that the algorithm sorts from [1] -> [ndim] this is the Heapsort algorithm from "Numerical Recipes", page 231 */ char *field; int flen, *ika, ndim; { int kka, m, ir, j, i, ioff, koff; m = ndim/2 + 1; ir = ndim; while (1) { if (m > 1) /* still hiring */ kka = ika[--m]; else /* in retirement + promotion phase */ { kka = ika[ir]; /* clear a space at end of array ika */ ika[ir] = ika[1]; /* retire the top of the heap into it */ if (--ir == 1) /* done with last promotion */ { ika[1] = kka; /* the least competent guy of all... */ return; /* that's it folks */ } } /* in hiring as well as in promotion phase */ /* here set up to sift down kka to its right level */ i = m; j = m << 1; /* in FORTRAN: j = m + m */ while (j <= ir) { if (j < ir) { ioff = ika[j] * flen; koff = ika[j+1] * flen; /* compare to the better underling */ if (strcmp((field+ioff),(field+koff)) < 0) j++; } ioff = kka *flen; koff = ika[j] *flen; if (strcmp((field+ioff),(field+koff)) < 0) /* demote kka */ { ika[i] = ika[j]; i = j; j = j << 1; /* in FORTRAN: j = j + j */ } else j = ir + 1; } ika[i] = kka; /* put kka into its slot */ } }