[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: character data in cdl



> Keywords: 199403232128.AA11848

Hi Charles,

> Does anyone out there use netcdf?
> 
> I'm having trouble understanding how to enter character data in cdl.
> An example follows.  I understand that the values for frame_labels
> will get concatenated according to the documentation (and they do -
> even though this seems useless).  How do I write what I want: a
> separate frame_label string for each frame?  Do I pad the strings with
> something to a fixed length?  Can I pad them with NULLs (this didn't
> seem to work)?  Shouldn't there be something that says "fill the rest
> of this row with the fill value and go to the next row"?  Does hdf
> handle string values any better?
> 
> Thanks,
> Charles
> ----------------------------------------------------------------------
> netcdf reference_vectors {
> 
> dimensions:
>   frame_order = unlimited,
>   gsp_order = 34,
>   maxstr = 256;
> 
> variables:
> char gsp_method(maxstr);
> char filter_bank_name(maxstr);
> char frame_labels(frame_order, maxstr);
> float cum_occurrences(frame_order);
> float gsp_mean(frame_order, gsp_order);
> 
> data:
> gsp_method = "PFV3B";
> filter_bank_name = "14mel_5sf";
> frame_labels = "z_20_m$F_1","z_20_m$F_2","z_20_m$F_3","z_20_m$F_4";
> cum_occurrences = 36,57,70,69;
> gsp_mean =
  ...
> }

Sorry to take so long to answer this, but I went on vacation and things had
piled up when I got back.  As it happens, there is a fix for this
undesirable bahavior in the way ncgen handles strings, developed by Brian
Lincoln of SSECO.  The fix will be in the next release of netCDF, but in the
meantime, I have appended a patch to netcdf/ncgen/ncgen.y that will make it
do what you want.

Please let me know if this patch doesn't fix the problem you discovered.
__________________________________________________________________________
                      
Russ Rew                                              UCAR Unidata Program
address@hidden                                        P.O. Box 3000
(303)497-8645                                 Boulder, Colorado 80307-3000



diff -c -r1.21 ncgen.y
*** /tmp/T0a002yI       Thu Apr  7 11:17:07 1994
--- ncgen.y     Wed Dec 15 23:00:34 1993
***************
*** 1,7 ****
  /*********************************************************************
   *   Copyright 1993, UCAR/Unidata
   *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
!  *   $Header: /home/russ/src/netcdf/ncgen/RCS/ncgen.y,v 1.21 1993/04/02 
19:40:18 russ Exp $
   *********************************************************************/
  
  /* yacc source for "ncgen", a netCDL parser and netCDF generator */
--- 1,7 ----
  /*********************************************************************
   *   Copyright 1993, UCAR/Unidata
   *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
!  *   $Header: /a/zero/home/russ/src/netcdf/ncgen/RCS/ncgen.y,v 1.23 
1993/10/21 17:21:03 russ Exp russ $
   *********************************************************************/
  
  /* yacc source for "ncgen", a netCDL parser and netCDF generator */
***************
*** 8,14 ****
  
  %{
  #ifndef lint
! static char SccsId[] = "$Header: /home/russ/src/netcdf/ncgen/RCS/ncgen.y,v 
1.21 1993/04/02 19:40:18 russ Exp $";
  #endif
  #include        <string.h>
  #include      <stdlib.h>
--- 8,14 ----
  
  %{
  #ifndef lint
! static char SccsId[] = "$Header: 
/a/zero/home/russ/src/netcdf/ncgen/RCS/ncgen.y,v 1.23 1993/10/21 17:21:03 russ 
Exp russ $";
  #endif
  #include        <string.h>
  #include      <stdlib.h>
***************
*** 419,425 ****
  dconst:
                     {
                       if(valnum >= var_len) {
!                          derror("too many values for this variable");
                           exit (4);
                       }
                       not_a_string = 1;
--- 419,426 ----
  dconst:
                     {
                       if(valnum >= var_len) {
!                          derror("too many values for this variable, %d >= %d",
!                                 valnum, var_len);
                           exit (4);
                       }
                       not_a_string = 1;
***************
*** 515,530 ****
                       {
                           int len = strlen(termstring);
  
!                          valnum += len;
!                          if(valnum > var_len) {
!                              derror("string won't fit in this variable");
                               exit (5);
                           }
                           switch (valtype) {
                             case NC_CHAR:
!                              (void)strncpy(char_valp,termstring,len);
!                              char_valp += len;
!                              rec_cur = (void *) char_valp;
                               break;
                             case NC_BYTE:
                               (void)strncpy(byte_valp,termstring,len);
--- 516,542 ----
                       {
                           int len = strlen(termstring);
  
!                          if(valnum+len > var_len) {
!                              derror("string won't fit in this variable, 
%d>%d", 
!                                     valnum, var_len);
                               exit (5);
                           }
                           switch (valtype) {
                             case NC_CHAR:
!                              {
!                                  int i, sl, ld;
!                                  (void)strncpy(char_valp,termstring,len);
!                                  /* null-fill to size of last dim */
!                                  ld = vars[varnum].ndims-1;
!                                  sl = dims[vars[varnum].dims[ld]].size;
!                                  for (i =len;i<sl;i++)
!                                    char_valp[i] = '\0';
!                                  if (sl < len)
!                                    sl = len;
!                                  valnum += sl;
!                                  char_valp += sl;
!                                  rec_cur = (void *) char_valp;
!                              }
                               break;
                             case NC_BYTE:
                               (void)strncpy(byte_valp,termstring,len);
***************
*** 687,692 ****
--- 699,709 ----
  {
        derror(s);
  }
+ 
+ /* undefine yywrap macro, in case we are using bison instead of yacc */
+ #ifdef yywrap
+ #undef yywrap
+ #endif
  
  int
  yywrap()                      /* returns 1 on EOF if no more input */