star-meteo

Time varying meteorological data
git clone git://git.meso-star.fr/star-meteo.git
Log | Files | Refs | README | LICENSE

smeteo_main.c (3972B)


      1 /* Copyright (C) 2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redismeteobute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is dismeteobuted in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #define _POSIX_C_SOURCE 200112L /* getopt support */
     17 
     18 #include "smeteo.h"
     19 
     20 #include <rsys/mem_allocator.h>
     21 
     22 #include <stdio.h>
     23 #include <unistd.h> /* getopt */
     24 
     25 struct args {
     26   char* const* filenames; /* Path toward the files storing meteo data */
     27   int nfiles; /* Number of input files */
     28   int verbose; /* Verbosity level */
     29   int quit;
     30 };
     31 static const struct args ARGS_DEFAULT = {NULL, 0, 0, 0};
     32 
     33 struct cmd {
     34   struct args args;
     35   struct smeteo* smeteo;
     36 };
     37 static const struct cmd CMD_NULL = {0};
     38 
     39 /*******************************************************************************
     40  * Helper functions
     41  ******************************************************************************/
     42 static INLINE void
     43 usage(FILE* stream)
     44 {
     45   fprintf(stream, "usage: smeteo [-hv] [file ...]\n");
     46 }
     47 
     48 static res_T
     49 args_init(struct args* args, int argc, char** argv)
     50 {
     51   int opt = 0;
     52   res_T res = RES_OK;
     53 
     54   *args = ARGS_DEFAULT;
     55 
     56   while((opt = getopt(argc, argv, "hv")) != -1) {
     57     switch(opt) {
     58       case 'h':
     59         usage(stdout);
     60         args->quit = 1;
     61         goto exit;
     62       case 'v': args->verbose += (args->verbose < 3); break;
     63       default: res = RES_BAD_ARG; break;
     64     }
     65     if(res != RES_OK) goto error;
     66   }
     67 
     68   args->filenames = argv + optind;
     69   args->nfiles = argc - optind;
     70 
     71 exit:
     72   return res;
     73 error:
     74   usage(stderr);
     75   goto exit;
     76 }
     77 
     78 static INLINE void
     79 cmd_release(struct cmd* cmd)
     80 {
     81   if(cmd->smeteo) SMETEO(ref_put(cmd->smeteo));
     82 }
     83 
     84 static res_T
     85 cmd_init(struct cmd* cmd, const struct args* args)
     86 {
     87   struct smeteo_create_args smeteo_args = SMETEO_CREATE_ARGS_DEFAULT;
     88   res_T res = RES_OK;
     89   ASSERT(cmd && args);
     90 
     91   cmd->args = *args;
     92 
     93   smeteo_args.verbose = args->verbose;
     94   res = smeteo_create(&smeteo_args, &cmd->smeteo);
     95   if(res != RES_OK) goto error;
     96 
     97 exit:
     98   return res;
     99 error:
    100   cmd_release(cmd);
    101   goto exit;
    102 }
    103 
    104 static INLINE void
    105 print_info(struct cmd* cmd)
    106 {
    107   struct smeteo_desc desc = SMETEO_DESC_NULL;
    108   ASSERT(cmd);
    109 
    110   SMETEO(get_desc(cmd->smeteo, &desc));
    111   printf("%f %f %f %lu %s\n",
    112     desc.albedo, desc.longitude, desc.latitude, desc.nentries, desc.filename);
    113 }
    114 
    115 static res_T
    116 cmd_run(struct cmd* cmd)
    117 {
    118   res_T res = RES_OK;
    119   ASSERT(cmd);
    120 
    121   if(!cmd->args.nfiles) {
    122     /* Read input data from standard input */
    123     res = smeteo_load_stream(cmd->smeteo, stdin, "stdin");
    124     if(res != RES_OK) goto error;
    125 
    126     print_info(cmd);
    127 
    128   } else {
    129     /* Load provided input files */
    130     int i = 0;
    131     FOR_EACH(i, 0, cmd->args.nfiles) {
    132       res = smeteo_load(cmd->smeteo, cmd->args.filenames[i]);
    133       if(res != RES_OK) goto error;
    134 
    135       print_info(cmd);
    136     }
    137   }
    138 
    139 exit:
    140   return res;
    141 error:
    142   goto exit;
    143 }
    144 
    145 /*******************************************************************************
    146  * The program
    147  ******************************************************************************/
    148 int
    149 main(int argc, char** argv)
    150 {
    151   struct args args = ARGS_DEFAULT;
    152   struct cmd cmd = CMD_NULL;
    153   int err = 0;
    154   res_T res = RES_OK;
    155 
    156   if((res = args_init(&args, argc, argv)) != RES_OK) goto error;
    157   if(args.quit) goto exit;
    158 
    159   if((res = cmd_init(&cmd, &args)) != RES_OK) goto error;
    160   if((res = cmd_run(&cmd)) != RES_OK) goto error;
    161 
    162 exit:
    163   cmd_release(&cmd);
    164   CHK(mem_allocated_size() == 0);
    165   return err;
    166 error:
    167   err = 1;
    168   goto exit;
    169 }