~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to libsrc/st/middsc.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
3
 
 
4
  This program is free software; you can redistribute it and/or 
 
5
  modify it under the terms of the GNU General Public License as 
 
6
  published by the Free Software Foundation; either version 2 of 
 
7
  the License, or (at your option) any later version.
 
8
 
 
9
  This program is distributed in the hope that it will be useful,
 
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
  GNU General Public License for more details.
 
13
 
 
14
  You should have received a copy of the GNU General Public 
 
15
  License along with this program; if not, write to the Free 
 
16
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
 
17
  MA 02139, USA.
 
18
 
 
19
  Correspondence concerning ESO-MIDAS should be addressed as follows:
 
20
        Internet e-mail: midas@eso.org
 
21
        Postal address: European Southern Observatory
 
22
                        Data Management Division 
 
23
                        Karl-Schwarzschild-Strasse 2
 
24
                        D 85748 Garching bei Muenchen 
 
25
                        GERMANY
 
26
===========================================================================*/
 
27
 
 
28
/*+++++++++++++++++++++ Module MIDDSC +++++++++++++++++++++++++++++++++++++++
 
29
.LANGUAGE   C
 
30
.IDENTIFICATION  MIDDSC.C
 
31
.AUTHOR   Klaus Banse           ESO - Garching
 
32
.COMMENTS
 
33
holds  MID_DRESET, type_ok, MID_DSCDIR, MID_YDSCDIR
 
34
.KEYWORDS MIDAS Descriptors
 
35
.ENVIRONMENT VMS and UNIX
 
36
.VERSION  [1.30]  861110: creation from FORTRAN version
 
37
 
 
38
 090326         last modif
 
39
------------------------------------------------------------------------*/
 
40
 
 
41
#include <stdlib.h>
 
42
#include <stdio.h>
 
43
#include <string.h>
 
44
 
 
45
#include <fileexts.h>
 
46
 
 
47
 
 
48
#define DSCDIREXTENS 30
 
49
 
 
50
 
 
51
static int   nonul = -1;
 
52
static int   old_yimno = -1;
 
53
static int   cdif = 'A' - 'a';
 
54
 
 
55
/*
 
56
 
 
57
*/
 
58
 
 
59
#ifdef __STDC__
 
60
void MID_DRESET(void)
 
61
#else
 
62
void MID_DRESET()
 
63
#endif
 
64
 
 
65
{
 
66
old_yimno = -1;
 
67
}
 
68
 
 
69
 
 
70
 
 
71
 
 
72
 
 
73
 
 
74
#ifdef __STDC__
 
75
int type_ok(char intyp , char outtyp)
 
76
#else
 
77
int type_ok(intyp,outtyp)
 
78
char  intyp, outtyp;
 
79
#endif
 
80
/*  return  0, if one of the types is 'H' (help)
 
81
    return -1, if bad type combination
 
82
    return  1, if good type combination (i.e. R/D)  */
 
83
{
 
84
if ((intyp == 'H') || (outtyp == 'H'))          /* ignore help descr. */
 
85
   return (0);
 
86
else if (intyp == ' ')                  /* we're searching for any descr. */
 
87
   return (1);
 
88
else
 
89
   return (-1);
 
90
}
 
91
/*
 
92
 
 
93
*/
 
94
 
 
95
#ifdef __STDC__
 
96
int DSCNAM_COPY(char *out, char *in)
 
97
#else
 
98
int DSCNAM_COPY(out,in)
 
99
char  *out, *in;
 
100
#endif
 
101
 
 
102
{
 
103
register int  nr;
 
104
 
 
105
register char cr, compa;
 
106
 
 
107
 
 
108
compa = cdif;                   /* avoid static (global) variable inside loop */
 
109
 
 
110
for (nr=0; nr<49; nr++)                 /* build up uppercase name */
 
111
   {
 
112
   cr = *in++;
 
113
   if (cr == '\0')
 
114
      {
 
115
      *out = '\0';
 
116
      return nr;                        /* return length of descr. */
 
117
      }
 
118
 
 
119
   if ((cr >= 'a') && (cr <= 'z')) 
 
120
      *out++ = cr + compa;
 
121
   else
 
122
      {
 
123
      if (cr == ' ')
 
124
         {
 
125
         *out = '\0';
 
126
         return nr;
 
127
         }
 
128
      *out++ = cr;
 
129
      }
 
130
   }
 
131
 
 
132
*out = '\0';
 
133
return 49;
 
134
}
 
135
/*
 
136
 
 
137
*/
 
138
 
 
139
#ifdef __STDC__
 
140
static void procHelp(char *myhelp)
 
