Merge 3.0 branch, start working on 3.0.3
[jelmer/ctrlproxy.git] / src / help.c
1 /*
2         ctrlproxy: A modular IRC proxy
3         help: module for access the help system
4
5         (c) 2006 Jelmer Vernooij <jelmer@nl.linux.org>
6         (c) 2004 Wilmer van der Gaast <wilmer@gaast.net>
7
8         This program is free software; you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation; either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program; if not, write to the Free Software
20         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "internals.h"
24 #include "help.h"
25 #include "log.h"
26
27 #define BUFSIZE 1100
28
29 void help_free(help_t *h)
30 {
31         if (h->file != NULL)
32 #if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 8
33                 g_mapped_file_free(h->file);
34 #else
35                 g_free(h->file);
36 #endif
37         if (h->entries != NULL)
38                 g_hash_table_destroy(h->entries);
39         g_free(h);
40 }
41
42 GHashTable *help_build_hash(char *data, gsize len)
43 {
44         GHashTable *h = g_hash_table_new_full(g_str_hash, g_str_equal,
45                                                                                   g_free, NULL);
46         gsize i;
47         char *p;
48
49         i = 0;
50         while (i < len) {
51                 if (data[i] != '?') {
52                         log_global(LOG_WARNING, "Unknown character '0x%02x' in help file", 
53                                            data[i]);
54                         g_hash_table_destroy(h);
55                         return NULL;
56                 }
57                 /* Key starts here */
58                 p = g_strstr_len(data+i, len-i, "\n");
59                 if (p == NULL) {
60                         log_global(LOG_WARNING, "Error parsing help file");
61                         g_hash_table_destroy(h);
62                         return NULL;
63                 }
64                 g_hash_table_insert(h, g_strndup(data+i+1, p-(data+i)-1), p+1);
65                 p = g_strstr_len(data+i, len-i, "\n%\n");
66                 if (p == NULL) {
67                         log_global(LOG_WARNING, "Error parsing help file");
68                         g_hash_table_destroy(h);
69                         return NULL;
70                 }
71                 i = p-data+3;
72         }
73         
74         return h;
75 }
76
77 help_t *help_load_file( const char *helpfile )
78 {
79         help_t *h;
80         char *data;
81         GError *error = NULL;
82         gsize len;
83         
84         h = g_new0 (help_t, 1);
85         
86 #if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 8
87         h->file = g_mapped_file_new(helpfile, FALSE, &error);
88         if (h->file != NULL) {
89                 len = g_mapped_file_get_length(h->file);
90                 data = g_mapped_file_get_contents(h->file);
91         }
92         
93         if( h->file == NULL ) {
94                 log_global(LOG_WARNING, "Unable to open help file `%s': %s", helpfile, 
95                                   error->message);
96                 help_free( h );
97                 return NULL;
98         }
99 #else
100         if (!g_file_get_contents(helpfile, &h->file, &len, &error)) {
101                 log_global(LOG_WARNING, "Unable to open help file `%s': %s", helpfile, 
102                                   error->message);
103                 help_free( h );
104                 return NULL;
105         } 
106         data = h->file;
107 #endif
108
109         h->entries = help_build_hash(data, len);
110
111         return h;
112 }
113
114 const char *help_get(help_t *h, const char *string)
115 {
116         if (h == NULL)
117                 return NULL;
118         return g_hash_table_lookup(h->entries, string);
119 }