nco/nco_lst_utl.h File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>
#include "nco_netcdf.h"
#include "nco.h"
#include "nco_ctl.h"
#include "nco_mmr.h"

Include dependency graph for nco_lst_utl.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void indexx (const int lmn_nbr, const int *const arr_in, int *const idx)
void indexx_alpha (const int lmn_nbr, char *const *const arr_in, int *const idx)
char ** lst_prs_1D (char *const sng_in, const char *const dlm_sng, int *const nbr_lst)
char ** lst_prs_2D (const char *const sng_in, const char *const dlm_sng, int *const nbr_lst)
nm_id_sctlst_heapsort (nm_id_sct *lst, const int nbr_lst, const nco_bool ALPHABETIZE_OUTPUT)
int nco_cmp_chr (const void *val_1, const void *val_2)
int nco_cmp_int (const void *val_1, const void *val_2)
int nco_cmp_sng (const void *val_1, const void *val_2)
int nco_cmp_nm_id_nm (const void *val_1, const void *val_2)
int nco_cmp_nm_id_id (const void *val_1, const void *val_2)
int nco_cmp_ptr_unn (const nc_type type, const ptr_unn op1, const ptr_unn op2)
dmn_sct ** nco_dmn_lst_free (dmn_sct **dmn_lst, const int dmn_nbr)
void nco_lst_comma2hash (char *const rx_sng)
nm_id_sctnco_lst_srt_nm_id (nm_id_sct *const lst, const int nbr_lst, const nco_bool ALPHABETIZE_OUTPUT)
nm_id_sctnco_nm_id_lst_free (nm_id_sct *nm_id_lst, const int nm_id_nbr)
char ** nco_sng_lst_free (char **sng_lst, const int sng_nbr)
char * sng_lst_cat (char **const sng_lst, const long lmn_nbr, const char *const dlm_sng)


Function Documentation

void indexx const int  lmn_nbr,
const int *const   arr_in,
int *const   idx
 

Definition at line 18 of file nco_lst_utl.c.

References EXIT_FAILURE, nco_exit(), and prg_nm_get().

00021 {
00022   /* Purpose: Stub for Numerical Recipes-compatible indexx() routine */
00023   long foo=sizeof(lmn_nbr)+sizeof(arr_in)+sizeof(idx); /* CEWI */
00024   foo++; /* CEWI */
00025   (void)fprintf(stdout,"%s: ERROR indexx() routine should not be called\n",prg_nm_get());
00026   nco_exit(EXIT_FAILURE);
00027 } /* end indexx() */

void indexx_alpha const int  lmn_nbr,
char *const *const   arr_in,
int *const   idx
 

Definition at line 31 of file nco_lst_utl.c.

References EXIT_FAILURE, nco_exit(), and prg_nm_get().

00034 {
00035   /* Purpose: Stub for Numerical Recipes-compatible indexx_alpha() routine */
00036   long foo=sizeof(lmn_nbr)+sizeof(arr_in)+sizeof(idx); /* CEWI */
00037   foo++; /* CEWI */
00038   (void)fprintf(stdout,"%s: ERROR indexx_alpha() routine should not be called\n",prg_nm_get());
00039   nco_exit(EXIT_FAILURE);
00040 } /* end indexx() */

nm_id_sct* lst_heapsort nm_id_sct lst,
const int  nbr_lst,
const nco_bool  ALPHABETIZE_OUTPUT
 

Definition at line 44 of file nco_lst_utl.c.

References nco_free(), and nco_malloc().