141
#else
 
142
 
 
143
static void procHelp(myhelp)
 
144
char  *myhelp;
 
145
#endif
 
146
 
 
147
/*++++++++++++++++++++++++++++++++++++++++++++++++++
 
148
 
 
149
 process the help string of a descriptor
 
150
 
 
151
 010910         last modif
 
152
 
 
153
 --------------------------------------------------*/
 
154
 
 
155
 
 
156
{
 
157
int  n, mm;
 
158
 
 
159
char  *mypntr;
 
160
 
 
161
 
 
162
 
 
163
 
 
164
n = (int) strlen(myhelp);
 
165
if (n > 0)
 
166
   {
 
167
   mypntr = YDSC_PNTR->NAMESTR + YDSC_PNTR->NAMELEN + 1;
 
168
 
 
169
   mm = 76 - YDSC_PNTR->NAMELEN;        /* 78 - 2, because two '\0's */
 
170
   if (n > mm)
 
171
      {
 
172
      YDSC_PNTR->HELPLEN = (short int) mm;
 
173
      (void) memcpy(mypntr,myhelp,(size_t)mm);
 
174
      YDSC_PNTR->NAMESTR[77] = '\0';
 
175
      }
 
176
   else
 
177
      {
 
178
      YDSC_PNTR->HELPLEN = (short int) n;
 
179
      (void) memcpy(mypntr,myhelp,(size_t)(n+1));
 
180
      }
 
181
   }
 
182
else
 
183
   YDSC_PNTR->HELPLEN = (short int) 0;
 
184
 
 
185
}
 
186
/*
 
187
 
 
188
*/
 
189
 
 
190
#ifdef __STDC__
 
191
int MID_YDSCDIR(int entrx, char action, char *descr, char *type,
 
192
                int *bytelem, int *noelem, int *unit, 
 
193
                int *block, int *indx, char *help)
 
194
#else
 
195
int MID_YDSCDIR(entrx,action,descr,type,bytelem,noelem,unit,block,indx,help)
 
196
/*++++++++++++++++++++++++++++++++++++++++++++++++++
 
197
.PURPOSE
 
198
  interface to the descriptor directory
 
199
.ALGORITHM
 
200
  A character descriptor (name = DESCRIPTOR.DIRECTORY) is stored from 
 
201
  LDB #1 on,
 
202
  each descriptor is entered in this directory as follows:
 
203
  namestr (78 chars): name (with '\0') followed by help text (with '\0')
 
204
  descr. type (1 char), freespace (1 char);
 
205
  length of name (short int); 
 
206
  length of help text (short int); 
 
207
  unit of descr (short int) - not used yet;
 
208
  no. of bytes per descr. element (short int); 
 
209
  no. of elements of descr. (int);
 
210
  start block (int) + start index (int) withing the LDBs
 
211
 
 
212
  the exact structural layout is in $MID_INCLUDE/ydscext.h
 
213
 
 
214
  the functions provided are:
 
215
  F(ind), A(dd), D(elete) and E(xtend) a descriptor within the directory
 
216
  as well as the relevant LDB space (for Add + Extend only)
 
217
 
 
218
  It is assumed, that the FCB of the frame has already been read in!
 
219
.RETURNS
 
220
  stat: I*4             return status
 
221
 
 
222
 030102         last modif
 
223
 
 
224
--------------------------------------------------*/
 
225
 
 
226
int   entrx;    /* IN : entry of frame in FCT   */
 
227
char  action;   /* IN : action to perform :           
 
228
                        F find, D delete, A add, E extend */
 
229
char  *descr;   /* IN : descriptor name */
 
230
char  *type;    /* IO : type of descriptor: I, R, C or D */
 
231
int   *bytelem; /* IO : no. of bytes per descr. element */
 
232
int   *noelem;  /* IO : no. of descr. elements */
 
233
int   *unit;    /* IO : unit pointer  */
 
234
int   *block;   /* OUT: starting block of descriptor on output*/
 
235
int   *indx;    /* OUT: starting index of descr. */
 
236
char  *help;    /* IO : help text name */
 
237
#endif
 
