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