nco/ncatted.c File Reference

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "nco_getopt.h"
#include <netcdf.h>
#include "nco_netcdf.h"
#include "nco.h"
#include "libnco.h"

Include dependency graph for ncatted.c:

Go to the source code of this file.

Defines

#define MAIN_PROGRAM_FILE

Functions

int main (int argc, char **argv)


Define Documentation

#define MAIN_PROGRAM_FILE
 

Definition at line 119 of file ncatted.c.


Function Documentation

int main int  argc,
char **  argv
 

Definition at line 124 of file ncatted.c.

References aed_sct::att_nm, copyright_prn(), EXIT_FAILURE, EXIT_SUCCESS, False, getopt_long, aed_sct::id, option::name, NC_GLOBAL, NC_MAX_ATTRS, NC_NOERR, NC_SHARE, NC_WRITE, nco__enddef(), nco_aed_prc(), nco_bool, nco_close(), nco_cmd_ln_sng(), nco_enddef(), nco_err_exit(), nco_exit(), nco_exit_gracefully(), nco_fl_cp(), nco_fl_lst_mk(), nco_fl_mk_lcl(), nco_fl_nm_prs(), nco_fl_rm(), nco_free(), nco_hst_att_cat(), nco_inq(), nco_inq_varid(), nco_lbr_vrs_prn(), nco_open(), nco_prs_aed_lst(), nco_redef(), nco_sng_lst_free(), nco_usg_prn(), no_argument, NULL_CEWI, optarg, optind, prg_nm_get(), prg_prs(), required_argument, True, aed_sct::val, aed_sct::var_nm, and ptr_unn::vp.

