sphin_lint.c (4087B)
1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique 2 * Copyright (C) 2024-2026 Clermont Auvergne INP 3 * Copyright (C) 2024-2026 INSA Lyon 4 * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux 5 * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse 6 * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com) 7 * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com) 8 * Copyright (C) 2024-2026 Université de Lorraine 9 * Copyright (C) 2024-2026 Université Paul Sabatier 10 * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24 25 #define _POSIX_C_SOURCE 200112L /* for getopt support */ 26 27 #include "sphin.h" 28 29 #include <rsys/cstr.h> 30 #include <rsys/mem_allocator.h> 31 #include <rsys/rsys.h> 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <unistd.h> 36 37 struct args { 38 int verbose; /* Verbosity level. Bigger values => more verbosity */ 39 int quit; 40 char* filename; /* NULL => use stdin */ 41 }; 42 43 #define ARGS_DEFAULT__ {0, 0, NULL} 44 static const struct args ARGS_DEFAULT = ARGS_DEFAULT__; 45 46 static void 47 usage 48 (FILE* stream) 49 { 50 ASSERT(NULL != stream); 51 fprintf(stream, "Usage: sphin-lint [-hv] [file]\n"); 52 } 53 54 static res_T 55 parse_args 56 (struct args* args, int argc, char** argv) 57 { 58 int opt = 0; 59 res_T res = RES_OK; 60 61 ASSERT(NULL != args); 62 ASSERT(NULL != argv); 63 ASSERT(argc > 0); 64 65 *args = ARGS_DEFAULT; 66 67 while((opt = getopt(argc, argv, "hv")) != -1) { 68 switch(opt) { 69 case 'v': 70 /* Increase the verbosity level counter for each 'v' entered, up to a 71 * maximum of 3. We use the boolean value of (3 > args->verbose): if 72 * the condition is true, it evaluates to 1, increasing the counter. 73 * Otherwise, it evaluates to 0, leaving the counter unchanged. */ 74 args->verbose += (3 > args->verbose); 75 break; 76 case 'h': 77 usage(stdout); 78 args->quit = 1; 79 break; 80 default: 81 res = RES_BAD_ARG; 82 goto error; 83 } 84 if (RES_OK != res) { goto error; } 85 } 86 87 /* opting is a global variable that indexes the next argv to be processed */ 88 if (optind < argc) { /* True if not all the args have been processed */ 89 args->filename = argv[optind]; 90 } 91 92 exit: 93 return res; 94 error: 95 usage(stderr); 96 goto exit; 97 } 98 99 int 100 main(int argc, char** argv) 101 { 102 struct sphin* sphin = NULL; 103 struct sphin_config* config = NULL; 104 struct args args = ARGS_DEFAULT; /* Command line args */ 105 struct sphin_create_args sphin_args = SPHIN_CREATE_ARGS_DEFAULT; 106 size_t sz = 0; 107 int err = EXIT_SUCCESS; 108 res_T res = RES_OK; 109 110 /* Process command line args */ 111 res = parse_args(&args, argc, argv); 112 if (RES_OK != res) { goto error; } 113 if (1 == args.quit) { goto exit; } 114 115 /* Initialize sphin */ 116 sphin_args.verbose = args.verbose; 117 sphin_create(&sphin_args, &sphin); 118 119 /* Load stream */ 120 if (NULL != args.filename) { 121 res = sphin_load(sphin, args.filename, &config); 122 } 123 else { 124 res = sphin_load_stream(sphin, stdin, "stdin", &config); 125 } 126 if (RES_OK != res) { goto error; } 127 128 exit: 129 if (NULL != sphin) { SPHIN(ref_put(sphin)); } 130 if (NULL != config) { SPHIN(config_ref_put(config)); } 131 sz = mem_allocated_size(); 132 if (sz != 0) { 133 char buffer[64] = {0}; /* Initialize all fields to 0 */ 134 size_to_cstr(sz, SIZE_ALL, NULL, buffer, sizeof(buffer)); 135 fprintf(stderr, "Memory leaks: %s\n", buffer); 136 err = EXIT_FAILURE; 137 } 138 139 return err; 140 141 error: 142 err = EXIT_FAILURE; 143 goto exit; 144 }