00047 {
00048   /* Purpose: Sort extraction lists numerically or alphabetically
00049      Routine is deprecated in favor of nco_lst_srt_nm_id() which uses system qsort()
00050      lst_heapsort drives Numerical Recipes indexx-style routines
00051 
00052      Advantage of indexx* routines is they return list of sorted indices,
00053      allowing original list to be untouched and sorted indices to be used.
00054      Disadvantage of indexx* routines is they employ 1-based indexing,
00055      and are non-free.
00056 
00057      This driver routine IS free, and maintained for future reference
00058      Main purpose of routine is to handle bookkeeping of copying structure
00059      elements to be sorted and rearranging original list on basis of sorted indices */
00060 
00061   int *srt_idx; /* List to store sorted key map */
00062   int idx; /* Counting index */
00063   nm_id_sct *lst_tmp; /* Temporary copy of original extraction list */
00064   
00065   srt_idx=(int *)nco_malloc(nbr_lst*sizeof(int));
00066   lst_tmp=(nm_id_sct *)nco_malloc(nbr_lst*sizeof(nm_id_sct));
00067   (void)memcpy((void *)lst_tmp,(void *)lst,nbr_lst*sizeof(nm_id_sct));
00068   
00069   /* indexx() and relatives assume "one-based" arrays 
00070      Use pointer arithmetic to spoof zero-based arrays, i.e.,
00071      xtr_nm[0] in calling routine becomes xtr_nm[1] in sorting routine  */
00072   if(ALPHABETIZE_OUTPUT){
00073     /* Alphabetize list by variable name
00074        This produces easy-to-read screen output with ncks */
00075     char **xtr_nm;
00076     xtr_nm=(char **)nco_malloc(nbr_lst*sizeof(char *));
00077     for(idx=0;idx<nbr_lst;idx++) xtr_nm[idx]=lst[idx].nm;
00078     /* Replace with free (speech) index_alpha() replacement */
00079     /*(void)index_alpha(nbr_lst,xtr_nm-1,srt_idx-1);*/
00080     xtr_nm=(char **)nco_free(xtr_nm);
00081   }else{
00082     /* Heapsort list by variable ID 
00083        This theoretically allows fastest I/O when creating output file */
00084     int *xtr_id;
00085     xtr_id=(int *)nco_malloc(nbr_lst*sizeof(int));
00086     for(idx=0;idx<nbr_lst;idx++) xtr_id[idx]=lst[idx].id;
00087     /* Replace with free (speech) indexx() replacement */
00088     /* (void)indexx(nbr_lst,xtr_id-1,srt_idx-1);*/
00089     xtr_id=(int *)nco_free(xtr_id);
00090   } /* end else */
00091 
00092   /* indexx and relatives employ "one-based" arrays 
00093      Thus min(srt_idx) == 1 and max(srt_idx) == nbr_lst */
00094   for(idx=0;idx<nbr_lst;idx++){
00095     lst[idx].id=lst_tmp[srt_idx[idx]-1].id;
00096     lst[idx].nm=lst_tmp[srt_idx[idx]-1].nm;
00097   } /* end loop over idx */
00098   lst_tmp=(nm_id_sct *)nco_free(lst_tmp);
00099   srt_idx=(int *)nco_free(srt_idx);
00100   
00101   return lst;
00102 } /* end lst_heapsort() */

char** lst_prs_1D char *const   sng_in,
const char *const   dlm_sng,
int *const   nbr_lst
 

Definition at line 106 of file nco_lst_utl.c.

References dbg_lvl_get(), and nco_malloc().

