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 }