238
 
 
239
{
 
240
static char     old_descr[52] = " ", next_descr[52] = " ";
 
241
static char     dscdir[6000];
 
242
 
 
243
char   dsctype, *cpntra, *cpntrb, *dscpntr, tmp[100];
 
244
register char  cr;
 
245
 
 
246
int   ext, ext_len, iret;
 
247
int   found, mm1, mm2, long_len, lastlen=0;
 
248
int   dirfirst, dirused, diralloc, dscupda, totext;
 
249
int   status, ios, n, mm, chanl, extens[2];
 
250
int   foundflag, myblock, myindx;
 
251
 
 
252
static int   xoff;
 
253
static int   old_diroff, old_found, old_ext;
 
254
static int   next_diroff, next_found, next_ext;
 
255
register int   direntry, dirext, dirlen, diroff;
 
256
register int   nr, mr;
 
257
 
 
258
struct FCT_STRUCT  *fctpntr;
 
259
 
 
260
struct FCB_STRUCT  *fcbp;
 
261
 
 
262
struct LDB_STRUCT    *ldbp;
 
263
 
 
264
void LDBinfo();
 
265
 
 
266
 
 
267
 
 
268
        
 
269
status = ERR_NORMAL;
 
270
 
 
271
fctpntr = FCT.ENTRIES + entrx;
 
272
fcbp = fctpntr->FZP;
 
273
chanl = fctpntr->IOCHAN;
 
274
 
 
275
dscupda = 0;
 
276
dirused = fcbp->DFILLED;
 
277
dirlen = dirused;
 
278
diralloc = fcbp->DSIZE;
 
279
direntry = fcbp->DIRENTRY;
 
280
dirext = (int) fcbp->DIREXT;
 
281
 
 
282
myindx = -9999;
 
283
 
 
284
totext = diralloc/dirext;               /* no. of extens. for dsc-directory */
 
285
dscpntr = (char *) &YDSCDIR_ENTRY;              /* point to descr-dir entry */
 
286
 
 
287
 
 
288
                 /*  branch on action  */
 
289
 
 
290
foundflag = 0;
 
291
if (action == 'F') 
 
292
   {                                    /* FIND - find descriptor */
 
293
   if (entrx == old_yimno)                      /* old_yimno = entrx ... */
 
294
      {
 
295
      if (strcmp(old_descr,descr) == 0)
 
296
         {
 
297
         found = old_found;
 
298
         ext = old_ext;
 
299
         diroff = old_diroff;
 
300
         foundflag = 1;
 
301
         goto descr_found;                      /* use old extension */
 
302
         }
 
303
      else if (strcmp(next_descr,descr) == 0)
 
304
         {
 
305
         found = next_found;
 
306
         ext = next_ext;
 
307
         diroff = next_diroff;
 
308
         goto search_loop;
 
309
         }
 
310
      }
 
311
 
 
312
   /* init variables for search */
 
313
 
 
314
   ext = 1;                                     /* extension counter */
 
315
   diroff = 0;                                  /* offset within directory */
 
316
   old_yimno = -1;                              /* in case, search fails... */
 
317
   next_found = 0;
 
318
 
 
319
        
 
320
   /*  get one directory extension after the other...  */
 
321
 
 
322
  search_loop:
 
323
   dirfirst = diroff + 1;
 
324
   dirlen = dirused - diroff;
 
325
   if (dirext < dirlen)
 
326
      dirlen = dirext;          /* read max. 2500/6000 ch. in one go... */
 
327
 
 
328
        
 
329
   /*  read descr `DESCRIPTOR.DIRECTORY' which holds the descr. directory */
 
330
 
 
331
   nonul = -1;
 
332
   (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nonul);
 
333
        
 
334
 
 
335
   /*  find descriptor name in directory  */
 
336
   /*  this loop has to be fast, so emulate as if assember... */ 
 
337
 
 
338
   cpntrb = dscdir;
 
339
   nr = 0;
 
340
 
 
341
  outer:
 
342
   cpntra = cpntrb;
 
343
   mr = 0;
 
344
 
 
345
  inner: 
 
346
   cr = descr[mr];
 
347
   if (cr != *cpntra++) goto move_on;
 
348
   if (cr == '\0')
 
349
      {
 
350
      found = nr;                       /* save offset within directory */
 
351
      goto descr_found;
 
352
      }
 
353
   mr ++;
 
354
   goto inner;
 
355
 
 
356
  move_on:
 
357
   nr += direntry;
 
358
   if (nr < dirlen) 
 
359
      {
 
360
      cpntrb += direntry;
 
361
      goto outer;
 
362
      }
 
363
        
 
364
        
 
365
   /*  we need another segment (next extension) of descr. directory  */
 
366
 
 
367
   mm = diroff + dirext;                /* move offset up */
 
368
   if (mm < dirused)
 
369
      {
 
370
      ext ++;                   /* prepare reading of next dir. segment */
 
371
      diroff = mm;
 
372
      goto search_loop;                 /* and loop more... */
 
373
      }
 
374
       
 
375
   old_ext = ext;               /* end of filled directory reached */
 
376
   old_diroff = diroff;         /* may be used in descr. adding */
 
377
   return (ERR_DSCNPR);
 
378
        
 
379
 
 
380
  descr_found:
 
381
   cpntrb = dscdir + found;
 
382
   (void) memcpy(dscpntr,cpntrb,(size_t) direntry); /* -> YDSC entry */
 
383
 
 
384
   if (*type == ' ') 
 
385
      *type = YDSC_PNTR->TYPE;
 
386
 
 
387
   else if (*type == 'H')                       /* modify help string */
 
388
      {
 
389
      procHelp(help);                           /* copy help string */
 
390
      (void) 
 
391
      MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr,0,diroff+found+1,direntry);
 
392
      goto save_info;
 
393
      }
 
394
 
 
395
   else if (*type != YDSC_PNTR->TYPE)
 
396
      {
 
397
      *type = YDSC_PNTR->TYPE;          /* pass back type */
 
398
       status = ERR_DSCTYP;
 
399
      }
 
400
 
 
401
 
 
402
   if (YDSC_PNTR->HELPLEN > 0)          /* also return help string */
 
403
      {
 
404
      cpntra = YDSC_PNTR->NAMESTR+YDSC_PNTR->NAMELEN+1;
 
405
      (void) memcpy(help,cpntra,(size_t) (YDSC_PNTR->HELPLEN+1));
 
406
      }
 
407
   else
 
408
      *help = '\0';                     /* no help string */
 
409
 
 
410
 
 
411
   *bytelem = (int) YDSC_PNTR->BYTELEM;
 
412
   if ((found == 0) && (ext == 1))         /* descr. directory is different */
 
413
      *noelem = dirused;
 
414
   else
 
415
      *noelem = YDSC_PNTR->NOELEM;
 
416
   *block = YDSC_PNTR->START;           /* get starting block */
 
417
   *indx = YDSC_PNTR->INDEX - 1;        /* get starting index-1 in stablock */
 
418
   *unit = (int) YDSC_PNTR->UNIT;
 
419
 
 
420
        
 
421
   /*  save interesting data - maybe we can use it on next call again... */
 
422
 
 
423
  save_info:
 
424
   if (foundflag != 1) 
 
425
      {
 
426
      old_yimno = entrx;
 
427
      old_found = found;
 
428
      old_ext = ext;
 
429
      old_diroff = diroff;
 
430
      (void)memcpy(old_descr,descr,(size_t)49);
 
431
 
 
432
      next_found = found + direntry;
 
433
      if (next_found < dirlen)
 
434
         {
 
435
         cpntra = cpntrb + direntry;
 
436
         next_ext = ext;
 
437
         next_diroff = diroff;
 
438
         (void)memcpy(next_descr,cpntra,(size_t)49);
 
439
         }
 
440
      else                              /* next_descr is in next extension */
 
441
         {
 
442
         if (ext == totext)
 
443
            next_descr[0] = '\0';       /* no next descr. */
 
444
         else
 
445
            {
 
446
            char  kdsc[52];
 
447
 
 
448
            next_found = 0;             /* next extension */
 
449
            next_ext = ext + 1;
 
450
            next_diroff = diroff + dirext;
 
451
            nonul = -1;
 
452
            (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,next_diroff+1,50,
 
453
                           kdsc,&nonul);
 
454
            (void)memcpy(next_descr,kdsc,(size_t)49);
 
455
            }
 
456
         }
 
457
      }
 
458
   return status;
 
459
   }
 
