add a command line option parsing, using getopt. It currently does -v (version) and...
[navit-package] / navit / main.c
1 #include <locale.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <getopt.h>
5 #include <string.h>
6 #include <signal.h>
7 #include <glib.h>
8 #include <sys/types.h>
9
10 #ifndef _WIN32
11 #include <sys/wait.h>
12 #include <signal.h>
13 #endif
14
15 #include <unistd.h>
16 #include <libintl.h>
17 #include "config.h"
18 #include "file.h"
19 #include "debug.h"
20 #include "main.h"
21 #include "navit.h"
22 #include "gui.h"
23 #include "xmlconfig.h"
24 #include "item.h"
25 #include "coord.h"
26 #include "route.h"
27 #include "navigation.h"
28 #include "event.h"
29
30 #define _(STRING)    gettext(STRING)
31
32 struct map_data *map_data_default;
33
34 static void sigchld(int sig)
35 {
36 #ifndef _WIN32
37         int status;
38         while (waitpid(-1, &status, WNOHANG) > 0);
39 #endif
40 }
41
42
43 static gchar *get_home_directory(void)
44 {
45         static gchar *homedir = NULL;
46
47         if (homedir) return homedir;
48         homedir = getenv("HOME");
49         if (!homedir)
50         {
51 //              struct passwd *p;
52
53 //              p = getpwuid(getuid());
54 //              if (p) homedir = p->pw_dir;
55         }
56         if (!homedir)
57         {
58                 g_warning("Could not find home directory. Using current directory as home directory.");
59                 homedir = ".";
60         }
61         return homedir;
62 }
63
64 static GList *navit;
65
66 struct iter {
67         GList *list;
68 };
69
70 struct iter *
71 main_iter_new(void)
72 {
73         struct iter *ret=g_new0(struct iter, 1);
74         ret->list=navit;
75         return ret;
76 }
77
78 void
79 main_iter_destroy(struct iter *iter)
80 {
81         g_free(iter);
82 }
83
84 struct navit *
85 main_get_navit(struct iter *iter)
86 {
87         GList *list;
88         struct navit *ret=NULL;
89         if (iter)
90                 list=iter->list;
91         else
92                 list=navit;
93         if (list) {
94                 ret=(struct navit *)(list->data);
95                 if (iter)
96                         iter->list=g_list_next(iter->list);
97         }
98         return ret;
99         
100 }
101 void
102 main_add_navit(struct navit *nav)
103 {
104         navit=g_list_prepend(navit, nav);
105 }
106
107 void
108 main_remove_navit(struct navit *nav)
109 {
110         navit=g_list_remove(navit, nav);
111         if (! navit) 
112                 event_main_loop_quit();
113 }
114
115 void
116 print_usage(void)
117 {
118         printf(_("navit usage:\nnavit [options] [configfile]\n\t-d <n>: set the debug output level to <n>.\n\t-h: print this usage info.\n\t-v: Print the version and exit.\n"));
119 }
120
121 int main(int argc, char **argv)
122 {
123         GError *error = NULL;
124         char *config_file = NULL;
125         char *s;
126         int l;
127
128
129 #ifndef _WIN32
130         signal(SIGCHLD, sigchld);
131 #endif
132
133         setenv("LC_NUMERIC","C",1);
134         setlocale(LC_ALL,"");
135         setlocale(LC_NUMERIC,"C");
136         if (file_exists("navit.c") || file_exists("navit.o")) {
137                 char buffer[PATH_MAX];
138                 printf(_("Running from source directory\n"));
139                 getcwd(buffer, PATH_MAX);
140                 setenv("NAVIT_PREFIX", buffer, 0);
141                 setenv("NAVIT_LIBDIR", buffer, 0);
142                 setenv("NAVIT_SHAREDIR", buffer, 0);
143                 setenv("NAVIT_LIBPREFIX", "*/.libs/", 0);
144                 s=g_strdup_printf("%s/../locale", buffer);
145                 setenv("NAVIT_LOCALEDIR", s, 0);
146                 g_free(s);
147         } else {
148                 if (!getenv("NAVIT_PREFIX")) {
149                         l=strlen(argv[0]);
150                         if (l > 10 && !strcmp(argv[0]+l-10,"/bin/navit")) {
151                                 s=g_strdup(argv[0]);
152                                 s[l-10]='\0';
153                                 if (strcmp(s, PREFIX))
154                                         printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
155                                 setenv("NAVIT_PREFIX", s, 0);
156                                 g_free(s);
157                         } else
158                                 setenv("NAVIT_PREFIX", PREFIX, 0);
159                 }
160 #ifdef _WIN32
161                 s=g_strdup_printf("locale");
162 #else
163                 s=g_strdup_printf("%s/share/locale", getenv("NAVIT_PREFIX"));
164 #endif
165                 setenv("NAVIT_LOCALEDIR", s, 0);
166                 g_free(s);
167 #ifdef _WIN32
168                 s=g_strdup_printf(".");
169 #else
170                 s=g_strdup_printf("%s/share/navit", getenv("NAVIT_PREFIX"));
171 #endif
172                 setenv("NAVIT_SHAREDIR", s, 0);
173                 g_free(s);
174                 s=g_strdup_printf("%s/lib/navit", getenv("NAVIT_PREFIX"));
175                 setenv("NAVIT_LIBDIR", s, 0);
176                 g_free(s);
177         }
178         bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
179         bind_textdomain_codeset (PACKAGE, "UTF-8");
180         textdomain(PACKAGE);
181
182         debug_init(argv[0]);
183         if (getenv("LC_ALL")) 
184                 dbg(0,"Warning: LC_ALL is set, this might lead to problems\n");
185 #ifndef USE_PLUGINS
186         extern void builtin_init(void);
187         builtin_init();
188 #endif
189 #if 0
190         /* handled in gui/gtk */
191         gtk_set_locale();
192         gtk_init(&argc, &argv);
193         gdk_rgb_init();
194 #endif
195         s = getenv("NAVIT_WID");
196         if (s) {
197                 setenv("SDL_WINDOWID", s, 0);
198         }
199         route_init();
200         navigation_init();
201         config_file=NULL;
202         int opt;
203         opterr=0;  //don't bomb out on errors.
204         if (argc > 1) {
205           while((opt = getopt(argc, argv, ":hvd:")) != -1) {
206             switch(opt) {
207               case 'h':
208                     print_usage();
209                     exit(0);
210                     break;
211               case 'v':
212                     printf("%s %s\n", "navit", "0.0.4+svn"); 
213                     exit(0);
214                     break;
215               case 'd':
216                     printf("TODO Verbose option is set to `%s'\n", optarg);
217                     break;
218               case ':':
219                     fprintf(stderr, "navit: Error - Option `%c' needs a value\n", optopt);
220                     print_usage();
221                     exit(1);
222                     break;
223                case '?':
224                     fprintf(stderr, "navit: Error - No such option: `%c'\n", optopt);
225                     print_usage();
226                     exit(1);
227                 }
228             }
229         }
230         // the first non-option argument is the config file
231         if (optind < argc)
232             config_file=argv[optind];
233
234         if (! config_file) {
235                 config_file=g_strjoin(NULL,get_home_directory(), "/.navit/navit.xml" , NULL);
236                 if (!file_exists(config_file)) {
237                         g_free(config_file);
238                         config_file=NULL;
239                         }
240         }
241         if (! config_file) {
242                 if (file_exists("navit.xml.local"))
243                         config_file="navit.xml.local";
244         }
245         if (! config_file) {
246                 if (file_exists("navit.xml"))
247                         config_file="navit.xml";
248         }
249         if (! config_file) {
250                 config_file=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml.local" , NULL);
251                 if (!file_exists(config_file)) {
252                         g_free(config_file);
253                         config_file=NULL;
254                 }
255         }
256         if (! config_file) {
257                 config_file=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml" , NULL);
258                 if (!file_exists(config_file)) {
259                         g_free(config_file);
260                         config_file=NULL;
261                 }
262         }
263         if (!config_file) {
264                 printf(_("No config file navit.xml, navit.xml.local found\n"));
265                 exit(1);
266         }
267         if (!config_load(config_file, &error)) {
268                 printf(_("Error parsing '%s': %s\n"), config_file, error->message);
269                 exit(1);
270         } else {
271                 printf(_("Using '%s'\n"), config_file);
272         }
273         if (! navit) {
274                 printf(_("No instance has been created, exiting\n"));
275                 exit(1);
276         }
277         if (main_loop_gui) {
278                 gui_run_main_loop(main_loop_gui);
279         } else 
280                 event_main_loop_run();
281
282         return 0;
283 }