1169695Skan/* Dependency generator utility. 2169695Skan Copyright (C) 2004 Free Software Foundation, Inc. 3169695Skan Contributed by Zack Weinberg, May 2004 4169695Skan 5169695SkanThis program is free software; you can redistribute it and/or modify it 6169695Skanunder the terms of the GNU General Public License as published by the 7169695SkanFree Software Foundation; either version 2, or (at your option) any 8169695Skanlater version. 9169695Skan 10169695SkanThis program is distributed in the hope that it will be useful, 11169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of 12169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13169695SkanGNU General Public License for more details. 14169695Skan 15169695SkanYou should have received a copy of the GNU General Public License 16169695Skanalong with this program; if not, write to the Free Software 17169695SkanFoundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18169695Skan 19169695Skan In other words, you are welcome to use, share and improve this program. 20169695Skan You are forbidden to forbid anyone else to use, share and improve 21169695Skan what you give them. Help stamp out software-hoarding! */ 22169695Skan 23169695Skan#include "config.h" 24169695Skan#include "system.h" 25169695Skan#include "line-map.h" 26169695Skan#include "cpplib.h" 27169695Skan#include "getopt.h" 28169695Skan#include "mkdeps.h" 29169695Skan 30169695Skanconst char *progname; 31169695Skanconst char *vpath; 32169695Skan 33169695Skanstatic const char *output_file; 34169695Skanstatic bool had_errors; 35169695Skan 36169695Skan/* Option lists, to give to cpplib before each input file. */ 37169695Skanstruct cmd_line_macro 38169695Skan{ 39169695Skan struct cmd_line_macro *next; 40169695Skan bool is_undef; 41169695Skan const char *macro; 42169695Skan}; 43169695Skan 44169695Skanstatic struct cmd_line_macro *cmd_line_macros; 45169695Skanstatic cpp_dir *cmd_line_searchpath; 46169695Skan 47169695Skanstatic void 48169695Skanadd_clm (const char *macro, bool is_undef) 49169695Skan{ 50169695Skan struct cmd_line_macro *clm = XNEW (struct cmd_line_macro); 51169695Skan clm->next = cmd_line_macros; 52169695Skan clm->is_undef = is_undef; 53169695Skan clm->macro = macro; 54169695Skan cmd_line_macros = clm; 55169695Skan} 56169695Skan 57169695Skanstatic void 58169695Skanadd_dir (char *name, bool sysp) 59169695Skan{ 60169695Skan cpp_dir *dir = XNEW (cpp_dir); 61169695Skan dir->next = cmd_line_searchpath; 62169695Skan dir->name = name; 63169695Skan dir->sysp = sysp; 64169695Skan dir->construct = 0; 65169695Skan dir->user_supplied_p = 1; 66169695Skan cmd_line_searchpath = dir; 67169695Skan} 68169695Skan 69169695Skan/* Command line processing. */ 70169695Skan 71169695Skanstatic void ATTRIBUTE_NORETURN 72169695Skanusage (int errcode) 73169695Skan{ 74169695Skan fprintf (stderr, 75169695Skan"usage: %s [-vh] [-V vpath] [-Dname[=def]...] [-Uname] [-Idir...] [-o file] sources...\n", 76169695Skan progname); 77169695Skan exit (errcode); 78169695Skan} 79169695Skan 80169695Skanstatic int 81169695Skanparse_options (int argc, char **argv) 82169695Skan{ 83169695Skan static const struct option longopts[] = { 84169695Skan { "--help", no_argument, 0, 'h' }, 85169695Skan { 0, 0, 0, 0 } 86169695Skan }; 87169695Skan 88169695Skan for (;;) 89169695Skan switch (getopt_long (argc, argv, "hD:U:I:J:o:V:", longopts, 0)) 90169695Skan { 91169695Skan case 'h': usage (0); 92169695Skan case 'D': add_clm (optarg, false); break; 93169695Skan case 'U': add_clm (optarg, true); break; 94169695Skan case 'I': add_dir (optarg, false); break; 95169695Skan case 'J': add_dir (optarg, true); break; 96169695Skan case 'o': 97169695Skan if (output_file) 98169695Skan { 99169695Skan fprintf (stderr, "%s: too many output files\n", progname); 100169695Skan usage (2); 101169695Skan } 102169695Skan output_file = optarg; 103169695Skan break; 104169695Skan case 'V': 105169695Skan if (vpath) 106169695Skan { 107169695Skan fprintf (stderr, "%s: too many vpaths\n", progname); 108169695Skan usage (2); 109169695Skan } 110169695Skan vpath = optarg; 111169695Skan break; 112169695Skan case '?': 113169695Skan usage (2); /* getopt has issued the error message. */ 114169695Skan 115169695Skan case -1: /* end of options */ 116169695Skan if (optind == argc) 117169695Skan { 118169695Skan fprintf (stderr, "%s: no input files\n", progname); 119169695Skan usage (2); 120169695Skan } 121169695Skan return optind; 122169695Skan 123169695Skan default: 124169695Skan abort (); 125169695Skan } 126169695Skan} 127169695Skan 128169695Skan/* Set up cpplib from command line options. */ 129169695Skanstatic cpp_reader * 130169695Skanreader_init (struct line_maps *line_table) 131169695Skan{ 132169695Skan cpp_reader *reader; 133169695Skan cpp_options *options; 134169695Skan 135169695Skan linemap_init (line_table); 136169695Skan reader = cpp_create_reader (CLK_GNUC89, 0, line_table); 137169695Skan 138169695Skan /* Ignore warnings and errors (we don't have access to system 139169695Skan headers). Request dependency output. */ 140169695Skan options = cpp_get_options (reader); 141169695Skan options->inhibit_warnings = 1; 142169695Skan options->inhibit_errors = 1; 143169695Skan options->deps.style = DEPS_USER; 144169695Skan 145169695Skan /* Further initialization. */ 146169695Skan cpp_post_options (reader); 147169695Skan cpp_init_iconv (reader); 148169695Skan cpp_set_include_chains (reader, cmd_line_searchpath, cmd_line_searchpath, 149169695Skan false); 150169695Skan if (vpath) 151169695Skan { 152169695Skan struct deps *deps = cpp_get_deps (reader); 153169695Skan deps_add_vpath (deps, vpath); 154169695Skan } 155169695Skan 156169695Skan return reader; 157169695Skan} 158169695Skan 159169695Skan/* Process one input source file. */ 160169695Skanstatic void 161169695Skanprocess_file (const char *file) 162169695Skan{ 163169695Skan struct line_maps line_table; 164169695Skan cpp_reader *reader = reader_init (&line_table); 165169695Skan 166169695Skan if (!cpp_read_main_file (reader, file)) 167169695Skan had_errors = true; 168169695Skan else 169169695Skan { 170169695Skan struct cmd_line_macro *clm; 171169695Skan 172169695Skan cpp_init_builtins (reader, true); 173169695Skan for (clm = cmd_line_macros; clm; clm = clm->next) 174169695Skan (clm->is_undef ? cpp_undef : cpp_define) (reader, clm->macro); 175169695Skan 176169695Skan cpp_scan_nooutput (reader); 177169695Skan if (cpp_finish (reader, stdout)) 178169695Skan had_errors = true; 179169695Skan } 180169695Skan cpp_destroy (reader); 181169695Skan linemap_free (&line_table); 182169695Skan} 183169695Skan 184169695Skan/* Master control. */ 185169695Skan 186169695Skanint 187169695Skanmain(int argc, char **argv) 188169695Skan{ 189169695Skan int first_input, i; 190169695Skan 191169695Skan progname = argv[0]; 192169695Skan xmalloc_set_program_name (progname); 193169695Skan 194169695Skan first_input = parse_options (argc, argv); 195169695Skan if (output_file) 196169695Skan if (!freopen (output_file, "w", stdout)) 197169695Skan { 198169695Skan perror (output_file); 199169695Skan return 1; 200169695Skan } 201169695Skan 202169695Skan for (i = first_input; i < argc; i++) 203169695Skan process_file (argv[i]); 204169695Skan 205169695Skan return had_errors; 206169695Skan} 207