star-mesh

Define and load a binary data format for meshes
git clone git://git.meso-star.fr/star-mesh.git
Log | Files | Refs | README | LICENSE

smsh-desc.c (5305B)


      1 /* Copyright (C) 2020-2023, 2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute 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 distributed 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 "smsh.h"
     19 
     20 #include <rsys/cstr.h>
     21 #include <rsys/mem_allocator.h>
     22 #include <rsys/str.h>
     23 
     24 #include <errno.h>
     25 #include <unistd.h> /* getopt */
     26 
     27 enum query_flag {
     28   QUERY_DCELL = BIT(0),
     29   QUERY_DNODE = BIT(1),
     30   QUERY_NCELLS = BIT(2),
     31   QUERY_NNODES = BIT(3),
     32   QUERY_PAGESIZE = BIT(4),
     33   QUERY_ALL = ~0
     34 };
     35 
     36 /* Input arguments */
     37 struct args {
     38   const char* mesh;
     39   int query_mask; /* Cmbination of query flag */
     40 };
     41 static const struct args ARGS_DEFAULT = {0};
     42 
     43 /* Command data */
     44 struct cmd {
     45   struct args args;
     46   struct smsh* mesh; /* Tetrahedral mesh */
     47   uint64_t pagesize;
     48 };
     49 static const struct cmd CMD_NULL = {0};
     50 
     51 /*******************************************************************************
     52  * Helper functions
     53  ******************************************************************************/
     54 static INLINE void
     55 usage(FILE* stream)
     56 {
     57   fprintf(stream, "usage: smsh-desc [-cdnpt] mesh\n");
     58 }
     59 
     60 static res_T
     61 args_init(struct args* args, const int argc, char** argv)
     62 {
     63   int opt = 0;
     64   res_T res = RES_OK;
     65 
     66   *args = ARGS_DEFAULT;
     67 
     68   while((opt = getopt(argc, argv, "cdnpqt")) != -1) {
     69     switch(opt) {
     70       case 'c': args->query_mask |= QUERY_NCELLS; break;
     71       case 'd': args->query_mask |= QUERY_DNODE; break;
     72       case 'n': args->query_mask |= QUERY_NNODES; break;
     73       case 'p': args->query_mask |= QUERY_PAGESIZE; break;
     74       case 't': args->query_mask |= QUERY_DCELL; break;
     75       default: res = RES_BAD_ARG;
     76     }
     77     if(res != RES_OK) goto error;
     78   }
     79 
     80   if(optind < argc) args->mesh = argv[optind];
     81 
     82   /* By default, query all */
     83   if(!args->query_mask) args->query_mask = QUERY_ALL;
     84 
     85   if(!args->mesh) {
     86     fprintf(stderr, "mesh is missing\n");
     87     res = RES_BAD_ARG;
     88     goto error;
     89   }
     90 
     91 exit:
     92   return res;
     93 error:
     94   usage(stderr);
     95   goto exit;
     96 }
     97 
     98 static res_T
     99 setup_mesh(struct cmd* cmd, const struct args* args)
    100 {
    101   struct smsh_create_args create_args = SMSH_CREATE_ARGS_DEFAULT;
    102   struct smsh_load_args load_args = SMSH_LOAD_ARGS_NULL;
    103   FILE* fp = NULL;
    104   res_T res = RES_OK;
    105   ASSERT(cmd && args);
    106 
    107   if(!(fp = fopen(args->mesh, "r"))) {
    108     fprintf(stderr, "%s: %s\n", args->mesh, strerror(errno));
    109     res = RES_IO_ERR;
    110     goto error;
    111   }
    112   if(fread(&cmd->pagesize, sizeof(uint64_t), 1, fp) != 1) {
    113     fprintf(stderr, "%s: %s\n", args->mesh, strerror(errno));
    114     res = RES_IO_ERR;
    115     goto error;
    116   }
    117 
    118   create_args.verbose = 1;
    119   if((res = smsh_create(&create_args, &cmd->mesh)) != RES_OK) goto error;
    120 
    121   load_args.path = args->mesh;
    122   if((res = smsh_load(cmd->mesh, &load_args)) != RES_OK) goto error;
    123 
    124 exit:
    125   if(fp) CHK(fclose(fp) == 0);
    126   return res;
    127 error:
    128   if(cmd->mesh) { SMSH(ref_put(cmd->mesh)); cmd->mesh = NULL; }
    129   goto exit;
    130 }
    131 
    132 static void
    133 cmd_release(struct cmd* cmd)
    134 {
    135   ASSERT(cmd);
    136   if(cmd->mesh) SMSH(ref_put(cmd->mesh));
    137 }
    138 
    139 static res_T
    140 cmd_init(struct cmd* cmd, const struct args* args)
    141 {
    142   res_T res = RES_OK;
    143   ASSERT(cmd && args && args->query_mask);
    144 
    145   if((res = setup_mesh(cmd, args)) != RES_OK) goto error;
    146   cmd->args = *args;
    147 
    148 exit:
    149   return res;
    150 error:
    151   cmd_release(cmd);
    152   goto exit;
    153 }
    154 
    155 static res_T
    156 cmd_run(struct cmd* cmd)
    157 {
    158   struct smsh_desc desc = SMSH_DESC_NULL;
    159   struct str str;
    160   res_T res = RES_OK;
    161   ASSERT(cmd);
    162 
    163   str_init(NULL, &str);
    164   SMSH(get_desc(cmd->mesh, &desc));
    165 
    166   #define APPEND(Fmt, Val) { \
    167     if((res = str_append_printf(&str, Fmt, (Val))) != RES_OK) goto error; \
    168   } (void)0
    169   if(cmd->args.query_mask & QUERY_PAGESIZE) APPEND("%zu ", cmd->pagesize);
    170   if(cmd->args.query_mask & QUERY_NNODES) APPEND("%zu ", desc.nnodes);
    171   if(cmd->args.query_mask & QUERY_NCELLS) APPEND("%zu ", desc.ncells);
    172   if(cmd->args.query_mask & QUERY_DNODE) APPEND("%u ", desc.dnode);
    173   if(cmd->args.query_mask & QUERY_DCELL) APPEND("%u ", desc.dcell);
    174   APPEND("%s", cmd->args.mesh);
    175   #undef APPEND
    176 
    177   printf("%s\n", str_cget(&str));
    178 
    179 exit:
    180   str_release(&str);
    181   return res;
    182 error:
    183   fprintf(stderr, "error: %s\n", res_to_cstr(res));
    184   goto exit;
    185 }
    186 
    187 /*******************************************************************************
    188  * The program
    189  ******************************************************************************/
    190 int
    191 main(int argc, char** argv)
    192 {
    193   struct args args = ARGS_DEFAULT;
    194   struct cmd cmd = CMD_NULL;
    195   int err = 0;
    196   res_T res = RES_OK;
    197 
    198   if((res = args_init(&args, argc, argv)) != RES_OK) goto error;
    199   if((res = cmd_init(&cmd, &args)) != RES_OK) goto error;
    200   if((res = cmd_run(&cmd)) != RES_OK) goto error;
    201 
    202 exit:
    203   cmd_release(&cmd);
    204   CHK(mem_allocated_size() == 0);
    205   return err;
    206 error:
    207   err = 1;
    208   goto exit;
    209 }