1 /* 2 * Main program. 3 * 4 * Copyright (C) 2019, 2022, 2023 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 {"alignment", required_argument, NULL, 'A' }, 41 {"all", no_argument, NULL, 'a' }, 42 {"client", no_argument, NULL, 'c' }, 43 {"dir", required_argument, NULL, 'd' }, 44 {"files", no_argument, NULL, 'f' }, 45 {"headers", no_argument, NULL, 'h' }, 46 {"help", no_argument, NULL, '?' }, 47 {"interfaces", no_argument, NULL, 'i' }, 48 {"language", required_argument, NULL, 'l' }, 49 {"recursive", no_argument, NULL, 'R' }, 50 {"routines", no_argument, NULL, 'r' }, 51 {"server", no_argument, NULL, 's' }, 52 {"verbose", no_argument, NULL, 'v' }, 53 {"version", no_argument, NULL, 'V' }, 54 {0, 0, 0, 0 }, 55 }; 56 57 58 /* Main program, parsing indicated files or standard input. */ 59 60 int main(int argc, char *argv[]) 61 { 62 char *arg, *progname; 63 int option, index, selected_content = 0, selected_role = 0; 64 struct interface *iface; 65 66 #if YYDEBUG == 1 67 yydebug = 0; 68 #endif 69 70 /* The configuration structure is already initialised in config.c. */ 71 72 /* Accept various options. */ 73 74 while (1) 75 { 76 option = getopt_long(argc, argv, "A:acd:fhil:rRsvV?", long_options, NULL); 77 if (option == -1) 78 break; 79 80 switch (option) 81 { 82 /* Set alignment. */ 83 case 'A': 84 conf.alignment = atoi(optarg); 85 break; 86 87 /* Generate everything. */ 88 case 'a': 89 conf.client = 1; conf.server = 1; 90 conf.headers = 1; conf.interfaces = 1; conf.routines = 1; 91 selected_content = 1; 92 selected_role = 1; 93 break; 94 95 /* Select client output. */ 96 case 'c': 97 conf.client = 1; 98 selected_role = 1; 99 break; 100 101 /* Set output directory. */ 102 case 'd': 103 conf.output_dir = optarg; 104 break; 105 106 /* Only report processed file basenames. */ 107 case 'f': 108 conf.show_filenames = 1; 109 break; 110 111 /* Generate headers. */ 112 case 'h': 113 conf.headers = 1; 114 selected_content = 1; 115 break; 116 117 /* Generate interface headers. */ 118 case 'i': 119 conf.interfaces = 1; 120 selected_content = 1; 121 break; 122 123 /* Select output language. */ 124 case 'l': 125 if (!strcasecmp(optarg, "c")) 126 conf.language = C_LANGUAGE; 127 else if (!strcasecmp(optarg, "c++")) 128 conf.language = CPP_LANGUAGE; 129 else 130 { 131 fprintf(stderr, "Output language not recognised: %s\n", optarg); 132 return 1; 133 } 134 break; 135 136 /* Generate routines (definitions). */ 137 case 'r': 138 conf.routines = 1; 139 selected_content = 1; 140 break; 141 142 /* Also generate files associated with base interfaces. */ 143 case 'R': 144 conf.generate_all = 1; 145 break; 146 147 /* Select server output. */ 148 case 's': 149 conf.server = 1; 150 selected_role = 1; 151 break; 152 153 /* Verbose reporting. */ 154 case 'v': 155 conf.verbose = 1; 156 break; 157 158 /* Show version (defined in the Makefile) and exit. */ 159 case 'V': 160 puts(VERSION_INFORMATION); 161 return 0; 162 163 /* Show help and exit. */ 164 case '?': 165 progname = make_basename(argv[0]); 166 printf(help_text, progname); 167 free(progname); 168 return 0; 169 170 default: 171 return 1; 172 } 173 } 174 175 /* Without any output selection, enable all output of the given kind. */ 176 177 if (!selected_content) 178 { 179 conf.headers = 1; conf.interfaces = 1; conf.routines = 1; 180 } 181 182 if (!selected_role) 183 { 184 conf.client = 1; conf.server = 1; 185 } 186 187 /* Produce an error without any input files. */ 188 189 if (optind >= argc) 190 { 191 fputs("No input files.\n", stderr); 192 return 1; 193 } 194 195 /* Process named files. */ 196 197 for (index = optind; index < argc; index++) 198 { 199 arg = argv[index]; 200 201 /* Import each file for processing. */ 202 203 iface = import_file(arg, 1); 204 205 if (iface == NULL) 206 { 207 fprintf(stderr, "Could not process file: %s\n", arg); 208 return 1; 209 } 210 211 /* Summarise interfaces if requested. */ 212 213 if (conf.verbose) 214 show_interfaces(iface); 215 } 216 217 return 0; 218 }