00109 {
00110   /* Purpose: Create list of strings from given string and arbitrary delimiter
00111      Routine is often called with system memory, e.g., with strings from
00112      command line arguments whose memory was allocated by shell or by getopt().
00113      Conservative policy would be, therefore, to never modify input string
00114      However, we are safe if any modifications do not extend input string
00115      Thus this routine is allowed to replace delimiter strings by NULs
00116 
00117      NB: Function takes single string as input and returns "list of strings" 
00118      However, this list of strings was not obtained by malloc'ing each string 
00119      It was obtained by inserting delimiters in a single string 
00120      Hence do not try to separately free() each member of list of strings
00121 
00122      Contrasting lst_prs_1D() to successor lst_prs_2D():
00123      lst_prs_2D() creates two-dimensional output string list, i.e., list of pointers to separately malloc()'d buffers
00124      lst_prs_2D() does not modify input
00125      lst_prs_2D() output list should be free'd by nco_sng_lst_free()
00126      lst_prs_1D() creates one-dimensional string list by inserting NULs into single buffer
00127      lst_prs_1D() modifies input (by inserting NULs)
00128      lst_prs_1D() output list may be free'd by nco_free() */
00129 
00130   /* Number of list members is always one more than number of delimiters, e.g.,
00131      foo,,3, has 4 arguments: "foo", "", "3" and "".
00132      A delimiter without an argument is valid syntax to indicate default argument
00133      Therefore a storage convention is necessary to indicate default argument was selected
00134      Either NULL or '\0' can be used without requiring additional flag
00135      NULL is not printable, but is useful as a logical flag since its value is False
00136      On the other hand, '\0', the empty string, can be printed but is not as useful as a flag
00137      Currently, NCO implements former convention, where default selections are set to NULL */
00138     
00139   char **lst; /* O [sng] Array of list elements */
00140   char *sng_in_ptr;
00141 
00142   int dlm_lng;
00143   int idx;
00144 
00145   /* Delimiter must be NUL-terminated (a string) so we may find its length */
00146   dlm_lng=strlen(dlm_sng); 
00147 
00148   /* Increment dummy pointer instead of actual sng_in pointer while searching for delimiters */
00149   sng_in_ptr=sng_in; 
00150 
00151   /* First element does not require preceding delimiter */
00152   *nbr_lst=1;
00153 
00154   /* Count list members */
00155   while((sng_in_ptr=strstr(sng_in_ptr,dlm_sng))){
00156     sng_in_ptr+=dlm_lng;
00157     (*nbr_lst)++;
00158   } /* end while */
00159 
00160   lst=(char **)nco_malloc(*nbr_lst*sizeof(char *));
00161 
00162   sng_in_ptr=sng_in; 
00163   lst[0]=sng_in;
00164   idx=0;
00165   while((sng_in_ptr=strstr(sng_in_ptr,dlm_sng))){
00166     /* NUL-terminate previous arg */
00167     *sng_in_ptr='\0';
00168     sng_in_ptr+=dlm_lng;
00169     lst[++idx]=sng_in_ptr;
00170   } /* end while */
00171 
00172   /* Default list member is assumed when two delimiters are adjacent to eachother, 
00173      i.e., when length of string between delimiters is 0. 
00174      If list ends with delimiter, last element of list is also assumed to be default list member */
00175   /* This loop sets default list members to NULL */
00176   for(idx=0;idx<*nbr_lst;idx++)
00177     if(strlen(lst[idx]) == 0) lst[idx]=NULL;
00178 
00179   if(dbg_lvl_get() == 5){
00180     (void)fprintf(stderr,"lst_prs_1d() reports %d elements in list delimited by \"%s\"\n",*nbr_lst,dlm_sng);
00181     for(idx=0;idx<*nbr_lst;idx++) 
00182       (void)fprintf(stderr,"lst[%d] = %s\n",idx,(lst[idx] == NULL) ? "NULL" : lst[idx]);
00183     (void)fprintf(stderr,"\n");
00184     (void)fflush(stderr);
00185   } /* end debug */
00186 
00187   return lst;
00188 } /* end lst_prs_1D() */

char** lst_prs_2D const char *const   sng_in,
const char *const   dlm_sng,
int *const   nbr_lst
 

Definition at line 192 of file nco_lst_utl.c.

References dbg_lvl_get(), nco_free(), and nco_malloc().

Referenced by main(), nco_lmt_prs(), nco_lmt_udu_cnv(), and nco_prs_aed_lst().

