city_generator2

Generated conformal 3D meshes representing a city
git clone git://git.meso-star.fr/city_generator2.git
Log | Files | Refs | README | LICENSE

cg_args.c (8534B)


      1 /* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
      2  * Copyright (C) 2022 CNRS
      3  * Copyright (C) 2022 Sorbonne Université
      4  * Copyright (C) 2022 Université Paul Sabatier
      5  * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
      6  *
      7  * This program is free software: you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License as published by
      9  * the Free Software Foundation, either version 3 of the License, or
     10  * (at your option) any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     15  * GNU General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU General Public License
     18  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     19 
     20 #include "cg_args.h"
     21 #include "cg_catalog_parsing.h"
     22 #include "cg_default.h"
     23 #include "cg_version.h"
     24 #include "cg_default.h"
     25 #include "cg.h"
     26 
     27 #include <rsys/rsys.h>
     28 #include <rsys/logger.h>
     29 #include <rsys/cstr.h>
     30 
     31 #include <getopt.h>
     32 #include <stdio.h>
     33 
     34 void
     35 print_version(void)
     36 {
     37   printf(
     38     "city-generator2 version %i.%i.%i\n",
     39     CG2_VERSION_MAJOR, CG2_VERSION_MINOR, CG2_VERSION_PATCH);
     40 }
     41 
     42 void
     43 short_help(void)
     44 {
     45 #ifndef NDEBUG
     46   printf("Running debug binary.\n");
     47 #endif
     48 
     49   print_version();
     50   printf("\nUsage:\n"
     51      "city_generator2 -m <FILENAME> {-c <FILENAME>}+ [-%c] [-s] [-V verbosity] [-k] [-f <NAME>] [-F <level>] [-E]\n"
     52      "city_generator2 [-h]\n"
     53      "city_generator2 [-v]\n",
     54       CG2_ARGS_CHANGE_BINARY_DEFAULT_OPTION
     55      );
     56   printf(
     57       "\nMandatory options\n"
     58       "-----------------\n"
     59       "-m <city_map_filename>\n"
     60       " Read a yaml file that describes the city map.\n"
     61       "-c <filename>\n"
     62       " Read a yaml file containing datasets for a given construction mode.\n"
     63       " Can be used more than once.\n"
     64       "\nOther options\n"
     65       "-------------\n"
     66       "-h\n"
     67       " Print this help and exit.\n"
     68       "-%c\n"
     69       " Set the format of output files to "STR(CG2_ARGS_STL_NON_DEFAULT_STR)
     70       " (default "STR(CG2_ARGS_STL_DEFAULT_STR)").\n"
     71       "-k\n"
     72       " Keep running on errors.\n"
     73       "-E\n"
     74       " Don't use escape characters in logs.\n"
     75       " Use as first option to avoid escape characters in initial log messages.\n"
     76       "-f <NAME>\n"
     77       " Dump the footprint of the building with the given name.\n"
     78       " Can be used more than once.\n"
     79       "-F <level>\n"
     80       " Dump the footprint of some buildings, depending on level:\n"
     81       " - With level 1 dump the footprint of any building not generated due to an error.\n"
     82       " - With level 2 dump the footprint of any building.\n"
     83       " Process the whole file regardless of errors, and exit if any error was found unless -k is used.\n"
     84       "-s\n"
     85       " Force single threaded execution. By default use as many threads as available.\n"
     86       "-v\n"
     87       " Print the software version and exit.\n"
     88       "-V <LEVEL>\n"
     89       " Set the verbosity level (default %i)\n",
     90       CG2_ARGS_CHANGE_BINARY_DEFAULT_OPTION,
     91       CG2_ARGS_DEFAULT_VERBOSITY_LEVEL
     92   );
     93   printf(
     94       "\nCopyright (C) 2022-2023 Université de Pau et des Pays de l'Adour UPPA.\n"
     95       "Copyright (C) 2022-2023 CNRS.\n"
     96       "Copyright (C) 2022-2023 Sorbonne Université.\n"
     97       "Copyright (C) 2022-2023 Université Paul Sabatier.\n"
     98       "Copyright (C) 2022-2023 |Meso|Star> (contact@meso-star.com).\n"
     99       "city_generator2 is free software released under the GNU GPL license,\n"
    100       "version 3 or later.\n"
    101       "You are free to change or redistribute it under certain conditions\n"
    102       "<http://gnu.org/licenses/gpl.html>.\n");
    103 }
    104 
    105 res_T
    106 parse_args
    107   (struct mem_allocator* allocator,
    108    struct logger* logger,
    109    int argc,
    110    char** argv,
    111    struct args** out_args)
    112 {
    113   res_T res = RES_OK;
    114   int opt;
    115   int info_provided = 0, c_provided = 0, m_provided = 0, s_provided = 0;
    116   struct args* args;
    117   char option_list[] = "?c:m:hkEF:f:s:vV:1";
    118 
    119   ASSERT(allocator && logger && argv && out_args);
    120 
    121   /* Patch option_list[] according to stl format default */
    122   option_list[0] = CG2_ARGS_CHANGE_BINARY_DEFAULT_OPTION;
    123 
    124   args = MEM_CALLOC(allocator, 1, sizeof(*args));
    125   if(!args) {
    126     res = RES_MEM_ERR;
    127     goto error;
    128   }
    129 
    130   args->allocator = allocator;
    131   args->logger = logger;
    132   darray_names_init(allocator, &args->catalog_files);
    133   darray_names_init(allocator, &args->dump_footprint_names);
    134 
    135   /* Set non-zero default values */
    136   args->binary_export = CG2_ARGS_BINARY_STL_DEFAULT;
    137   args->verbosity_level = CG2_ARGS_DEFAULT_VERBOSITY_LEVEL;
    138   args->stardis_basename = CG2_ARGS_DEFAULT_STARDIS_FILES_BASENAME;
    139 
    140   opterr = 0; /* No default error messages */
    141   while((opt = getopt(argc, argv, option_list)) != -1) {
    142     const char* name;
    143     switch (opt) {
    144 
    145       case '?': /* Unrecognized option */
    146       {
    147         char* ptr = strchr(option_list, optopt);
    148         if(ptr && ptr[1] == ':') {
    149           logger_print(logger, LOG_ERROR,
    150             "Missing argument for option -%c\n",
    151             optopt);
    152         } else {
    153           logger_print(logger, LOG_ERROR, "Invalid option -%c.\n", optopt);
    154         }
    155         res = RES_BAD_ARG;
    156         goto error;
    157       }
    158 
    159       case 'c':
    160         c_provided = 1;
    161         name = optarg;
    162         ERR(darray_names_push_back(&args->catalog_files, &name));
    163         break;
    164 
    165       case 'm':
    166         if(m_provided) {
    167           logger_print(logger, LOG_ERROR, "Option -%c provided twice.\n", opt);
    168           res = RES_BAD_ARG;
    169           goto error;
    170         }
    171         args->city_filename = optarg;
    172         m_provided = 1;
    173         break;
    174 
    175       case CG2_ARGS_CHANGE_BINARY_DEFAULT_OPTION:
    176         args->binary_export = !CG2_ARGS_BINARY_STL_DEFAULT;
    177         break;
    178 
    179      /* Optional */
    180 
    181       case 'E':
    182         args->no_escape = 1;
    183         /* Immediate effect on logs */
    184         logger_set_stream(logger, LOG_OUTPUT, log_prt_fn_ne, NULL);
    185         logger_set_stream(logger, LOG_WARNING, log_warn_fn_ne, NULL);
    186         logger_set_stream(logger, LOG_ERROR, log_err_fn_ne, NULL);
    187         break;
    188 
    189       case 'F':
    190         res = cstr_to_int(optarg, &args->dump_footprints_level);
    191         if(res != RES_OK
    192             || args->dump_footprints_level < 1 || args->dump_footprints_level > 2)
    193         {
    194           if(res == RES_OK) res = RES_BAD_ARG;
    195           logger_print(logger, LOG_ERROR, "Invalid arg for option %c: '%s'.\n",
    196               opt, optarg);
    197           goto error;
    198         }
    199         break;
    200 
    201       case 'f':
    202         name = optarg;
    203         ERR(darray_names_push_back(&args->dump_footprint_names, &name));
    204         break;
    205 
    206       case 'h':
    207         info_provided = 1;
    208         args->print_help = 1;
    209         break;
    210 
    211       case 'k':
    212         args->keep_running_on_errors = 1;
    213         break;
    214 
    215       case 's':
    216         if(s_provided) {
    217           logger_print(logger, LOG_ERROR, "Option -%c provided twice.\n", opt);
    218           res = RES_BAD_ARG;
    219           goto error;
    220         }
    221         args->stardis_basename = optarg;
    222         s_provided = 1;
    223         break;
    224 
    225       case 'v':
    226         info_provided = 1;
    227         args->print_version = 1;
    228         break;
    229 
    230       case 'V':
    231         res = cstr_to_int(optarg, &args->verbosity_level);
    232         if(res != RES_OK
    233           || args->verbosity_level < 0
    234           || args->verbosity_level > 3)
    235         {
    236           if(res == RES_OK) res = RES_BAD_ARG;
    237           logger_print(logger, LOG_ERROR,
    238             "Invalid argument for option -%c: %s\n",
    239             opt, optarg);
    240           goto error;
    241         }
    242         break;
    243 
    244       case '1':
    245         args->single_thread = 1;
    246         break;
    247     }
    248   }
    249 
    250   if(argc > optind) {
    251     int i;
    252     for(i = optind; i < argc; i++) {
    253       logger_print(logger, LOG_ERROR, "Unexpected argument: %s.\n", argv[i]);
    254     }
    255     res = RES_BAD_ARG;
    256     goto error;
    257   }
    258 
    259   if(!c_provided && !info_provided) {
    260     ERR(logger_print(logger, LOG_ERROR,
    261         "Missing mandatory argument: -c <construction_mode_filename>\n"));
    262     res = RES_BAD_ARG;
    263     goto error;
    264   }
    265 
    266   if(!m_provided && !info_provided) {
    267     ERR(logger_print(logger, LOG_ERROR,
    268         "Missing mandatory argument: -m <city_filename>\n"));
    269     res = RES_BAD_ARG;
    270     goto error;
    271   }
    272 
    273 exit:
    274   *out_args = args;
    275   return res;
    276 error:
    277   release_args(args);
    278   args = NULL;
    279   goto exit;
    280 }
    281 
    282 void
    283 release_args
    284   (struct args* args)
    285 {
    286   if(!args) return;
    287 
    288   darray_names_release(&args->catalog_files);
    289   darray_names_release(&args->dump_footprint_names);
    290   MEM_RM(args->allocator, args);
    291 }