460
 
 
461
 
 
462
else if (action == 'A')         /* ADD - add descr entry */
 
463
   goto add_descr;
 
464
 
 
465
 
 
466
else if (action == 'a')
 
467
   {                    /* ADD - add descr entry, but no 'F' before...  */
 
468
   ios = cacheLDB(1,chanl,fcbp->PTRLDB,&ldbp);  /* get start LDB in */
 
469
 
 
470
   old_ext = dirused/dirext;            /* no. of last dir-ext used */
 
471
   old_diroff = old_ext * dirext;
 
472
   dirlen = dirused - old_diroff;               /* space still available */
 
473
   if (dirlen > 0)
 
474
      {
 
475
      nonul = -1;
 
476
     (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,old_diroff+1,
 
477
                       dirlen,dscdir,&nonul);
 
478
      }
 
479
   else if (dirlen < 0)
 
480
      return ERR_DSCBAD;
 
481
 
 
482
   /*  last extension of directory already in - add new entry in the end  */
 
483
 
 
484
  add_descr:
 
485
   if (*type == 'H')
 
486
      {
 
487
      procHelp(help);                           /* copy help string */
 
488
      (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr,0,xoff,direntry);
 
489
      return ERR_NORMAL;
 
490
      }
 
491
 
 
492
   diroff = old_diroff;
 
493
   dscupda = 1;                 /* show that we modified the stuff */
 
494
   ext_len = diralloc;
 
495
   while ((ext_len-dirused) >= dirext) ext_len -= dirext;
 
496
 
 
497
   if (dirused < ext_len)       /* descr. directory extension not full yet */
 
498
      {
 
499
      found = dirused - diroff;
 
500
      dirused += direntry;      /* update directory length in use */
 
501
      goto add_3;
 
502
      }
 
503
 
 
504
   /*  descr. directory filled up, so extend it in the FCB  */
 
505
 
 
506
   ext_len += dirext;
 
507
   myblock = fcbp->PTRLDB;      /* link new extension for descr. directory */
 
508
   myindx = 0;
 
509
   if (diralloc >= ext_len) goto add_2;
 
510
 
 
511
   diralloc = ext_len;
 
512
   iret = 1;                            /* set return pointer */
 
513
   goto work_b;                         /* and do it ...  */
 
514
 
 
515
  add_1:
 
516
   mm1 = dirext;                        /* length for addition in the end */
 
517
   mm2 = 1;
 
518
   dsctype = 'C';                               /* type of descr. directory */
 
519
   goto work_a;         
 
520
        
 
521
  add_2:
 
522
   diroff = dirused;      /* start at first free entry in descr. directory */
 
523
   dirused += direntry;         /* already increase in_use_length */
 
524
   found = 0;
 
525
        
 
526
   /*  finally enter new entry in directory  */
 
527
 
 
528
  add_3:
 
529
   YDSC_PNTR->TYPE = *type;
 
530
   YDSC_PNTR->NAMELEN = CGN_COPY(YDSC_PNTR->NAMESTR,descr);
 
531
   YDSC_PNTR->BYTELEM = (short int) *bytelem;
 
532
   YDSC_PNTR->NOELEM = *noelem;
 
533
   YDSC_PNTR->UNIT = (short int) *unit;
 
534
   mm1 = *noelem;                               /* keep number of elements */
 
535
   mm2 = *bytelem;
 
536
   YDSC_PNTR->START = fcbp->ENDLDB;
 
537
   YDSC_PNTR->INDEX = fcbp->ENDLDB_OFF;
 
538
 
 
539
   procHelp(help);                              /* copy help string */
 
540
        
 
541
   /*  write updated directory back + reserve space for descr itself  */
 
542
 
 
543
   xoff = diroff+found+1;
 
544
   (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr,0,xoff,direntry);
 
545
   *block = YDSC_PNTR->START;           /* for the calling program... */
 
546
   *indx = YDSC_PNTR->INDEX - 1;
 
547
 
 
548
   dsctype = YDSC_PNTR->TYPE;
 
549
 
 
550
   iret = 2;
 
551
   goto work_a;                 /* after that directly to end_of_it ... */
 
552
   }
 
