1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
4 * Copyright (C) 2008 Imendio AB
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 the
9 * 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 GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22 #include "config.h"
23 #include <string.h>
24 #include <glib-object.h>
25 #include <glib/gi18n-lib.h>
26 #include "dh-link.h"
27
28 struct _DhLink {
29 /* FIXME: Those two could exist only for book to save some
30 * memory.
31 */
32 gchar *id;
33 gchar *base;
34
35 gchar *name;
36 gchar *filename;
37
38 DhLink *book;
39 DhLink *page;
40
41 guint ref_count;
42
43 DhLinkType type : 8;
44 DhLinkFlags flags : 8;
45 };
46
47 GType
dh_link_get_type(void)48 dh_link_get_type (void)
49 {
50 static GType type = 0;
51
52 if (G_UNLIKELY (type == 0)) {
53 type = g_boxed_type_register_static (
54 "DhLink",
55 (GBoxedCopyFunc) dh_link_ref,
56 (GBoxedFreeFunc) dh_link_unref);
57 }
58 return type;
59 }
60
61 static void
link_free(DhLink * link)62 link_free (DhLink *link)
63 {
64 g_free (link->base);
65 g_free (link->id);
66 g_free (link->name);
67 g_free (link->filename);
68
69 if (link->book) {
70 dh_link_unref (link->book);
71 }
72 if (link->page) {
73 dh_link_unref (link->page);
74 }
75
76 g_slice_free (DhLink, link);
77 }
78
79 DhLink *
dh_link_new(DhLinkType type,const gchar * base,const gchar * id,const gchar * name,DhLink * book,DhLink * page,const gchar * filename)80 dh_link_new (DhLinkType type,
81 const gchar *base,
82 const gchar *id,
83 const gchar *name,
84 DhLink *book,
85 DhLink *page,
86 const gchar *filename)
87 {
88 DhLink *link;
89
90 g_return_val_if_fail (name != NULL, NULL);
91 g_return_val_if_fail (filename != NULL, NULL);
92
93 if (type == DH_LINK_TYPE_BOOK) {
94 g_return_val_if_fail (base != NULL, NULL);
95 g_return_val_if_fail (id != NULL, NULL);
96 }
97 if (type != DH_LINK_TYPE_BOOK && type != DH_LINK_TYPE_PAGE) {
98 g_return_val_if_fail (book != NULL, NULL);
99 g_return_val_if_fail (page != NULL, NULL);
100 }
101
102 link = g_slice_new0 (DhLink);
103
104 link->ref_count = 1;
105 link->type = type;
106
107 if (type == DH_LINK_TYPE_BOOK) {
108 link->base = g_strdup (base);
109 link->id = g_strdup (id);
110 }
111
112 link->name = g_strdup (name);
113 link->filename = g_strdup (filename);
114
115 if (book) {
116 link->book = dh_link_ref (book);
117 }
118 if (page) {
119 link->page = dh_link_ref (page);
120 }
121
122 return link;
123 }
124
125 gint
dh_link_compare(gconstpointer a,gconstpointer b)126 dh_link_compare (gconstpointer a,
127 gconstpointer b)
128 {
129 DhLink *la = (DhLink *) a;
130 DhLink *lb = (DhLink *) b;
131 gint flags_diff;
132
133 /* Sort deprecated hits last. */
134 flags_diff = (la->flags & DH_LINK_FLAGS_DEPRECATED) -
135 (lb->flags & DH_LINK_FLAGS_DEPRECATED);
136 if (flags_diff != 0) {
137 return flags_diff;
138 }
139
140 return strcmp (la->name, lb->name);
141 }
142
143 DhLink *
dh_link_ref(DhLink * link)144 dh_link_ref (DhLink *link)
145 {
146 g_return_val_if_fail (link != NULL, NULL);
147
148 link->ref_count++;
149
150 return link;
151 }
152
153 void
dh_link_unref(DhLink * link)154 dh_link_unref (DhLink *link)
155 {
156 g_return_if_fail (link != NULL);
157
158 link->ref_count--;
159
160 if (link->ref_count == 0) {
161 link_free (link);
162 }
163 }
164
165 const gchar *
dh_link_get_name(DhLink * link)166 dh_link_get_name (DhLink *link)
167 {
168 return link->name;
169 }
170
171 const gchar *
dh_link_get_book_name(DhLink * link)172 dh_link_get_book_name (DhLink *link)
173 {
174 if (link->book) {
175 return link->book->name;
176 }
177
178 return "";
179 }
180
181 const gchar *
dh_link_get_page_name(DhLink * link)182 dh_link_get_page_name (DhLink *link)
183 {
184 if (link->page) {
185 return link->page->name;
186 }
187
188 return "";
189 }
190
191 const gchar *
dh_link_get_file_name(DhLink * link)192 dh_link_get_file_name (DhLink *link)
193 {
194 if (link->page) {
195 return link->filename;
196 }
197
198 return "";
199 }
200
201 const gchar *
dh_link_get_book_id(DhLink * link)202 dh_link_get_book_id (DhLink *link)
203 {
204 if (link->type == DH_LINK_TYPE_BOOK) {
205 return link->id;
206 }
207
208 if (link->book) {
209 return link->book->id;
210 }
211
212 return "";
213 }
214
215 gchar *
dh_link_get_uri(DhLink * link)216 dh_link_get_uri (DhLink *link)
217 {
218 gchar *base, *uri;
219
220 if (link->type == DH_LINK_TYPE_BOOK)
221 base = link->base;
222 else
223 base = link->book->base;
224
225 uri = g_strconcat ("file://", base, "/", link->filename, NULL, NULL);
226
227 return uri;
228 }
229
230 DhLinkType
dh_link_get_link_type(DhLink * link)231 dh_link_get_link_type (DhLink *link)
232 {
233 return link->type;
234 }
235
236 DhLinkFlags
dh_link_get_flags(DhLink * link)237 dh_link_get_flags (DhLink *link)
238 {
239 return link->flags;
240 }
241
242 void
dh_link_set_flags(DhLink * link,DhLinkFlags flags)243 dh_link_set_flags (DhLink *link,
244 DhLinkFlags flags)
245 {
246 link->flags = flags;
247 }
248
249 const gchar *
dh_link_get_type_as_string(DhLink * link)250 dh_link_get_type_as_string (DhLink *link)
251 {
252 switch (link->type) {
253 case DH_LINK_TYPE_BOOK:
254 /* i18n: a documentation book */
255 return _("Book");
256 case DH_LINK_TYPE_PAGE:
257 /* i18n: a "page" in a documentation book */
258 return _("Page");
259 case DH_LINK_TYPE_KEYWORD:
260 /* i18n: a search hit in the documentation, could be a
261 * function, macro, struct, etc */
262 return _("Keyword");
263 case DH_LINK_TYPE_FUNCTION:
264 /* i18n: in the programming language context, if you don't
265 * have an ESTABLISHED term for it, leave it
266 * untranslated. */
267 return _("Function");
268 case DH_LINK_TYPE_STRUCT:
269 /* i18n: in the programming language context, if you don't
270 * have an ESTABLISHED term for it, leave it
271 * untranslated. */
272 return _("Struct");
273 case DH_LINK_TYPE_MACRO:
274 /* i18n: in the programming language context, if you don't
275 * have an ESTABLISHED term for it, leave it
276 * untranslated. */
277 return _("Macro");
278 case DH_LINK_TYPE_ENUM:
279 /* i18n: in the programming language context, if you don't
280 * have an ESTABLISHED term for it, leave it
281 * untranslated. */
282 return _("Enum");
283 case DH_LINK_TYPE_TYPEDEF:
284 /* i18n: in the programming language context, if you don't
285 * have an ESTABLISHED term for it, leave it
286 * untranslated. */
287 return _("Type");
288 }
289
290 return "";
291 }
292