1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010,2011,2012 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library 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 GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
23 * @Section_Id:utilities
25 * @short_description: Assorted macros and functions
27 * Collection of macros and functions that do not fit inside any other topic.
34 * @id: The name of a struct
36 * Forward declaration of struct @id. It is equivalent to a typical
37 * struct forward declaration, for example:
40 * ADG_FORWARD_DECL(test)
46 * typedef struct _test test
49 * This macro is needed to fake <command>gtk-doc</command>, because
50 * up to now (v.1.12) it generates two conflicting links when using
51 * forward declarations: the first in the source with the declaration
52 * and the second where the type is defined. Using ADG_FORWARD_DECL()
53 * instead of the usual typedef avoids the parsing of the declaration
54 * in the first file (<command>gtk-doc</command> is not able to do C
57 * The same principle can be applied in the definition file. Following
58 * the previous example, you can use something like this where struct
63 * // This is declared in another file
64 * typedef struct _type type;
77 * Symbolic constant for the right direction (in radians).
85 * Symbolic constant for the down direction (in radians).
93 * Symbolic constant for the left direction (in radians).
101 * Symbolic constant for the up direction (in radians).
109 * String constant that embeds a UTF-8 encoded diameter (U+2300).
110 * It can be used to prefix diameter quotes, such as:
113 * adg_dim_set_value(dim, ADG_UTF8_DIAMETER "<>");
122 * String constant that embeds a UTF-8 encoded degree symbol (U+00B0).
123 * It is used to suffix by the default implementation of #AdgADim to
124 * suffix the set value, but can be also used manually:
127 * adg_dim_set_value(dim, "<>" ADG_UTF8_DEGREE);
134 #include "adg-internal.h"
139 #if GLIB_CHECK_VERSION(2, 16, 0)
143 * @str1: a C string or %NULL
144 * @str2: another C string or %NULL
146 * Compares @str1 and @str2 like strcmp(). Handles %NULL
147 * gracefully by sorting it before non-%NULL strings.
148 * This is a backward compatibility fallback for GLib
151 * Returns: -1, 0 or 1, if @str1 is <, == or > than @str2.
156 g_strcmp0(const char *str1
, const char *str2
)
159 return -(str1
!= str2
);
164 return strcmp(str1
, str2
);
169 * adg_is_string_empty:
170 * @str: the subject string
172 * Checks if @str is an empty string, that is if is %NULL or if
173 * its first character is %'\0'.
175 * Returns: %TRUE if @str is an empty string, %FALSE otherwise
180 adg_is_string_empty(const gchar
*str
)
182 return str
== NULL
|| str
[0] == '\0';
187 * @value: the enum value to check
188 * @enum_type: a #GEnum based type
190 * Checks if @value is a valid @enum_type value.
192 * Returns: %TRUE if @value is a valid @enum_type, %FALSE otherwise
197 adg_is_enum_value(int value
, GType enum_type
)
199 GEnumClass
*enum_class
;
202 enum_class
= g_type_class_ref(enum_type
);
203 g_return_val_if_fail(enum_class
!= NULL
, FALSE
);
207 if (value
>= enum_class
->minimum
&& value
<= enum_class
->maximum
) {
208 GEnumValue
*enum_value
;
211 for (n
= 0; !found
&& n
< enum_class
->n_values
; ++n
) {
212 enum_value
= enum_class
->values
+ n
;
213 found
= value
== enum_value
->value
;
217 g_type_class_unref(enum_class
);
223 * adg_is_boolean_value:
224 * @value: the gboolean value to check
226 * Checks if @value is a valid #gboolean value, that is if it is %TRUE
227 * or %FALSE. No other values are accepted.
229 * Returns: %TRUE if @value is a valid #gboolean, %FALSE otherwise
234 adg_is_boolean_value(gboolean value
)
236 return value
== TRUE
|| value
== FALSE
;
240 * adg_string_replace:
241 * @str: the original string
242 * @from: the substring to replace
243 * @to: the replacement string
245 * Replaces @from with @to inside @str and returns the result as a
246 * newly allocated string.
248 * @str and @from must be non-null valid C strings while @to can be
249 * %NULL, in which case an empty string ("") will be implied.
251 * Returns: a newly allocated string to be freed with g_free() or
257 adg_string_replace(const gchar
*str
, const gchar
*from
, const gchar
*to
)
261 gchar
*ptr
, *old_result
;
263 g_return_val_if_fail(str
!= NULL
, NULL
);
264 g_return_val_if_fail(from
!= NULL
, NULL
);
266 from_len
= strlen(from
);
268 g_return_val_if_fail(from_len
> 0, NULL
);
273 result
= g_strdup(str
);
275 while ((ptr
= strstr(result
, from
)) != NULL
) {
278 result
= g_strconcat(old_result
, to
, ptr
+ from_len
, NULL
);
287 * @domain: the translation domain to use, or %NULL to use
288 * the domain set with textdomain()
289 * @msgid: message to translate
291 * A variant of dgettext() (or of g_dgettext(), if available) that
292 * initialize the ADG localization infrastructure.
294 * Returns: The translated string
299 _adg_dgettext(const gchar
*domain
, const gchar
*msgid
)
301 static gboolean initialized
= FALSE
;
303 if (G_UNLIKELY(!initialized
)) {
304 bindtextdomain(GETTEXT_PACKAGE
, LOCALEDIR
);
305 bindtextdomain(GETTEXT_PACKAGE
"-properties", LOCALEDIR
);
309 #if GLIB_CHECK_VERSION(2, 18, 0)
310 return g_dgettext(domain
, msgid
);
312 return dgettext(domain
, msgid
);
318 * @domain: the translation domain to use, or %NULL to use
319 * the domain set with textdomain()
320 * @msgctxtid: a combined message context and message id, separated
321 * by a \004 character
322 * @msgidoffset: the offset of the message id in @msgctxid
324 * This function is basically a duplicate of g_dpgettext() but using
325 * _adg_dgettext() internally instead of g_dgettext().
327 * Returns: The translated string
332 _adg_dpgettext(const gchar
*domain
, const gchar
*msgctxtid
, gsize msgidoffset
)
334 const gchar
*translation
;
337 translation
= _adg_dgettext(domain
, msgctxtid
);
339 if (translation
== msgctxtid
) {
341 return msgctxtid
+ msgidoffset
;
343 sep
= strchr(msgctxtid
, '|');
346 /* try with '\004' instead of '|', in case
347 * xgettext -kQ_:1g was used
349 gchar
*tmp
= g_alloca(strlen(msgctxtid
) + 1);
350 strcpy(tmp
, msgctxtid
);
351 tmp
[sep
- msgctxtid
] = '\004';
353 translation
= _adg_dgettext(domain
, tmp
);
355 if (translation
== tmp
)