553
 
 
554
 
 
555
else if (action == 'E')         /* EXTEND - extend descr. entry */
 
556
   {
 
557
   found = old_found;
 
558
   diroff = old_diroff;
 
559
   lastlen = YDSC_PNTR->NOELEM;                 /* save old length */
 
560
   myblock = *block;                            /* keep starting LDB */
 
561
   myindx = *indx;                              /* and index out of updates */
 
562
 
 
563
   YDSC_PNTR->NOELEM = *noelem;      /* update directory entry for descr. */
 
564
   (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr,0,
 
565
                     diroff+found+1,direntry);
 
566
        
 
567
   /*  link new extension for existing descr  */
 
568
 
 
569
   iret = 2;                            /* set return pointer -> "extend_1" */
 
570
   goto work_b;                         /* and do it...  */
 
571
        
 
572
  extend_1:
 
573
   mm1 = *noelem - lastlen;             /* length for addition in the end */
 
574
   mm2 = (int) YDSC_PNTR->BYTELEM;
 
575
   dsctype = YDSC_PNTR->TYPE;           /* now add space at the end */
 
576
   goto work_a;
 
577
   }
 
578
 
 
579
 
 
580
else if (action == 'D')         /* DELETE - delete descr entry in directory */
 
581
   {
 
582
   if (strcmp(descr,"DESCRIPTOR.DIRECTORY") == 0)
 
583
      status = ERR_INPINV;              /* directory cannot be deleted... */
 
584
        
 
585
   else
 
586
      {
 
587
      (void) memcpy(dscpntr,dscdir+old_found,(size_t) direntry);
 
588
      YDSC_PNTR->NAMESTR[0]= '\0';
 
589
      (void) MID_WDSCRC(chanl,fcbp->PTRLDB,0,dscpntr,
 
590
                        0,old_diroff+old_found+1,direntry);
 
591
      (void) memcpy(dscdir+old_found,dscpntr,(size_t) direntry);
 
592
 
 
593
      if (old_ext == totext)
 
594
         {                              /* we deleted in the last extension */
 
595
         diroff = old_diroff;           /* point already to last extension */
 
596
         dirfirst = diroff + 1;
 
597
         dirlen = dirused - diroff;     /* <= FCB.DIREXT because of `diroff' */
 
598
 
 
599
        pack_loop:
 
600
         mm1 = 0;
 
601
         found = 1;
 
602
         cpntrb = dscdir;
 
603
 
 
604
         while (found < dirlen)
 
605
            {           
 
606
            if (*cpntrb != '\0')        /* check for last filled blocks */
 
607
               mm1 = found;
 
608
 
 
609
            cpntrb += direntry;  found += direntry;
 
610
            }
 
611
 
 
612
         if (mm1 == 0)
 
613
            {                           /* empty extension! */
 
614
            dscupda = 1;
 
615
            dirused -= dirlen;
 
616
            dirfirst -= dirext;
 
617
            dirlen = dirext;
 
618
            nonul = -1;
 
619
            (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirext,
 
620
                              dscdir,&nonul);
 
621
            goto pack_loop;
 
622
            }
 
623
 
 
624
         cpntrb = dscdir + mm1 - 1;     /* point to last filled block */
 
625
         dirused = dirfirst + mm1 + direntry - 2;
 
626
         dscupda = 1;
 
627
         }
 
628
      }
 
629
   goto end_of_it;
 
630
   }
 
