#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) |
|
|
|
|
||||||||||||
|
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() */
|
1.4.4