00125 {
00126   aed_sct *aed_lst=NULL_CEWI;
00127 
00128   nco_bool FILE_RETRIEVED_FROM_REMOTE_LOCATION;
00129   nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
00130   nco_bool FORCE_APPEND=False; /* Option A */
00131   nco_bool FORCE_OVERWRITE=False; /* Option O */
00132   nco_bool HISTORY_APPEND=True; /* Option h */
00133   nco_bool OUTPUT_TO_NEW_NETCDF_FILE=False;
00134   nco_bool REMOVE_REMOTE_FILES_AFTER_PROCESSING=True; /* Option R */
00135   
00136   char **fl_lst_abb=NULL; /* Option n */
00137   char **fl_lst_in;
00138   char *aed_arg[NC_MAX_ATTRS];
00139   char *cmd_ln;
00140   char *fl_in=NULL;
00141   char *fl_out=NULL; /* Option o */
00142   char *fl_pth=NULL; /* Option p */
00143   char *fl_pth_lcl=NULL; /* Option l */
00144   char *opt_crr=NULL; /* [sng] String representation of current long-option name */
00145   char *time_bfr_srt;
00146 
00147   const char * const CVS_Id="$Id: ncatted.c,v 1.93 2006/02/26 07:41:55 zender Exp $"; 
00148   const char * const CVS_Revision="$Revision: 1.93 $";
00149   const char * const opt_sht_lst="4Aa:D:hl:Oo:p:Rr-:";
00150   
00151   extern char *optarg;
00152   extern int optind;
00153   
00154   int abb_arg_nbr=0;
00155   int fl_nbr=0;
00156   int idx;
00157   int idx_var;
00158   int nbr_aed=0; /* Option a. NB: nbr_var_aed gets incremented */
00159   int nbr_var_fl;
00160   int nc_id;  
00161   int ncopen_mode=NC_WRITE; /* [enm] Mode flag for nco_open() call */
00162   int opt;
00163   int rcd=NC_NOERR; /* [rcd] Return code */
00164 
00165   size_t hdr_pad=0UL; /* [B] Pad at end of header section */
00166 
00167   time_t time_crr_time_t;
00168 
00169   static struct option opt_lng[]=
00170     { /* Structure ordered by short option key if possible */
00171       /* Long options with no argument, no short option counterpart */
00172       /* Long options with argument, no short option counterpart */
00173       {"hdr_pad",required_argument,0,0},
00174       {"header_pad",required_argument,0,0},
00175       /* Long options with short counterparts */
00176       {"append",no_argument,0,'A'},
00177       {"attribute",required_argument,0,'a'},
00178       {"debug",required_argument,0,'D'},
00179       {"dbg_lvl",required_argument,0,'D'},
00180       {"history",no_argument,0,'h'},
00181       {"hst",no_argument,0,'h'},
00182       {"local",required_argument,0,'l'},
00183       {"lcl",required_argument,0,'l'},
00184       {"overwrite",no_argument,0,'O'},
00185       {"ovr",no_argument,0,'O'},
00186       {"output",required_argument,0,'o'},
00187       {"fl_out",required_argument,0,'o'},
00188       {"path",required_argument,0,'p'},
00189       {"retain",no_argument,0,'R'},
00190       {"rtn",no_argument,0,'R'},
00191       {"version",no_argument,0,'r'},
00192       {"vrs",no_argument,0,'r'},
00193       {"help",no_argument,0,'?'},
00194       {0,0,0,0}
00195     }; /* end opt_lng */
00196   int opt_idx=0; /* Index of current long option into opt_lng array */
00197 
00198   /* Start clock and save command line */ 
00199   cmd_ln=nco_cmd_ln_sng(argc,argv);
00200   time_crr_time_t=time((time_t *)NULL);
00201   time_bfr_srt=ctime(&time_crr_time_t); time_bfr_srt=time_bfr_srt; /* Avoid compiler warning until variable is used for something */
00202   
00203   /* Get program name and set program enum (e.g., prg=ncra) */
00204   prg_nm=prg_prs(argv[0],&prg);
00205 
00206   /* Parse command line arguments */
00207   while(1){
00208     /* getopt_long_only() allows one dash to prefix long options */
00209     opt=getopt_long(argc,argv,opt_sht_lst,opt_lng,&opt_idx);
00210     /* NB: access to opt_crr is only valid when long_opt is detected */
00211     if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */
00212     opt_crr=(char *)strdup(opt_lng[opt_idx].name);
00213 
00214     /* Process long options without short option counterparts */
00215     if(opt == 0){
00216       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")) hdr_pad=strtoul(optarg,(char **)NULL,10);
00217     } /* opt != 0 */
00218     /* Process short options */
00219     switch(opt){
00220     case 0: /* Long options have already been processed, return */
00221       break;
00222     case 'A': /* Toggle FORCE_APPEND */
00223       FORCE_APPEND=!FORCE_APPEND;
00224       break;
00225     case 'a': /* Copy argument for later processing */
00226       aed_arg[nbr_aed]=(char *)strdup(optarg);
00227       nbr_aed++;
00228       break;
00229     case 'D': /* Debugging level. Default is 0. */
00230       dbg_lvl=(unsigned short)strtol(optarg,(char **)NULL,10);
00231       break;
00232     case 'h': /* Toggle appending to history global attribute */
00233       HISTORY_APPEND=!HISTORY_APPEND;
00234       break;
00235     case 'l': /* Local path prefix for files retrieved from remote file system */
00236       fl_pth_lcl=(char *)strdup(optarg);
00237       break;
00238     case 'O': /* Toggle FORCE_OVERWRITE */
00239       FORCE_OVERWRITE=!FORCE_OVERWRITE;
00240       break;
00241     case 'o': /* Name of output file */
00242       fl_out=(char *)strdup(optarg);
00243       break;
00244     case 'p': /* Common file path */
00245       fl_pth=(char *)strdup(optarg);
00246       break;
00247     case 'R': /* Toggle removal of remotely-retrieved-files. Default is True. */
00248       REMOVE_REMOTE_FILES_AFTER_PROCESSING=!REMOVE_REMOTE_FILES_AFTER_PROCESSING;
00249       break;
00250     case 'r': /* Print CVS program information and copyright notice */
00251       (void)copyright_prn(CVS_Id,CVS_Revision);
00252       (void)nco_lbr_vrs_prn();
00253       nco_exit(EXIT_SUCCESS);
00254       break;
00255     case '?': /* Print proper usage */
00256       (void)nco_usg_prn();
00257       nco_exit(EXIT_SUCCESS);
00258       break;
00259     case '-': /* Long options are not allowed */
00260       (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",prg_nm_get());
00261       nco_exit(EXIT_FAILURE);
00262       break;
00263     default: /* Print proper usage */
00264       (void)nco_usg_prn();
00265       nco_exit(EXIT_FAILURE);
00266     } /* end switch */
00267     if(opt_crr != NULL) opt_crr=(char *)nco_free(opt_crr);
00268   } /* end while loop */
00269   
00270   /* Process positional arguments and fill in filenames */
00271   fl_lst_in=nco_fl_lst_mk(argv,argc,optind,&fl_nbr,&fl_out,&FL_LST_IN_FROM_STDIN);
00272   if(fl_out != NULL) OUTPUT_TO_NEW_NETCDF_FILE=True; else fl_out=(char *)strdup(fl_lst_in[0]);
00273 
00274   if(nbr_aed == 0){
00275     (void)fprintf(stdout,"%s: ERROR must specify an attribute to edit\n",prg_nm);
00276     nco_usg_prn();
00277     nco_exit(EXIT_FAILURE);
00278   } /* end if */ 
00279 
00280   /* Make uniform list of user-specified attribute edit structures */
00281   if(nbr_aed > 0) aed_lst=nco_prs_aed_lst(nbr_aed,aed_arg);
00282 
00283   /* We now have final list of attributes to edit */
00284   
00285   /* Parse filename */
00286   fl_in=nco_fl_nm_prs(fl_in,0,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth);
00287   /* Make sure file is on local system and is readable or die trying */
00288   fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION);
00289 
00290   if(OUTPUT_TO_NEW_NETCDF_FILE){
00291 
00292     if(!FORCE_OVERWRITE){
00293       int rcd_lcl;
00294       struct stat stat_sct;
00295 
00296       rcd_lcl=stat(fl_out,&stat_sct);
00297 
00298       /* If file already exists, then query user whether to overwrite */
00299       if(rcd_lcl != -1){
00300         char usr_reply;
00301         
00302         usr_reply='z';
00303         while(usr_reply != 'n' && usr_reply != 'y'){
00304           (void)fprintf(stdout,"ncrename: overwrite %s (y/n)? ",fl_out);
00305           (void)fflush(stdout);
00306           usr_reply=(char)fgetc(stdin);
00307         } /* end while */
00308         
00309         if(usr_reply == 'n'){
00310           nco_exit(EXIT_SUCCESS);
00311         } /* end if */
00312       } /* end if */
00313     } /* end if */
00314     
00315     /* Copy input file to output file, then search through output, editing attributes along the way
00316        This avoids possible XDR translation performance penalty copying each variable with netCDF */
00317     (void)nco_fl_cp(fl_in,fl_out);
00318   } /* end if */
00319 
00320   /* Open file. Writing must be enabled and file should be in define mode for renaming */
00321   if(dbg_lvl == 8) ncopen_mode|=NC_SHARE;
00322   rcd=nco_open(fl_out,ncopen_mode,&nc_id);
00323   (void)nco_redef(nc_id);
00324 
00325   /* Get number of variables in file */
00326   (void)nco_inq(nc_id,(int *)NULL,&nbr_var_fl,(int *)NULL,(int *)NULL);
00327 
00328   for(idx=0;idx<nbr_aed;idx++){
00329 
00330     if(aed_lst[idx].var_nm != NULL){
00331 
00332       /* Is this a global attribute? */
00333       if(!strcmp(aed_lst[idx].var_nm,"global")) aed_lst[idx].id=NC_GLOBAL; else (void)nco_inq_varid(nc_id,aed_lst[idx].var_nm,&aed_lst[idx].id);
00334 
00335       /* Edit attribute */
00336       (void)nco_aed_prc(nc_id,aed_lst[idx].id,aed_lst[idx]);
00337 
00338     }else{ /* var_nm == NULL */
00339       /* Perform operation for every variable for which it makes sense */
00340       
00341       /* Edit attribute for every variable */
00342       for(idx_var=0;idx_var<nbr_var_fl;idx_var++) 
00343         (void)nco_aed_prc(nc_id,idx_var,aed_lst[idx]);
00344 
00345     } /* end else var_nm == NULL */
00346 
00347   } /* end loop over idx */
00348   
00349   /* Catenate the timestamped command line to the "history" global attribute */
00350   if(HISTORY_APPEND) (void)nco_hst_att_cat(nc_id,cmd_ln);
00351   
00352   /* Take output file out of define mode */
00353   if(hdr_pad == 0UL){
00354     (void)nco_enddef(nc_id);
00355   }else{
00356     (void)nco__enddef(nc_id,hdr_pad);
00357     if(dbg_lvl > 1) (void)fprintf(stderr,"%s: INFO Padding header with %lu extra bytes \n",prg_nm_get(),(unsigned long)hdr_pad);
00358   } /* hdr_pad */
00359     
00360   /* Close the open netCDF file */
00361   nco_close(nc_id);
00362   
00363   /* Remove local copy of file */
00364   if(FILE_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in);
00365 
00366   /* ncatted-unique memory */
00367   for(idx=0;idx<nbr_aed;idx++) aed_arg[idx]=(char *)nco_free(aed_arg[idx]);
00368   for(idx=0;idx<nbr_aed;idx++){
00369     if(aed_lst[idx].att_nm != NULL) aed_lst[idx].att_nm=(char *)nco_free(aed_lst[idx].att_nm);
00370     if(aed_lst[idx].var_nm != NULL) aed_lst[idx].var_nm=(char *)nco_free(aed_lst[idx].var_nm);
00371     aed_lst[idx].val.vp=(void *)nco_free(aed_lst[idx].val.vp);
00372   } /* end for */
00373   if(nbr_aed > 0) aed_lst=(aed_sct *)nco_free(aed_lst);
00374 
00375   /* NCO-generic clean-up */
00376   /* Free individual strings/arrays */
00377   if(cmd_ln != NULL) cmd_ln=(char *)nco_free(cmd_ln);
00378   if(fl_in != NULL) fl_in=(char *)nco_free(fl_in);
00379   if(fl_out != NULL) fl_out=(char *)nco_free(fl_out);
00380   if(fl_pth != NULL) fl_pth=(char *)nco_free(fl_pth);
00381   if(fl_pth_lcl != NULL) fl_pth_lcl=(char *)nco_free(fl_pth_lcl);
00382   /* Free lists of strings */
00383   if(fl_lst_in != NULL && fl_lst_abb == NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,fl_nbr); 
00384   if(fl_lst_in != NULL && fl_lst_abb != NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,1);
00385   if(fl_lst_abb != NULL) fl_lst_abb=nco_sng_lst_free(fl_lst_abb,abb_arg_nbr);
00386 
00387   if(rcd != NC_NOERR) nco_err_exit(rcd,"main");
00388   nco_exit_gracefully();
00389   return EXIT_SUCCESS;
00390 } /* end main() */


Generated on Thu Mar 16 18:14:40 2006 for nco by  doxygen 1.4.4