631
 
 
632
 
 
633
else if (action == 'H')         /* return help info of last descr. */
 
634
   {
 
635
   cpntrb = dscdir + old_found;
 
636
   (void) memcpy(dscpntr,cpntrb,(size_t) direntry);  /* -> YDSC entry */
 
637
   *noelem = YDSC_PNTR->HELPLEN;
 
638
   *block = YDSC_PNTR->NAMELEN;         /* length of preceding descr name */
 
639
   return ERR_NORMAL;
 
640
   }
 
641
 
 
642
 
 
643
/* as default we display the contents of the descriptor directory in
 
644
   a user friendly way (`action' = 'Z')  */
 
645
 
 
646
ext = 1;                                        /* extension counter */
 
647
diroff = 0;                                     /* offset within directory */
 
648
old_yimno = -1;                                 /* in case, search fails... */
 
649
mm1 = 0; mm2 = 0;
 
650
        
 
651
dir_search_loop:
 
652
dirfirst = diroff + 1;
 
653
dirlen = dirused - diroff;
 
654
if (dirext < dirlen) dirlen = dirext;
 
655
 
 
656
nonul = -1;
 
657
(void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nonul);
 
658
        
 
659
 
 
660
/*  loop through directory extension  */
 
661
 
 
662
(void) snprintf(tmp,(size_t) 80,"Descr_dir_extension %d:",ext);
 
663
SCTPUT(tmp);                            /* calling an SC routine is not nice */
 
664
SCTPUT("-----------------------");      /* but this is a debugging tool only */
 
665
 
 
666
cpntrb = dscdir;
 
667
nr = 0;
 
668
while (nr < dirlen)
 
669
   {                                    /* get stuff into structure */
 
670
   (void) memcpy(dscpntr,cpntrb,(size_t) direntry);
 
671
 
 
672
   if (*cpntrb == '\0')
 
673
      (void) snprintf(tmp,(size_t) 80,"Entry #%d: unused ...",mm1);
 
674
   else
 
675
      {
 
676
      (void) snprintf(tmp,(size_t) 80,
 
677
             "Entry #%d: Name = %s",mm1,YDSC_PNTR->NAMESTR);
 
678
      mm2 ++;
 
679
      }
 
680
   SCTPUT(tmp);
 
681
   (void) snprintf(tmp,(size_t) 80,
 
682
   "   Type = %c, No_elem = %d, Bytes_per_elem = %d, unit = %d",
 
683
   YDSC_PNTR->TYPE,YDSC_PNTR->NOELEM,YDSC_PNTR->BYTELEM,YDSC_PNTR->UNIT);
 
684
   SCTPUT(tmp);
 
685
   (void) snprintf(tmp,(size_t) 80,"   Start block, Index for data = %d, %d",
 
686
                  YDSC_PNTR->START,YDSC_PNTR->INDEX);
 
687
   SCTPUT(tmp);
 
688
   if (YDSC_PNTR->HELPLEN > 0)
 
689
      {
 
690
      cpntra = YDSC_PNTR->NAMESTR+YDSC_PNTR->NAMELEN+1;
 
691
      (void) snprintf(tmp,(size_t) 80,
 
692
             "   Help text: %s (%d chars)",cpntra,YDSC_PNTR->HELPLEN);
 
693
      SCTPUT(tmp);
 
694
      }
 
695
 
 
696
   mm1 ++;                              /* increment dir_entry counter */
 
697
   cpntrb += direntry;  nr += direntry;
 
698
   }
 
