1 /* 2 * Main program. 3 * 4 * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <getopt.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <strings.h> 27 #include "common.h" 28 #include "config.h" 29 #include "imports.h" 30 #include "summary.h" 31 #include "templates.h" 32 #include "version.h" 33 34 35 36 /* Option definitions. */ 37 38 static struct option long_options[] = { 39 /* long opt following var pointer short opt */ 40 {"all", no_argument, NULL, 'a' }, 41 {"client", no_argument, NULL, 'c' }, 42 {"dir", required_argument, NULL, 'd' }, 43 {"files", no_argument, NULL, 'f' }, 44 {"headers", no_argument, NULL, 'h' }, 45 {"help", no_argument, NULL, '?' }, 46 {"interfaces", no_argument, NULL, 'i' }, 47 {"language", required_argument, NULL, 'l' }, 48 {"recursive", no_argument, NULL, 'R' }, 49 {"routines", no_argument, NULL, 'r' }, 50 {"server", no_argument, NULL, 's' }, 51 {"verbose", no_argument, NULL, 'v' }, 52 {"version", no_argument, NULL, 'V' }, 53 {0, 0, 0, 0 }, 54 }; 55 56 57 /* Main program, parsing indicated files or standard input. */ 58 59 int main(int argc, char *argv[]) 60 { 61 char *arg, *progname; 62 int option, index, selected_content = 0, selected_role = 0; 63 struct interface *iface; 64 65 #if YYDEBUG == 1 66 yydebug = 0; 67 #endif 68 69 /* The configuration structure is already initialised in config.c. */ 70 71 /* Accept various options. */ 72 73 while (1) 74 { 75 option = getopt_long(argc, argv, "acd:fhil:rRsvV?", long_options, NULL); 76 if (option == -1) 77 break; 78 79 switch (option) 80 { 81 /* Generate everything. */ 82 case 'a': 83 conf.client = 1; conf.server = 1; 84 conf.headers = 1; conf.interfaces = 1; conf.routines = 1; 85 selected_content = 1; 86 selected_role = 1; 87 break; 88 89 /* Select client output. */ 90 case 'c': 91 conf.client = 1; 92 selected_role = 1; 93 break; 94 95 /* Set output directory. */ 96 case 'd': 97 conf.output_dir = optarg; 98 break; 99 100 /* Only report processed file basenames. */ 101 case 'f': 102 conf.show_filenames = 1; 103 break; 104 105 /* Generate headers. */ 106 case 'h': 107 conf.headers = 1; 108 selected_content = 1; 109 break; 110 111 /* Generate interface headers. */ 112 case 'i': 113 conf.interfaces = 1; 114 selected_content = 1; 115 break; 116 117 /* Select output language. */ 118 case 'l': 119 if (!strcasecmp(optarg, "c")) 120 conf.language = C_LANGUAGE; 121 else if (!strcasecmp(optarg, "c++")) 122 conf.language = CPP_LANGUAGE; 123 else 124 { 125 fprintf(stderr, "Output language not recognised: %s\n", optarg); 126 return 1; 127 } 128 break; 129 130 /* Generate routines (definitions). */ 131 case 'r': 132 conf.routines = 1; 133 selected_content = 1; 134 break; 135 136 /* Also generate files associated with base interfaces. */ 137 case 'R': 138 conf.generate_all = 1; 139 break; 140 141 /* Select server output. */ 142 case 's': 143 conf.server = 1; 144 selected_role = 1; 145 break; 146 147 /* Verbose reporting. */ 148 case 'v': 149 conf.verbose = 1; 150 break; 151 152 /* Show version (defined in the Makefile) and exit. */ 153 case 'V': 154 puts(VERSION_INFORMATION); 155 return 0; 156 157 /* Show help and exit. */ 158 case '?': 159 progname = make_basename(argv[0]); 160 printf(help_text, progname); 161 free(progname); 162 return 0; 163 164 default: 165 return 1; 166 } 167 } 168 169 /* Without any output selection, enable all output of the given kind. */ 170 171 if (!selected_content) 172 { 173 conf.headers = 1; conf.interfaces = 1; conf.routines = 1; 174 } 175 176 if (!selected_role) 177 { 178 conf.client = 1; conf.server = 1; 179 } 180 181 /* Produce an error without any input files. */ 182 183 if (optind >= argc) 184 { 185 fputs("No input files.\n", stderr); 186 return 1; 187 } 188 189 /* Process named files. */ 190 191 for (index = optind; index < argc; index++) 192 { 193 arg = argv[index]; 194 195 /* Import each file for processing. */ 196 197 iface = import_file(arg, 1); 198 199 if (iface == NULL) 200 { 201 fprintf(stderr, "Could not process file: %s\n", arg); 202 return 1; 203 } 204 205 /* Summarise interfaces if requested. */ 206 207 if (conf.verbose) 208 show_interfaces(iface); 209 } 210 211 return 0; 212 }