00195 {
00196   /* Purpose: Create list of strings from given string and arbitrary delimiter
00197      Algorithm recursively copies all text up to delimiter into new string and
00198      then appends new string to output list
00199      Output list has no delimiter strings
00200      Contrasting lst_prs_2D() to predecessor lst_prs_1D():
00201      lst_prs_2D() creates two-dimensional output string list, i.e., list of pointers to separately malloc()'d buffers
00202      lst_prs_2D() does not modify input
00203      lst_prs_2D() output list should be free'd by nco_sng_lst_free()
00204      lst_prs_1D() creates one-dimensional string list by inserting NULs into single buffer
00205      lst_prs_1D() modifies input (by inserting NULs)
00206      lst_prs_1D() output list may be free'd by nco_free() */
00207 
00208   /* Number of list members is always one more than number of delimiters, e.g.,
00209      foo,,3, has 4 arguments: "foo", "", "3" and "".
00210      A delimiter without an argument is valid syntax to indicate default argument
00211      Therefore a storage convention is necessary to indicate default argument was selected
00212      Either NULL or '\0' can be used without requiring additional flag
00213      NULL is not printable, but is useful as a logical flag since its value is False
00214      On the other hand, '\0', the empty string, can be printed but is not as useful as a flag
00215      Currently, NCO implements former convention, where default selections are set to NULL */
00216     
00217   char **sng_lst_out; /* O [sng] Array of list elements */
00218   char *sng_in_cpy;
00219   char *dlm_ptr_crr;
00220   char *sng_out_srt;
00221 
00222   int dlm_lng;
00223   int idx;
00224 
00225   /* Delimiter must be NUL-terminated (a string) so we may find its length */
00226   dlm_lng=strlen(dlm_sng);
00227 
00228   /* Create duplicate to search, modify, copy, and free */
00229   sng_in_cpy=(char *)strdup(sng_in); 
00230 
00231   /* Increment temporary dummy pointer dlm_ptr_crr in strstr() search loops */
00232   dlm_ptr_crr=sng_in_cpy;
00233 
00234   /* First element does not require preceding delimiter */
00235   *nbr_lst=1;
00236 
00237   /* Count list members */
00238   while((dlm_ptr_crr=strstr(dlm_ptr_crr,dlm_sng))){
00239     dlm_ptr_crr+=dlm_lng;
00240     (*nbr_lst)++;
00241   } /* end while */
00242 
00243   /* Calling routine has responsibility to free this memory */
00244   sng_lst_out=(char **)nco_malloc(*nbr_lst*sizeof(char *));
00245 
00246   dlm_ptr_crr=sng_in_cpy; 
00247   sng_out_srt=sng_in_cpy;
00248   idx=0;
00249   while((dlm_ptr_crr=strstr(sng_out_srt,dlm_sng))){
00250     /* This loop brackets and grabs "previous" arguments
00251        Grab final argument after loop */
00252     /* NUL-terminate previous arg */
00253     *dlm_ptr_crr='\0';
00254     /* Calling routine has responsibility to free this memory */
00255     sng_lst_out[idx++]=(char *)strdup(sng_out_srt);
00256     sng_out_srt=dlm_ptr_crr+dlm_lng;
00257   } /* end while */
00258   /* Grab final argument after last delimiter
00259      This also handles case of string with no delimiters */
00260   sng_lst_out[idx++]=(char *)strdup(sng_out_srt);
00261 
00262   /* Assume default list member when two delimiters are adjacent to eachother, 
00263      i.e., when length of string between delimiters is 0. 
00264      If list ends with delimiter, last element of list is also assumed to be default list member */
00265   /* This loop sets default list members to NULL */
00266   for(idx=0;idx<*nbr_lst;idx++)
00267     if(strlen(sng_lst_out[idx]) == 0) sng_lst_out[idx]=NULL;
00268 
00269   if(dbg_lvl_get() == 5){
00270     (void)fprintf(stderr,"lst_prs_2D() reports %d elements in list delimited by \"%s\"\n",*nbr_lst,dlm_sng);
00271     for(idx=0;idx<*nbr_lst;idx++) 
00272       (void)fprintf(stderr,"sng_lst_out[%d] = %s\n",idx,(sng_lst_out[idx] == NULL) ? "NULL" : sng_lst_out[idx]);
00273     (void)fprintf(stderr,"\n");
00274     (void)fflush(stderr);
00275   } /* end debug */
00276 
00277   /* Free duplicate of sng_in */
00278   sng_in_cpy=(char *)nco_free(sng_in_cpy); 
00279 
00280   return sng_lst_out;
00281 } /* end lst_prs_2D() */

int nco_cmp_chr const void *  val_1,
const void *  val_2
 

Definition at line 285 of file nco_lst_utl.c.

00287 {
00288   /* Purpose: Compare two characters
00289      Function is suitable for argument to ANSI C qsort() routine in stdlib.h
00290      Code based on responses to my comp.lang.c thread 20040101 */
00291   const char * const val_1_cp=(char *)val_1;
00292   const char * const val_2_cp=(char *)val_2;
00293   return *val_1_cp < *val_2_cp ? -1 : (*val_1_cp > *val_2_cp);
00294   /* Alternative one-liner:
00295      return (*val_1_cp > *val_2_cp) - (*val_1_cp < *val_2_cp); */
00296 } /* end nco_cmp_chr() */

int nco_cmp_int const void *  val_1,
const void *  val_2
 

Definition at line 300 of file nco_lst_utl.c.

Referenced by nco_var_dmn_rdr_mtd().

