NCEPLIBS-bufr  12.0.0
stseq.c
Go to the documentation of this file.
1 
8 #include "bufrlib.h"
9 #include "mstabs.h"
10 
27 int
28 cmpia(const void *pf1, const void *pf2)
29 {
30  int *mypf1 = ( int * ) pf1;
31  int *mypf2 = ( int * ) pf2;
32 
33  if ( *mypf1 == *mypf2 ) return 0;
34 
35  return ( *mypf1 < *mypf2 ? -1 : 1 );
36 }
37 
53 void
54 nummtb(int *idn, char *tab, int *ipt)
55 {
56  int *pifxyn, *pbs, nmt;
57 
58  char adn[FXY_STR_LEN+1], errstr[129];
59 
60  if ( *idn >= ifxy_f(MIN_FXY_TABLED) ) {
61  *tab = 'D';
62  pifxyn = &idfxyn_c[0];
63  nmt = nmtd_c;
64  }
65  else {
66  *tab = 'B';
67  pifxyn = &ibfxyn_c[0];
68  nmt = nmtb_c;
69  }
70 
71  pbs = bsearch(idn, pifxyn, (size_t) nmt, sizeof(int),
72  (int (*) (const void *, const void *)) cmpia);
73  if ( pbs == NULL ) {
74  cadn30_f(*idn, adn, FXY_STR_LEN+1);
75  sprintf(errstr, "BUFRLIB: NUMMTB - COULD NOT FIND DESCRIPTOR "
76  "%s IN MASTER TABLE %c", adn, *tab);
77  bort_f(errstr);
78  }
79  *ipt = pbs - pifxyn;
80 
81  return;
82 }
83 
110 void
111 stseq(int lun, int *irepct, int idn, char *nemo,
112  char *cseq, int *cdesc, int ncdesc)
113 {
114  int i, j, nb, nd, ix, iy, iret, nbits;
115  int rpidn, pkint, ilen, imxcd, ipt, *rpdesc;
116 
117  char tab, adn[FXY_STR_LEN+1], adn2[FXY_STR_LEN+1], units[10], errstr[129];
118  char nemo2[NEMO_STR_LEN+1], rpseq[56], card[80], ctmp[4], cblk = ' ', czero = '0';
119 
120 /*
121 ** The following variables are declared as static so that they
122 ** automatically initialize to zero and remain unchanged between
123 ** recursive calls to this subroutine.
124 */
125  static int naf, iafpk[MXNAF];
126 
127 /*
128 ** Is idn already listed as an entry in the internal Table D?
129 ** If so, then there's no need to proceed any further.
130 */
131  numtbd_f(lun, idn, nemo2, NEMO_STR_LEN+1, &tab, &iret);
132  if ( ( iret > 0 ) && ( tab == 'D' ) ) return;
133 
134 /*
135 ** Start a new Table D entry for idn.
136 */
137  tab = 'D';
138  nd = igetntbi_f(lun, &tab);
139  cadn30_f(idn, adn, FXY_STR_LEN+1);
140  stntbi_f(nd, lun, adn, nemo, cseq);
141 
142 /*
143 ** Now, go through the list of child descriptors corresponding to idn.
144 */
145  imxcd = igetprm_f("MAXCD");
146 
147  for ( i = 0; i < ncdesc; i++ ) {
148  cadn30_f(cdesc[i], adn, FXY_STR_LEN+1); adn[6] = '\0';
149  strncpy(ctmp, &adn[1], 2); ctmp[2] = '\0';
150  strnum_f(ctmp, &ix, &iret);
151  strncpy(ctmp, &adn[3], 4); /* trailing null will be included in this copy */
152  strnum_f(ctmp, &iy, &iret);
153  if ( adn[0] == '3' ) {
154 /*
155 ** cdesc[i] is itself a Table D descriptor, so locate it within the
156 ** master table D and then store the contents within the internal
157 ** Table D via a recursive call to this same routine.
158 */
159  nummtb(&cdesc[i], &tab, &ipt);
160  if ( naf > 0 ) {
161 /*
162 ** There are associated fields in effect which will modify this
163 ** descriptor when storing it within the internal Table D. So
164 ** create a new sequence to store the contents of this descriptor
165 ** along with its associated fields.
166 */
167  rpidn = igettdi_f(lun);
168 
169  sprintf(rpseq, "REPLICATION SEQUENCE %.3d", ++(*irepct));
170  memset(&rpseq[24], (int) cblk, 31);
171  sprintf(nemo2, "RPSEQ%.3d", *irepct);
172 
173  stseq(lun, irepct, rpidn, nemo2, rpseq,
174  &idefxy_c[icvidx(ipt,0,imxcd)],
175  ndelem_c[ipt]);
176  pkint = rpidn;
177 
178  }
179  else {
180 /*
181 ** Store cdesc[i] as is directly within the internal Table D.
182 */
183  stseq(lun, irepct, cdesc[i], &cdmnem_c[ipt][0],
184  &cdseq_c[ipt][0],
185  &idefxy_c[icvidx(ipt,0,imxcd)],
186  ndelem_c[ipt]);
187  pkint = cdesc[i];
188  }
189  }
190  else if ( adn[0] == '2' ) {
191 /*
192 ** cdesc[i] is an operator descriptor.
193 */
194  if ( ( ( ix >= 4 ) && ( ix <= 6 ) ) || ( imrkopr_f(adn) ) ) {
195 /*
196 ** This is a 204YYY, 205YYY, 206YYY operator, or else a 223255,
197 ** 224255, 225255 or 232255 marker operator. In any case,
198 ** generate a Table B mnemonic to hold the corresponding data.
199 */
200  strncpy(nemo2, adn, 6);
201  memset(&nemo2[6], (int) cblk, 2);
202  nemo2[8] = '\0';
203 
204  if ( ( ix == 4 ) && ( iy == 0 ) ) {
205 /*
206 ** Cancel the most-recently added associated field.
207 */
208  if ( naf-- <= 0 ) {
209  sprintf(errstr, "BUFRLIB: STSEQ - TOO MANY ASSOCIATED"
210  " FIELD CANCELLATION OPERATORS");
211  bort_f(errstr);
212  }
213  }
214  else {
215 /*
216 ** Is nemo2 already listed as an entry within the internal
217 ** Table B?
218 */
219  nemtab_f(lun, nemo2, &pkint, &tab, &iret);
220  if ( ( iret == 0 ) || ( tab != 'B' ) ) {
221 /*
222 ** No, so create and store a new Table B entry for nemo2.
223 */
224  tab = 'B';
225  nb = igetntbi_f(lun, &tab);
226 
227  if ( ix == 4 ) {
228  sprintf(rpseq, "Associated field of %3d bits", iy);
229  nbits = iy;
230  strcpy(units, "NUMERIC");
231  }
232  else if ( ix == 5 ) {
233  sprintf(rpseq, "Text string of %3d bytes", iy);
234  nbits = iy*8;
235  strcpy(units, "CCITT IA5");
236  }
237  else if ( ix == 6 ) {
238  sprintf(rpseq, "Local descriptor of %3d bits", iy);
239  nbits = iy;
240  if ( nbits > 32 ) {
241  strcpy(units, "CCITT IA5");
242  }
243  else {
244  strcpy(units, "NUMERIC");
245  }
246  }
247  else { // 2-XX-255 marker operator
248  if ( ix == 23 ) {
249  sprintf(rpseq, "Substituted value");
250  }
251  else if ( ix == 24 ) {
252  sprintf(rpseq, "First-order statistical value");
253  }
254  else if ( ix == 25 ) {
255  sprintf(rpseq, "Difference statistical value");
256  }
257  else if ( ix == 32 ) {
258  sprintf(rpseq, "Replaced/retained value");
259  }
260  /* For now, set a default bit width and units. */
261  nbits = 8;
262  strcpy(units, "NUMERIC");
263  }
264  ilen = ( int ) strlen(rpseq);
265  memset(&rpseq[ilen], (int) cblk, 55 - ilen);
266 /*
267 ** Note that 49152 = 3*(2**14), so subtracting 49152 in the
268 ** following statement changes a Table D bit-wise FXY value into
269 ** a Table B bit-wise FXY value.
270 */
271  pkint = (igettdi_f(lun) - 49152);
272  cadn30_f(pkint, adn2, FXY_STR_LEN+1);
273 
274  stntbi_f(nb, lun, adn2, nemo2, rpseq);
275 
276  /* Initialize card to all blanks. */
277  memset(card, (int) cblk, sizeof( card ));
278 
279  strncpy(&card[2], nemo2, 8);
280  memcpy(&card[16], &czero, 1);
281  memcpy(&card[30], &czero, 1);
282  sprintf(&card[33], "%4d", nbits);
283  strcpy(&card[40], units);
284  card[40+strlen(units)] = cblk; /* overwrite trailing null */
285  elemdx_f(card, lun);
286  }
287  if ( ix == 4 ) {
288 /*
289 ** Add an associated field.
290 */
291  if ( naf >= MXNAF ) {
292  sprintf(errstr, "BUFRLIB: STSEQ - TOO MANY ASSOCIATED"
293  " FIELDS ARE IN EFFECT AT THE SAME TIME");
294  bort_f(errstr);
295  }
296  iafpk[naf++] = pkint;
297  }
298  }
299  if ( ix == 6 ) {
300 /*
301 ** Skip over the local descriptor placeholder.
302 */
303  if ( ++i >= ncdesc ) {
304  sprintf(errstr, "BUFRLIB: STSEQ - COULD NOT FIND LOCAL"
305  " DESCRIPTOR PLACEHOLDER FOR %s", adn);
306  bort_f(errstr);
307  }
308  }
309  }
310  else {
311  pkint = cdesc[i];
312  }
313  }
314  else if ( adn[0] == '1' ) {
315 /*
316 ** cdesc[i] is a replication descriptor, so create a sequence
317 ** consisting of the set of replicated descriptors and then immediately
318 ** store that sequence within the internal Table D via a recursive call
319 ** to this same routine.
320 **
321 ** See subroutine BFRINI and COMMON /REPTAB/ for the source of the FXY
322 ** values referenced in the following block. Note we are guaranteed
323 ** that 0 <= iy <= 255 since adn was generated using subroutine CADN30.
324 */
325  if ( iy == 0 ) { /* delayed replication */
326  if ( ( i+1 ) >= ncdesc ) {
327  sprintf(errstr, "BUFRLIB: STSEQ - COULD NOT FIND DELAYED "
328  "DESCRIPTOR REPLICATION FACTOR FOR %s", adn);
329  bort_f(errstr);
330  }
331  else if ( cdesc[i+1] == ifxy_f("031002") ) {
332  pkint = ifxy_f("360001");
333  }
334  else if ( cdesc[i+1] == ifxy_f("031001") ) {
335  pkint = ifxy_f("360002");
336  }
337  else if ( cdesc[i+1] == ifxy_f("031000") ) {
338  pkint = ifxy_f("360004");
339  }
340  else {
341  sprintf(errstr, "BUFRLIB: STSEQ - UNKNOWN DELAYED "
342  "DESCRIPTOR REPLICATION FACTOR FOR %s", adn);
343  bort_f(errstr);
344  }
345  i += 2;
346  }
347  else { /* regular replication */
348  pkint = ifxy_f(MIN_FXY_REPL) + iy;
349  i++;
350  }
351 /*
352 ** Store this replication descriptor within the table D entry for
353 ** this parent.
354 */
355  pktdd_f(nd, lun, pkint, &iret);
356  if ( iret < 0 ) {
357  strncpy(nemo2, nemo, 8);
358  nemo2[8] = '\0';
359  sprintf(errstr, "BUFRLIB: STSEQ - BAD RETURN FROM PKTDD WHEN "
360  "STORING REPLICATOR FOR PARENT MNEMONIC %s", nemo2);
361  bort_f(errstr);
362  }
363 /*
364 ** Note we are guaranteed that 0 < ix <= 63 since adn was generated
365 ** using subroutine CADN30.
366 */
367  if ( ix > ( ncdesc - i ) ) {
368  sprintf(errstr, "BUFRLIB: STSEQ - NOT ENOUGH REMAINING CHILD "
369  "DESCRIPTORS TO COMPLETE REPLICATION FOR %s", adn);
370  bort_f(errstr);
371  }
372  else if ( ( ix == 1 ) && ( cdesc[i] >= ifxy_f(MIN_FXY_TABLED) ) ) {
373 /*
374 ** The only thing being replicated is a single Table D descriptor,
375 ** so there's no need to invent a new sequence for this replication
376 ** (this is a special case!)
377 */
378  nummtb(&cdesc[i], &tab, &ipt);
379  stseq(lun, irepct, cdesc[i], &cdmnem_c[ipt][0],
380  &cdseq_c[ipt][0],
381  &idefxy_c[icvidx(ipt,0,imxcd)],
382  ndelem_c[ipt]);
383  pkint = cdesc[i];
384  }
385  else {
386 /*
387 ** Store the ix descriptors to be replicated in a local list, then
388 ** get an FXY value to use with this list and generate a unique
389 ** mnemonic and description as well.
390 */
391 
392  if ( ( rpdesc = malloc( imxcd * sizeof(int) ) ) == NULL ) {
393  sprintf(errstr, "BUFRLIB: STSEQ - UNABLE TO ALLOCATE SPACE"
394  " FOR RPDESC");
395  bort_f(errstr);
396  }
397 
398  for ( j = 0; j < ix; j++ ) {
399  rpdesc[j] = cdesc[i+j];
400  }
401 
402  rpidn = igettdi_f(lun);
403 
404  sprintf(rpseq, "REPLICATION SEQUENCE %.3d", ++(*irepct));
405  memset(&rpseq[24], (int) cblk, 31);
406  sprintf(nemo2, "RPSEQ%.3d", *irepct);
407 
408  stseq(lun, irepct, rpidn, nemo2, rpseq, rpdesc, ix);
409 
410  free(rpdesc);
411 
412  pkint = rpidn;
413  i += ix - 1;
414  }
415  }
416  else {
417 /*
418 ** cdesc[i] is a Table B descriptor.
419 **
420 ** Is cdesc[i] already listed as an entry in the internal Table B?
421 */
422  numtbd_f(lun, cdesc[i], nemo2, NEMO_STR_LEN+1, &tab, &iret);
423  if ( ( iret == 0 ) || ( tab != 'B' ) ) {
424 /*
425 ** No, so search for it within the master table B.
426 */
427  nummtb(&cdesc[i], &tab, &ipt);
428 /*
429 ** Start a new Table B entry for cdesc[i].
430 */
431  nb = igetntbi_f(lun, &tab);
432  cadn30_f(cdesc[i], adn2, FXY_STR_LEN+1);
433  stntbi_f(nb, lun, adn2, &cbmnem_c[ipt][0], &cbelem_c[ipt][0]);
434 
435  /* Initialize card to all blanks. */
436  memset(card, (int) cblk, sizeof( card ));
437 
438  strncpy(&card[2], &cbmnem_c[ipt][0], 8);
439  strncpy(&card[13], &cbscl_c[ipt][0], 4);
440  strncpy(&card[19], &cbsref_c[ipt][0], 12);
441  strncpy(&card[33], &cbbw_c[ipt][0], 4);
442  strncpy(&card[40], &cbunit_c[ipt][0], 24);
443  elemdx_f(card, lun);
444  }
445  pkint = cdesc[i];
446  }
447  if (strncmp( adn, "204", 3) != 0 ) {
448 /*
449 ** Store this child descriptor within the table D entry for this
450 ** parent, preceding it with any associated fields that are currently
451 ** in effect.
452 **
453 ** Note that associated fields are only applied to Table B descriptors,
454 ** except for those in Class 31.
455 */
456  if ( ( naf > 0 ) && ( pkint <= ifxy_f(MAX_FXY_TABLEB) ) &&
457  ( ( pkint < ifxy_f("031000") ) ||
458  ( pkint > ifxy_f("031255") ) ) ) {
459  for ( j = 0; j < naf; j++ ) {
460  pktdd_f(nd, lun, iafpk[j], &iret);
461  if ( iret < 0 ) {
462  sprintf(errstr, "BUFRLIB: STSEQ - BAD RETURN FROM PKTDD "
463  "WHEN STORING ASSOCIATED FIELDS");
464  bort_f(errstr);
465  }
466  }
467  }
468 /*
469 ** Store the child descriptor.
470 */
471  pktdd_f(nd, lun, pkint, &iret);
472  if ( iret < 0 ) {
473  strncpy(nemo2, nemo, 8);
474  nemo2[8] = '\0';
475  sprintf(errstr, "BUFRLIB: STSEQ - BAD RETURN FROM PKTDD WHEN "
476  "STORING CHILD FOR PARENT MNEMONIC %s", nemo2);
477  bort_f(errstr);
478  }
479  }
480  }
481 }
int igetprm_f(char *cprmnm)
Get the current value of a parameter.
void nemtab_f(int lun, const char *mnemonic, int *descriptor, char *table_type, int *table_idx)
Get information about a descriptor.
Enable a number of NCEPLIBS-bufr subprograms to be called from within the C part of the library.
int igettdi_f(int iflag)
Get the next usable Table D index for the current master table, or reset the index.
void cadn30_f(int idn, char *adn, int adn_str_len)
Convert an FXY value from its WMO bit-wise representation to its six-character representation.
#define FXY_STR_LEN
Size of a character string needed to store an FXY value.
Definition: bufrlib.h:54
void elemdx_f(char *card, int lun)
Decode the scale factor, reference value, bit width, and units from a Table B mnemonic definition.
int imrkopr_f(char *nemo)
Check whether a specified mnemonic is a Table C marker operator.
#define MXNAF
Maximum number of associated fields that can be in effect at any given time for a Table B descriptor.
Definition: bufrlib.h:51
void numtbd_f(int lun, int idn, char *nemo, int nemo_str_len, char *tab, int *iret)
Search for a Table B or Table D descriptor within the internal DX BUFR tables.
void bort_f(char *errstr)
Log one error message and abort application program.
void stntbi_f(int n, int lun, char *numb, char *nemo, char *celsq)
Store a new entry within the internal BUFR Table B or D.
#define MIN_FXY_REPL
Character string containing minimum FXY value for a replication descriptor.
Definition: bufrlib.h:57
#define MIN_FXY_TABLED
Character string containing minimum FXY value for a Table D descriptor.
Definition: bufrlib.h:60
int ifxy_f(char *cfxy)
Convert an FXY value from its 6 character representation to its WMO bit-wise representation.
void strnum_f(char *str, int *num, int *iret)
Decode an integer from a character string.
#define NEMO_STR_LEN
Size of a character string needed to store a mnemonic.
Definition: bufrlib.h:66
#define MAX_FXY_TABLEB
Character string containing maximum FXY value for a Table B descriptor.
Definition: bufrlib.h:63
void pktdd_f(int id, int lun, int idn, int *iret)
Store information about a child mnemonic within the internal arrays.
int igetntbi_f(int lun, char *table_type)
Get the next index for storing an entry within an internal DX BUFR table.
int icvidx(int ii, int jj, int numjj)
Computes a unique 1-dimensional array index from 2-dimensional indices.
Definition: icvidx.c:22
Declare variables for internal storage of master Table B and Table D entries.
char(* cbunit_c)[24]
Master Table B units; copied from Fortran cbunit array.
int * idfxyn_c
Bit-wise representations of master Table D FXY numbers; copied from Fortran idfxyn array.
char(* cdmnem_c)[8]
Master Table D mnemonics; copied from Fortran cdmnem array.
char(* cbelem_c)[120]
Master Table B element names; copied from Fortran cbelem array.
int * ndelem_c
Number of child descriptors for master Table D sequence; copied from Fortran ndelem array.
int nmtd_c
Number of master Table D entries; copied from Fortran nmtd variable.
int * idefxy_c
Bit-wise representations of child descriptors for master Table D sequence; copied from Fortran idefxy...
char(* cbbw_c)[4]
Master Table B bit widths; copied from Fortran cbbw array.
char(* cbsref_c)[12]
Master Table B reference value; copied from Fortran cbsref array.
char(* cdseq_c)[120]
Master Table D sequence names; copied from Fortran cdseq array.
int * ibfxyn_c
Bit-wise representations of master Table B FXY numbers; copied from Fortran ibfxyn array.
int nmtb_c
Number of master Table B entries; copied from Fortran nmtb variable.
char(* cbscl_c)[4]
Master Table B scale factors; copied from Fortran cbscl array.
char(* cbmnem_c)[8]
Master Table B mnemonics; copied from Fortran cbmnem array.
void nummtb(int *idn, char *tab, int *ipt)
Search for an entry in the BUFR master table.
Definition: stseq.c:54
void stseq(int lun, int *irepct, int idn, char *nemo, char *cseq, int *cdesc, int ncdesc)
Store information about a standard Table D descriptor within internal DX BUFR tables.
Definition: stseq.c:111
int cmpia(const void *pf1, const void *pf2)
Define a comparison between two integers.
Definition: stseq.c:28