699
        
 
700
        
 
701
/*  check, if we need another segment (next extension) of descr_dir  */
 
702
 
 
703
if (ext == totext)
 
704
   {
 
705
   SCTPUT("Descr. directory:");
 
706
   (void) snprintf(tmp,(size_t) 80,
 
707
             "size = %d, in_use = %d (chars)",diralloc,dirused);
 
708
   SCTPUT(tmp);
 
709
   (void) snprintf(tmp,(size_t) 80,
 
710
             "no_entries = %d, no_descr = %d (incl. direc)",mm1,mm2);
 
711
   SCTPUT(tmp);
 
712
 
 
713
   *bytelem = dirused;
 
714
   *noelem = mm1;
 
715
   return (ERR_NORMAL);                 /* we're done */
 
716
   }
 
717
 
 
718
ext ++ ;                /* prepare reading of next directory segment */
 
719
diroff += dirext;
 
720
goto dir_search_loop;                   /* and loop more... */
 
721
 
 
722
 
 
723
 
 
724
 
 
725
 
 
726
 
 
727
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   
 
728
        
 
729
   working section for reserving space for a descr
 
730
        
 
731
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
 
732
        
 
733
work_a:
 
734
ext_len = LDB_NDSCRW1;                  /* index will move from 0 on... */
 
735
                                        /* read last used LDB */
 
736
ios = cacheLDB(1,chanl,fcbp->ENDLDB,&ldbp);     /* read last used LDB */
 
737
myindx = (int) fcbp->ENDLDB_OFF - 1;    /* remember that arrays begin with 0  */
 
738
        
 
739
 
 
740
/*  determine no. of elements + length in 4-byte words  */
 
741
 
 
742
if ( (dsctype == 'I') || (dsctype == 'R') )
 
743
   long_len = mm1;
 
744
else if (dsctype == 'D')
 
745
   {
 
746
   n = DD_SIZE / II_SIZE;               /* no. of integers in a double */
 
747
   mm1 *= n;                    /* double prec. looks internally as int */
 
748
   long_len = mm1;
 
749
   }
 
750
else if (dsctype == 'S')
 
751
   {
 
752
   n = SS_SIZE / II_SIZE;               /* no. of size_t in a double */
 
753
   mm1 *= n;                    /* size_t looks internally as int */
 
754
   long_len = mm1;
 
755
   }
 
756
else                            /* for type C */
 
757
   {
 
758
   mm1 *= mm2;
 
759
   long_len = (mm1 + (II_SIZE-1)) / II_SIZE;
 
760
   }
 
761
        
 
762
ldbp->LDBWORDS.IWORD[myindx] = mm1;             /* store 1. header lword */
 
763
 
 
764
if (myindx == ext_len)  /* test, if 2. header lword still in same LDB ... */
 
765
   {
 
766
   status = MID_CRELDB(entrx,ldbp);                     
 
767
   if (status != ERR_NORMAL) goto end_of_it;
 
768
 
 
769
   ldbp->LDBWORDS.IWORD[0] = -1;                /* currently no extension... */
 
770
   ldbp->LDBWORDS.IWORD[1] = 0;                 /* index = 0 */
 
771
   myindx = 1;
 
772
   }
 
773
else
 
774
   {
 
775
   myindx ++;
 
776
   ldbp->LDBWORDS.IWORD[myindx] = -1;   /* currently no extension... */
 
777
   if (myindx == ext_len)           /* see, if 2. header lword in same LDB */
 
778
      {
 
779
      status = MID_CRELDB(entrx,ldbp);  
 
780
      if (status != ERR_NORMAL) goto end_of_it;
 
781
 
 
782
      myindx = 0;
 
783
      }
 
784
   else
 
785
      myindx ++;
 
786
 
 
787
   ldbp->LDBWORDS.IWORD[myindx] = 0;                    /* index = 0  */
 
788
   }
 