00302 {
00303   /* Purpose: Compare two integers
00304      Function is suitable for argument to ANSI C qsort() routine in stdlib.h
00305      Code based on responses to my comp.lang.c thread 20040101 */
00306   const int * const val_1_ip=(int *)val_1;
00307   const int * const val_2_ip=(int *)val_2;
00308   return *val_1_ip < *val_2_ip ? -1 : (*val_1_ip > *val_2_ip);
00309   /* Alternative one-liner:
00310      return (*val_1_ip > *val_2_ip) - (*val_1_ip < *val_2_ip); */
00311 } /* end nco_cmp_int() */

int nco_cmp_nm_id_id const void *  val_1,
const void *  val_2
 

Definition at line 340 of file nco_lst_utl.c.

Referenced by nco_lst_srt_nm_id().

00342 {
00343   /* Purpose: Compare two nm_id_sct's by ID structure member
00344      NB: This function uses a method which is, in general, unsafe
00345      By performing casts and then subracting, we are subject to overflow
00346      conditions should integer values be close to INT_MAX or INT_MIN.
00347      However, we know that nm_id_sct.id values are always small
00348      Thus we use this slightly unsafe method in order to show that
00349      comparison function may be written (albeit unsafely) in one line. */
00350   return (*(nm_id_sct const *)val_1).id-(*(nm_id_sct const *)val_2).id;
00351 } /* end nco_cmp_nm_id_nm() */

int nco_cmp_nm_id_nm const void *  val_1,
const void *  val_2
 

Definition at line 331 of file nco_lst_utl.c.

Referenced by nco_lst_srt_nm_id().

00333 {
00334   /* Purpose: Compare two nm_id_sct's by name structure member */
00335   return strcmp((*(nm_id_sct const *)val_1).nm,(*(nm_id_sct const *)val_2).nm);
00336 } /* end nco_cmp_nm_id_nm() */

int nco_cmp_ptr_unn const nc_type  type,
const ptr_unn  op1,
const ptr_unn  op2
 

Definition at line 355 of file nco_lst_utl.c.

References NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT, nco_dfl_case_nc_type_err(), and type.

00358 {
00359   /* Purpose: Compare values of two scalar pointer unions of same type 
00360      Function is almost suitable for argument to ANSI C qsort() routine in stdlib.h
00361      Like strcmp(), this routine returns <,=,> zero iff op1 <,=,> op2
00362      Routine based on nco_cmp_int()
00363      Note that only first value of pointer unions is compared */
00364   switch(type){
00365   case NC_FLOAT: 
00366     {const float * const op1_fp=op1.fp;
00367     const float * const op2_fp=op2.fp;
00368     return *op1_fp < *op2_fp ? -1 : (*op1_fp > *op2_fp);}
00369     break;
00370   case NC_DOUBLE: break;
00371     {const double * const op1_dp=op1.dp;
00372     const double * const op2_dp=op2.dp;
00373     return *op1_dp < *op2_dp ? -1 : (*op1_dp > *op2_dp);}
00374   case NC_SHORT: break;
00375     {const short * const op1_sp=op1.sp;
00376     const short * const op2_sp=op2.sp;
00377     return *op1_sp < *op2_sp ? -1 : (*op1_sp > *op2_sp);}
00378   case NC_INT: break;
00379     {const nco_int * const op1_lp=op1.lp;
00380     const nco_int * const op2_lp=op2.lp;
00381     return *op1_lp < *op2_lp ? -1 : (*op1_lp > *op2_lp);}
00382   case NC_CHAR: break;
00383     {const nco_char * const op1_cp=op1.cp;
00384     const nco_char * const op2_cp=op2.cp;
00385     return *op1_cp < *op2_cp ? -1 : (*op1_cp > *op2_cp);}
00386   case NC_BYTE: break;
00387     {const nco_byte * const op1_bp=op1.bp;
00388     const nco_byte * const op2_bp=op2.bp;
00389     return *op1_bp < *op2_bp ? -1 : (*op1_bp > *op2_bp);}
00390   default: nco_dfl_case_nc_type_err(); break;
00391   } /* end switch */
00392 
00393   /* Some compilers, e.g., SGI cc, need return statement to end non-void functions */
00394   return 0;
00395 
00396 } /* end nco_cmp_ptr_unn() */

