/* @(#)scdold.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:26 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++ Module SCDOLD +++++++++++++++++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION SCDOLD.C .AUTHOR Klaus Banse ESO - Garching .COMMENTS holds MID_DSCDIR, SCDCOP for old descriptor format will be removed in version 02FEB .KEYWORDS MIDAS Descriptors .ENVIRONMENT VMS and UNIX .VERSION [1.00] 010314: creation from different descr. related modules 010314 last modif ------------------------------------------------------------------------*/ #include #include #define DATA_ISIZE 2048 /* 2048 int's */ #define DATA_CSIZE DATA_ISIZE*II_SIZE /* in bytes */ #define DATA_DSIZE DATA_CSIZE/DD_SIZE /* no. of double's */ #define DISK_REC 512 /* size of disk record */ static int nonul = -1; static int maxdim[4] = {DATA_ISIZE,DATA_ISIZE,DATA_CSIZE-1,DATA_DSIZE}; static char *datpntr; /* */ #ifdef __STDC__ int MID_DSCDIR(int entrx , char action , char * descr , char * type , int * bytelem , int * noelem , int * unit , int * block , int * indx) #else int MID_DSCDIR(entrx,action,descr,type,bytelem,noelem,unit,block,indx) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE interface to the descriptor directory .ALGORITHM A character descriptor (name = DIRECTORY.MIDAS) of initial length 1500 is stored from LDB #1 on, each descriptor is entered in this directory as follows: descr name (15 char), descr. type (1 char), 4 char. spares, no. of bytes per descr. element (I*2), no. of elements (I*2), start block (I*4) + start index (I*2) - the exact structural layout is in $MID_INCLUDE/dscext.h the functions provided are: F(ind), A(dd), D(elete) and E(xtend) a descriptor within the directory as well as the relevant LDB space (for Add + Extend only) It is assumed, that the FCB of the frame has already been read in! .RETURNS stat: I*4 return status --------------------------------------------------*/ int entrx /* IN : entry of frame in FCT */; char action /* IN : action to perform : \ F find, D delete, A add, E extend */; char *descr /* IN : descriptor name */; char *type /* IO : type of descriptor: I, R, C or D or H */; int *bytelem /* IO : no. of bytes per descr. element */; int *noelem /* IO : no. of descr. elements */; int *unit /* IO : unit pointer */; int *block /* OUT: starting block of descriptor */; int *indx /* OUT: starting index of descr. */; #endif { int ext, ext_len, iret, ios; int found, mm1, mm2, long_len, lastlen; int dirfirst, dirused, dirsize, dirlen, diroff, dscupda, totext; int status, n, mm, chanl, extens[2]; int myblock, myindx, idummy; static int old_diroff, old_found, old_ext; register int cdif, nr; char *cpntrb, *dscpntr, cdummy[4]; char cha, chz; static char old_descr[16]={' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', ' ',' ',' ',' ',' ',' '}; static char realdescr[16]; static char dscdir[1500]; float rdummy; struct FCT_STRUCT *fctpntr; struct FCB_STRUCT *fcbp; struct LDB_STRUCT *ldbp; fctpntr = FCT.ENTRIES + entrx; fcbp = fctpntr->FZP; status = ERR_NORMAL; chanl = fctpntr->IOCHAN; status = cacheLDB(1,chanl,fcbp->PTRLDB,&ldbp); if (status != ERR_NORMAL) return status; dscupda = 0; if (fcbp->DSCFLAG == 'N') /* new descriptor stuff */ { dirused = fcbp->DFILLED; dirsize = fcbp->DSIZE; } else { dirused = fcbp->DIRUSE; dirsize = fcbp->DIRNOELEM; } totext = dirsize/fcbp->DIREXT; /* total no. of extens for directory */ dscpntr = (char *) &DSCDIR_ENTRY.NAME[0]; /* branch on action */ if (action == 'A') goto add_descr; else if (action == 'E') goto extend_descr; else if (action == 'D') goto delete_descr; /* here for Find descr */ if (*type == 'H') { cha = 'A'; chz = 'Z'; cdif = 'a' - 'A'; /* help descriptors are lower case */ } else { cha = 'a'; chz = 'z'; cdif = 'A' - 'a'; } for (nr=0; nr<15; nr++) { /* fill realdescr with descr. name */ if (descr[nr] == '\0') /* and convert to upper case */ { for (mm=nr; mm<15; mm++) realdescr[mm] = ' '; break; } else { realdescr[nr] = descr[nr]; if ((realdescr[nr] >= cha) && (realdescr[nr] <= chz)) realdescr[nr] += cdif; } } *noelem = 0; /* init to 0 always... */ /* init variables for search */ init_loop: ext = 1; /* extension counter */ diroff = 0; /* offset within directory */ /* get one directory extension after the other... */ search_loop: dirfirst = diroff + 1; dirlen = dirused - diroff; if (fcbp->DIREXT < dirlen) dirlen = fcbp->DIREXT; /* read max. 1500 chars. at one go... */ found = 0; /* read descriptor 'DIRECTORY.MIDAS' which holds the descr. directory */ nonul = -1; MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nonul); /* find descriptor name in directory */ compare: cpntrb = dscdir + found; for (nr=found; nrDIRENTRY) { /* always take chunks of 30 chars. */ if (strncmp(cpntrb,realdescr,15) == 0) { CGN_COPYALL(dscpntr,cpntrb,fcbp->DIRENTRY); found = nr; /* save offset within directory */ goto descr_found; } cpntrb += fcbp->DIRENTRY; } /* we need another segment (next extension) of descr. directory */ if (ext == totext) /* descr. does not exist... */ { old_ext = ext; old_diroff = diroff; /* maybe used in descr. adding */ return (ERR_DSCNPR); } else { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; goto search_loop; /* and loop more... */ } /* ...... FIND - find descriptor (that's the default) ...... */ descr_found: if (*type != DSC_PNTR->TYPE) { n = type_ok(*type,DSC_PNTR->TYPE); if (n == 0) { found += fcbp->DIRENTRY; /* point to next descr. */ goto compare; } else if (n < 0) return (ERR_DSCBAD); *type = DSC_PNTR->TYPE; } *bytelem = (int) DSC_PNTR->BYTELEM; if ((found == 0) && (ext == 1)) /* descr. directory may be long */ *noelem = dirused; else *noelem = (int) DSC_PNTR->NOELEM; *unit = DSC_PNTR->UNIT; *block = DSC_PNTR->START; /* get starting block */ *indx = (int)DSC_PNTR->INDEX - 1; /* get starting index ( - 1 !) in starting block */ /* save interesting data - maybe we can use it on next call again... */ old_found = found; old_ext = ext; old_diroff = diroff; (void)strncpy(old_descr,realdescr,15); found += fcbp->DIRENTRY; return status; /* ...... DELETE - delete descr entry in directory ...... */ delete_descr: { char *workspace; if (strncmp(realdescr,"DIRECTORY.MIDAS",15) == 0) { status = ERR_INPINV; /* directory may not be deleted... */ goto end_of_it; /* return via error check point */ } ext_len = fcbp->DIREXT; workspace = malloc((unsigned int) ext_len); /* allocate workspace */ oscfill(workspace,ext_len,'\0'); found = old_found; CGN_COPYALL(workspace,dscdir,found); ios = found + fcbp->DIRENTRY; n = ext_len - ios; CGN_COPYALL(&workspace[found],&dscdir[ios],n); ios = fcbp->DIREXT - fcbp->DIRENTRY; /* point to last entry */ ext = old_ext; dirfirst = old_diroff + 1; while (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ mm = dirfirst + fcbp->DIREXT; nonul = -1; MID_RDSCRC(chanl,fcbp->PTRLDB,0,mm,ext_len,dscdir,&nonul); n = ext_len - fcbp->DIRENTRY; CGN_COPYALL(&workspace[n],dscdir,fcbp->DIRENTRY); /* copy over first entry of next extension */ (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,workspace,0,dirfirst,ext_len); CGN_COPYALL(workspace,&dscdir[fcbp->DIRENTRY],ios); dirfirst = mm; } /* and process last extension */ (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,workspace,0,dirfirst,ext_len); dirused -= fcbp->DIRENTRY; /* decrease actual size */ dscupda = 1; free(workspace); goto end_of_it; } /* ...... ADD - add descr entry type, bytelem, noelem are input parms ...... */ /* last extension of directory already in - add new entry in the end */ add_descr: diroff = old_diroff; if (dirused < dirsize) { found = dirused - diroff + 1; dirused += fcbp->DIRENTRY; /* update directory length in use */ dscupda = 1; /* show that we modified the stuff */ goto add_3; } /* descr. directory already filled up, so extend it in the FCB */ dirsize += fcbp->DIREXT; dscupda = 1; /* show that we modified the stuff */ /* link new extension for descr. directory */ myblock = fcbp->PTRLDB; myindx = 0; iret = 1; /* set return pointer */ goto work_b; /* and do it ... */ add_1: mm1 = fcbp->DIREXT; /* length for addition in the end */ mm2 = 1; /* now reserve space for extension of descr directory */ DSC_PNTR->TYPE = 'C'; /* type of descr. directory */ goto work_a; /* do it there... */ add_2: diroff = dirused; /* start at first free entry in descr. directory */ dirused += fcbp->DIRENTRY; /* already increase in_use_length */ dscupda = 1; found = 1; /* finally enter new entry in directory */ add_3: (void)strncpy(DSC_PNTR->NAME,realdescr,15); DSC_PNTR->TYPE = *type; DSC_PNTR->BYTELEM = (short int) *bytelem; DSC_PNTR->NOELEM = (unsigned short int) *noelem; /* s.int => unsigned s.i. */ DSC_PNTR->UNIT = *unit; mm1 = *noelem; /* keep number of elements */ mm2 = *bytelem; DSC_PNTR->START = fcbp->ENDLDB[0]; DSC_PNTR->INDEX = (short int) fcbp->ENDLDB[1]; /* write updated directory back */ (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr,0,diroff+found,fcbp->DIRENTRY); *block = DSC_PNTR->START; /* for the calling program... */ *indx = DSC_PNTR->INDEX - 1; /* now reserve space for descr itself */ iret = 2; goto work_a; /* after that directly to end_of_it ... */ /* ...... EXTEND - extend descr. entry type, noelem are input parms ...... */ extend_descr: found = old_found; diroff = old_diroff; DSC_PNTR->UNIT = *unit; /* update unit */ lastlen = DSC_PNTR->NOELEM; /* save old length */ myblock = *block; /* keep starting LDB */ myindx = *indx; /* and index out of updates */ /* update directory entry for descr. */ DSC_PNTR->NOELEM = (unsigned short int) *noelem; /* s.int => unsigned s.i. */ (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr, 0,diroff+found+1,fcbp->DIRENTRY); /* link new extension for existing descr */ iret = 2; /* set return pointer */ goto work_b; /* and do it... */ extend_1: mm1 = *noelem - lastlen; /* length for addition in the end */ mm2 = (int) DSC_PNTR->BYTELEM; goto work_a; /* now add space at the end */ /* ...... that's it folks... ...... */ end_of_it: if (dscupda == 1) { if (fcbp->DSCFLAG == 'N') /* new descriptor stuff */ { fcbp->DFILLED = dirused; fcbp->DSIZE = dirsize; fcbp->DIRUSE = (short int) dirused; /* so it works with files of 90MAY */ fcbp->DIRNOELEM = (short int) dirsize; } else { fcbp->DIRUSE = (short int) dirused; fcbp->DIRNOELEM = (short int) dirsize; } } old_descr[0] = '!'; if (status != ERR_NORMAL) MID_ERROR("MIDAS","MID_DSCDIR:",status,0); return status; /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ working section for reserving space for a descr ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ work_a: ext_len = LDB_NDSCRW - 1; /* index will move from 0 on... */ ios = cacheLDB(1,chanl,fcbp->ENDLDB[0],&ldbp); /* read last used LDB */ myindx = fcbp->ENDLDB[1] - 1; /* remember that arrays begin with 0 */ /* determine no. of elements + length in 4-byte words */ if (DSC_PNTR->TYPE == 'I') long_len = mm1; else if (DSC_PNTR->TYPE == 'R') long_len = mm1; else if (DSC_PNTR->TYPE == 'D') { n = DD_SIZE / II_SIZE; /* no. of integers in a double */ mm1 *= n; /* double prec. looks internally as int... */ long_len = mm1; } else /* for type C + H */ { mm1 *= mm2; long_len = ( mm1 + (II_SIZE-1)) / II_SIZE ; } ldbp->LDBWORDS.IWORD[myindx] = mm1; /* store 1. header lword */ if (myindx == ext_len) /* test, if 2. header lword still in same LDB ... */ { MID_CRELDB(entrx,ldbp); ldbp->LDBWORDS.IWORD[0] = -1; /* currently no extension... */ ldbp->LDBWORDS.IWORD[1] = 0; /* index = 0 */ myindx = 1; } else { myindx ++; ldbp->LDBWORDS.IWORD[myindx] = -1; /* currently no extension... */ if (myindx == ext_len) /* see, if 2. header lword in same LDB */ { MID_CRELDB(entrx,ldbp); myindx = 0; } else myindx ++; ldbp->LDBWORDS.IWORD[myindx] = 0; /* index = 0 */ } myindx += (long_len + 1) ; while (myindx > ext_len) /* we need more LDBs */ { MID_CRELDB(entrx,ldbp); /* get new LDB + link it in */ myindx -= LDB_NDSCRW; } /* make sure this also goes to disk */ ios = cacheLDB(2,chanl,ldbp->BLKNUM,&ldbp); /* and update FCB */ fcbp->ENDLDB[0] = ldbp->BLKNUM; fcbp->ENDLDB[1] = myindx + 1; /* FCB.ENDLDB counts from 1 on ... */ if (iret == 1) goto add_2; else goto end_of_it; /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ working section for extending + linking descriptors... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ work_b: ext_len = LDB_NDSCRW - 1; /* index will move from 0 on... */ ios = cacheLDB(1,chanl,myblock,&ldbp); /* read start LDB of descr */ while (1) { mm = 0; MID_RDLDB(chanl,ldbp,myindx,1,&idummy,&rdummy,cdummy,1,&mm,extens); /* get pointers only */ if (extens[0] != -1) { myblock = extens[0]; myindx = extens[1] - 1; /* on disk file FORTRAN indexing ... */ if (ldbp->BLKNUM != myblock) ios = cacheLDB(1,chanl,myblock,&ldbp); } else { if (ldbp->BLKNUM != myblock) ios = cacheLDB(1,chanl,myblock,&ldbp); break; /* already get out of loop... */ } } ldbp->LDBWORDS.IWORD[myindx] = mm; if (myindx == ext_len) /* test, if 2. header lword still in same LDB ... */ { MID_CRELDB(entrx,ldbp); ldbp->LDBWORDS.IWORD[0] = fcbp->ENDLDB[0]; /* store 2. headr word */ ldbp->LDBWORDS.IWORD[1] = fcbp->ENDLDB[1]; /* store 3. headr word */ } else { myindx ++; ldbp->LDBWORDS.IWORD[myindx] = fcbp->ENDLDB[0]; /* store 2. header word */ if (myindx == ext_len) /* see, if 3. header word still in same LDB */ { MID_CRELDB(entrx,ldbp); myindx = 0; } else myindx ++; ldbp->LDBWORDS.IWORD[myindx] = fcbp->ENDLDB[1]; /* store 3. header word */ } ios = cacheLDB(2,chanl,ldbp->BLKNUM,&ldbp); if (iret == 1) goto add_1; else goto extend_1; /* go back to where we came from... */ } /* */ int oldSCDCOP(from,to,mask,dsc) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Copy descriptors from one frame to another .ALGORITHM Depending on 'mask' the relevant descriptors are read from the source frame + written to the destination frame. .REMARKS mask for copying: = 1 , copy all descriptors = 2 , copy only standard desc. = 3 , copy all but standard descriptors = 4 , copy descriptor specified by DSClist = 5 , copy all but extended list of standard descriptors .RETURNS return status ( 0 = o.k. ) --------------------------------------------------*/ int from; /* IN: no. of source frame */ int to; /* IN: no. of destination frame */ int mask; /* IN: copy_mask */ char *dsc; /* IN: name of descr. to copy (if mask = 4) */ { int iav, lk, nval, nfr, no_elem, byt_elem; int total, nin, dunit, status, mm, e_c, e_l; int nullo; int *ibuf; static int def_total[5] = {10000,6,10000,1,10000}; static int mapdat = -1; float *rbuf; double *dbuf; char *cbuf, dtype[4], worky[16], filty, dscbuf[40], descr[16]; static char stand0[16] = "NAXIS "; static char stand1[16] = "NPIX "; static char stand2[16] = "START "; static char stand3[16] = "STEP "; static char stand4[16] = "CUNIT "; static char stand5[16] = "IDENT "; static char stand6[16] = "LHCUTS "; static char stand7[16] = "DISPLAY_DATA "; static char stand8[16] = "HIST_BINS "; static char stand9[16] = "HISTOGRAM "; static char stand10[16] = "STATISTIC "; static char stand11[16] = "WINDOW_TO "; static char stand12[16] = "WINDOW_FROM "; static char *stand[13] = {stand0,stand1,stand2,stand3,stand4,stand5,stand6, stand7,stand8,stand9,stand10,stand11,stand12}; static char tstand0[16] = "TBLENGTH "; static char tstand1[16] = "TBLOFFST "; static char tstand2[16] = "TBLCONTR "; static char tstand3[16] = "TSELTABL "; static char *tstand[4] = {tstand0,tstand1,tstand2,tstand3}; struct FCT_STRUCT *fctpntri; fctpntri = FCT.ENTRIES + from; if (mapdat < 0) /* allocate working buffer */ { /* for descr. data */ datpntr = malloc((unsigned int)DATA_CSIZE); mapdat = 1; } /* disable error abort */ e_c = ERRO_CONT; e_l = ERRO_LOG; ERRO_CONT = 1; ERRO_LOG = 0; if ( (mask < 1 ) || (mask > 5) ) { status = ERR_INPINV; goto end_of_it; } status = ERR_NORMAL; cbuf = datpntr; ibuf = (int *) datpntr; rbuf = (float *) datpntr; dbuf = (double *) datpntr; /* determine total no. of descriptors to be copied from `mask' */ if (mask == 4) /* pad blanks in the end of given descr. */ { mm = (int) strlen(dsc); if (mm > 15) mm = 15; /* old descr. length = 15 */ CGN_FILL(worky,' ',15); (void) strncpy(worky,dsc,mm); worky[15] = '\0'; /* just for completeness... */ } total = def_total[mask-1]; filty = fctpntri->CATALOG[0]; /* get file type */ /* main loop - read descriptor name + copy, if name o.k. */ for (lk=1; lk<32767; lk++) { if (total < 1) break; /* all descriptors copied... */ /* get NAME,TYPE + SIZE back */ status = SCDINF(from,lk,5,dscbuf,39,ibuf); if ( (status != ERR_NORMAL) || (dscbuf[0] == ' ') ) break; /* finished or problem with SCDINF */ mm = CGN_INDEXC(dscbuf,','); dscbuf[mm] = '\0'; (void) strcpy(descr,dscbuf); dtype[0] = dscbuf[mm+1]; no_elem = *ibuf; byt_elem = *(ibuf+1); /* if 'mask' = 4, compare descriptor with 'dsc' */ if (mask == 4) { if (strncmp(worky,descr,15) != 0) goto sect_1000; total = 0; } /* if mask = 3, compare descriptor with list of standard descriptors */ else if (mask == 3) { if (filty == 'T') { for (nin=0; nin<4; nin++) { if ((strncmp(descr,tstand[nin],15) == 0) || (strncmp(descr,"TLABL",5) == 0)) goto sect_1000; } } else { for (nin=0; nin<7; nin++) { if (strncmp(descr,stand[nin],15) == 0) goto sect_1000; } } /* non-standard descriptor found */ } /* if mask = 5, compare descriptor with extended list of stand. descr. */ else if (mask == 5) { for (nin=0; nin<13; nin++) { if (strncmp(descr,stand[nin],15) == 0) goto sect_1000; } /* non-standard descriptor found */ } /* if mask = 2, compare descriptor with list of standard descriptors */ else if (mask == 2) { if (filty == 'T') { for (nin=0; nin<4; nin++) { if (strncmp(descr,tstand[nin],15) == 0) { total --; goto sect_200; } } } else { for (nin=0; nin<7; nin++) { if (strncmp(descr,stand[nin],15) == 0) { total --; goto sect_200; } } } goto sect_1000; } /* mask = 1, all source descriptors are copied */ sect_200: nfr = 1; sect_222: nval = no_elem - nfr + 1; nullo = -1; if (dtype[0] == 'I') /* integer descriptor */ { if (nval > maxdim[0]) nval = maxdim[0]; status = SCDRDI(from,descr,nfr,nval,&iav,ibuf,&dunit,&nullo); if (status == ERR_NORMAL) status = SCDWRI(to,descr,ibuf,nfr,nval,&dunit); } else if (dtype[0] == 'R') /* real descriptor */ { if (nval > maxdim[1]) nval = maxdim[1]; status = SCDRDR(from,descr,nfr,nval,&iav,rbuf,&dunit,&nullo); if (status == ERR_NORMAL) status = SCDWRR(to,descr,rbuf,nfr,nval,&dunit); } else if (dtype[0] == 'C') /* character descriptor */ { if (byt_elem > 1) { mm = maxdim[2] / byt_elem; if (mm < 0) { (void) sprintf (cbuf,"bytes_per_element = %d > 4096, descr %s not copied!", byt_elem,descr); SCTPUT(cbuf); goto help_descr; } } else mm = maxdim[2]; if (nval > mm) nval = mm; status = SCDRDC(from,descr, byt_elem,nfr,nval,&iav,cbuf,&dunit,&nullo); if (status == ERR_NORMAL) { cbuf[nval*byt_elem] = '\0'; status = SCDWRC(to,descr,byt_elem,cbuf,nfr,nval,&dunit); } } else /* double precision descriptor */ { if (nval > maxdim[3]) nval = maxdim[3]; status = SCDRDD(from,descr,nfr,nval,&iav,dbuf,&dunit,&nullo); if (status == ERR_NORMAL) status = SCDWRD(to,descr,dbuf,nfr,nval,&dunit); } if (status != ERR_NORMAL) goto end_of_it; /* test, if descriptor copied completely */ if ((nval+nfr) <= no_elem) { nfr += nval; goto sect_222; } help_descr: nval = maxdim[2]; status = SCDRDH(from,descr,1,nval,&iav,cbuf,&mm); if (status != ERR_NORMAL) goto end_of_it; if (mm > 0) /* Yes. So copy also the help */ { cbuf[iav] = '\0'; status = SCDWRH(to,descr,cbuf,1,iav); if (status != ERR_NORMAL) goto end_of_it; } sect_1000: ; } /* end of main loop */ end_of_it: ERRO_CONT = e_c; ERRO_LOG = e_l; /* reset error flags */ if (status != ERR_NORMAL) MID_E2(8,from,descr,status,1); return status; }