789
 
 
790
myindx += (long_len + 1) ;
 
791
        
 
792
 
 
793
while (myindx > ext_len)                        /* we need more LDBs */
 
794
   {
 
795
   status = MID_CRELDB(entrx,ldbp);             /* get new LDB + link it in */
 
796
   if (status != ERR_NORMAL) goto end_of_it;
 
797
 
 
798
   myindx -= LDB_NDSCRW;
 
799
   }
 
800
 
 
801
ios = cacheLDB(2,chanl,ldbp->BLKNUM,&ldbp);     
 
802
        
 
803
/*  and update FCB (FCB.ENDLDB counts from 1 on) */
 
804
 
 
805
fcbp->ENDLDB = (unsigned int) ldbp->BLKNUM;
 
806
fcbp->ENDLDB_OFF = (unsigned int) (myindx + 1); 
 
807
if (iret == 1)
 
808
   goto add_2;
 
809
else 
 
810
   goto end_of_it;
 
811
 
 
812
 
 
813
 
 
814
 
 
815
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   
 
816
        
 
817
   working section for extending + linking descriptors...
 
818
        
 
819
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
 
820
        
 
821
work_b:
 
822
ext_len = LDB_NDSCRW1;                  /* index will move from 0 on... */
 
823
ios = cacheLDB(1,chanl,myblock,&ldbp);  /* read last used LDB */
 
824
 
 
825
while (1)
 
826
   {
 
827
   LDBinfo(chanl,ldbp,myindx,&mm,extens);
 
828
                                        /* get pointers only */
 
829
   if (extens[0] != -1)
 
830
      {
 
831
      myblock = extens[0];
 
832
      myindx = extens[1] - 1;           /* on disk file FORTRAN indexing */
 
833
      if (ldbp->BLKNUM != myblock)
 
834
         ios = cacheLDB(1,chanl,myblock,&ldbp); /* get start LDB of descr. */
 
835
      }
 
836
   else
 
837
      {
 
838
      if (ldbp->BLKNUM != myblock)
 
839
         ios = cacheLDB(1,chanl,myblock,&ldbp); /* get start LDB of descr. */
 
840
      break;                            /* already get out of loop...  */
 
841
      }
 
842
   }
 
843
        
 
844
ldbp->LDBWORDS.IWORD[myindx] = mm;
 
845
if (myindx == ext_len)  /* test, if 2. header lword still in same LDB ... */
 
846
   {
 
847
   status = MID_CRELDB(entrx,ldbp);
 
848
   if (status != ERR_NORMAL) goto end_of_it;
 
849
 
 
850
   ldbp->LDBWORDS.IWORD[0] = (int) fcbp->ENDLDB;        /* store 2. header word */
 
851
   ldbp->LDBWORDS.IWORD[1] = (int) fcbp->ENDLDB_OFF;    /* store 3. header word */
 
852
   }
 
853
else
 
854
   {
 
855
   myindx ++;
 
856
   ldbp->LDBWORDS.IWORD[myindx] =       /* store 2. header word */
 
857
         (int) fcbp->ENDLDB;    
 
858
   if (myindx == ext_len)       /* see, if 3. header word still in same LDB */
 
859
      {
 
860
      status = MID_CRELDB(entrx,ldbp);
 
861
      if (status != ERR_NORMAL) goto end_of_it;
 
862
 
 
863
      myindx = 0;
 
864
      }
 
865
   else
 
866
      myindx ++;
 
867
 
 
868
   ldbp->LDBWORDS.IWORD[myindx] =               /* store 3. header word */
 
869
         (int) fcbp->ENDLDB_OFF;
 
870
   }
 
871
 
 
872
ios = cacheLDB(2,chanl,ldbp->BLKNUM,&ldbp);     /* update LDB */
 
873
if (iret == 1)
 
874
   goto add_1;
 
875
else
 
876
   goto extend_1;               /* go back to where we came from... */
 
877
 
 
878
 
 
879
 
 
880
 
 
881
 
 
882
/* ......
 
883
 
 
884
   that's it folks...
 
885
 
 
886
   ...... */
 
887
 
 
888
end_of_it:
 
889
if (dscupda == 1)
 
890
   {
 
891
   fcbp->DFILLED = dirused;
 
892
   fcbp->DSIZE = diralloc;
 
893
   }
 
894
old_descr[0] = '\0';
 
895
 
 
896
if (status != ERR_NORMAL)
 
897
   MID_ERROR("MIDAS","MID_YDSCDIR:",status,0);
 
898
 
 
899
return status;
 
900
}
 
901
 
 
902