int nco_cmp_sng const void *  val_1,
const void *  val_2
 

Definition at line 315 of file nco_lst_utl.c.

00317 {
00318   /* Purpose: Compare two strings
00319      Function is suitable for argument to ANSI C qsort() routine in stdlib.h
00320      http://www.eskimo.com/~scs/C-faq/q13.8.html describes sorting strings: 
00321      Arguments to qsort()'s comparison function are pointers to objects being sorted,
00322      i.e., pointers to pointers to chars 
00323      strcmp(), however, accepts simple pointers to char
00324      Therefore, strcmp() cannot be used directly as comparison function for qsort()
00325      This wrapper casts input values to simple char pointers, calls strcmp(), and feeds results back to qsort() */
00326   return strcmp(*(char * const *)val_1,*(char * const *)val_2);
00327 } /* end nco_cmp_sng() */

dmn_sct** nco_dmn_lst_free dmn_sct **  dmn_lst,
const int  dmn_nbr
 

Definition at line 224 of file nco_dmn_utl.c.

References nco_dmn_free(), and nco_free().

Referenced by main().

00226 {
00227   /* Threads: Routine is thread safe and calls no unsafe routines */
00228   /* Purpose: Free all memory associated with dynamically allocated dimension structure list */
00229   int idx;
00230 
00231   for(idx=0;idx<dmn_nbr;idx++){
00232     dmn_lst[idx]=nco_dmn_free(dmn_lst[idx]);
00233   } /* end loop over idx */
00234 
00235   /* Free structure pointer last */
00236   dmn_lst=(dmn_sct **)nco_free(dmn_lst);
00237 
00238   return dmn_lst;
00239 } /* end nco_dmn_lst_free() */

void nco_lst_comma2hash char *const   rx_sng  ) 
 

Definition at line 400 of file nco_lst_utl.c.

References False, and True.

Referenced by main().

00401 {
00402   /* Purpose: Convert commas within braces to hashes within braces in regular expressions
00403      Required for handling corner cases in wildcarding regular expressions
00404      NB: Usually this code operates on system memory (e.g., optarg) so be very careful 
00405      not to overwrite ends of strings */
00406   char *cp;
00407   char *cp_cnv=NULL; /* [ptr] Location of comma following open brace */
00408   bool openbrace=False; /* [flg] Open brace has been found */
00409   cp=rx_sng;
00410   /* Loop over each character in string until first NUL encountered */
00411   while(*cp){
00412     /* Find open brace */
00413     if(*cp=='{') openbrace=True;
00414     if(openbrace && *cp==',') cp_cnv=cp;
00415     /* Find close brace */
00416     if(*cp=='}'){ 
00417       /* Change comma following open brace, if any, to hash */
00418       if(cp_cnv) *cp_cnv='#';
00419       /* Reset comma location following open brace */
00420       openbrace=False;
00421       /* Reset indicator and location of comma following open brace */
00422       cp_cnv=NULL;
00423     } /* endif */
00424     /* Increment position in regular expression */
00425     cp++;
00426   } /* end while character is not NUL */
00427 } /* end nco_lst_comma2hash() */

nm_id_sct* nco_lst_srt_nm_id nm_id_sct *const   lst,
const int  nbr_lst,
const nco_bool  ALPHABETIZE_OUTPUT
 

Definition at line 431 of file nco_lst_utl.c.

References nco_cmp_nm_id_id(), and nco_cmp_nm_id_nm().

Referenced by main().

00434 {
00435   /* Purpose: Sort extraction lists numerically or alphabetically */
00436   if(ALPHABETIZE_OUTPUT){
00437     /* Alphabetize list by variable name
00438        This produces easy-to-read screen output with ncks */
00439     qsort(lst,(size_t)nbr_lst,sizeof(lst[0]),nco_cmp_nm_id_nm);
00440   }else{
00441     /* Heapsort list by variable ID 
00442        This theoretically allows fastest I/O when creating output file */
00443     qsort(lst,(size_t)nbr_lst,sizeof(lst[0]),nco_cmp_nm_id_id);
00444   } /* end else */
00445   return lst;
00446 } /* end nco_lst_srt_nm_id() */

nm_id_sct* nco_nm_id_lst_free nm_id_sct nm_id_lst,
const int  nm_id_nbr
 

Definition at line 450 of file nco_lst_utl.c.

References nco_free(), and nm_id_sct::nm.

Referenced by main(), and nco_var_lst_sub().

00452 {
00453   /* Threads: Routine is thread safe and calls no unsafe routines */
00454   /* Purpose: Free all memory associated with dynamically allocated name-ID structure list */
00455   int idx;
00456 
00457   for(idx=0;idx<nm_id_nbr;idx++){
00458     nm_id_lst[idx].nm=(char *)nco_free(nm_id_lst[idx].nm);
00459   } /* end loop over idx */
00460 
00461   /* Free structure pointer last */
00462   nm_id_lst=(nm_id_sct *)nco_free(nm_id_lst);
00463 
00464   return nm_id_lst;
00465 } /* end nco_nm_id_lst_free() */

char** nco_sng_lst_free char **  sng_lst,
const int  sng_nbr
 

Definition at line 519 of file nco_lst_utl.c.

References nco_free().

Referenced by main(), and nco_prs_aed_lst().

00521 {
00522   /* Threads: Routine is thread safe and calls no unsafe routines */
00523   /* Purpose: Free all memory associated with dynamically allocated string list */
00524   int idx;
00525 
00526   for(idx=0;idx<sng_nbr;idx++){
00527     sng_lst[idx]=(char *)nco_free(sng_lst[idx]);
00528   } /* end loop over idx */
00529 
00530   /* Free structure pointer last */
00531   sng_lst=(char **)nco_free(sng_lst);
00532 
00533   return sng_lst;
00534 } /* end nco_sng_lst_free() */

char* sng_lst_cat char **const   sng_lst,
const long  lmn_nbr,
const char *const   dlm_sng
 

Definition at line 469 of file nco_lst_utl.c.

References EXIT_FAILURE, nco_exit(), nco_free(), nco_malloc(), and prg_nm_get().

Referenced by nco_prs_aed_lst().

00472 {
00473   /* Purpose: Join list of strings together into one string
00474      Delete original string list
00475      Elements of input list should all be NUL-terminated strings
00476      Elements with value NUL are interpreted as strings of zero length */
00477 
00478   char *sng; /* Output string */
00479 
00480   int dlm_lng;
00481   long lmn;
00482   long sng_sz=0L; /* NB: sng_sz get incremented */
00483 
00484   if(lmn_nbr == 1L){
00485     sng=(char *)strdup(sng_lst[0]);
00486     goto cln_and_xit;
00487   } /* lmn_nbr != 1L */
00488 
00489   /* Delimiter must be NUL-terminated (a string) so strlen() works */
00490   if(dlm_sng == NULL){
00491     (void)fprintf(stdout,"%s: ERROR sng_lst_cat() reports delimiter string is NULL\n",prg_nm_get());
00492     nco_exit(EXIT_FAILURE);
00493   } /* end if */
00494   dlm_lng=strlen(dlm_sng); 
00495 
00496   /* List elements must be NUL-terminated (strings) so strlen() works */
00497   for(lmn=0L;lmn<lmn_nbr;lmn++) sng_sz+=(sng_lst[lmn] == NULL) ? 0L : strlen(sng_lst[lmn])+dlm_lng;
00498   /* Add one for NUL byte */
00499   sng=(char *)nco_malloc(sizeof(char)*(sng_sz+1L));
00500   /* NUL-terminate string for safety */
00501   sng[0]='\0';
00502   for(lmn=0L;lmn<lmn_nbr;lmn++){
00503     /* List elements must be NUL-terminated (strings) so strcat() works */
00504     sng=(sng_lst[lmn] == NULL) ? sng : strcat(sng,sng_lst[lmn]);
00505     if(lmn != lmn_nbr-1L && dlm_lng != 0) sng=strcat(sng,dlm_sng);
00506   } /* end loop over lmn */
00507 
00508   /* Jump here if only one string */
00509  cln_and_xit:
00510   for(lmn=0L;lmn<lmn_nbr;lmn++){
00511     if(sng_lst[lmn] != NULL) sng_lst[lmn]=(char *)nco_free(sng_lst[lmn]);
00512   } /* end loop over lmn */
00513 
00514   return sng;
00515 } /* end sng_lst_cat() */


Generated on Thu Mar 16 18:15:45 2006 for nco by  doxygen 1.4.4