1 #include <stdarg.h>
2 #include <glib.h>
3 #include "MakerDialogUtil.h"
4
5 static MkdgLogLevel debugLevel = WARN;
6 #define MKDG_LOG_DOMAIN_LEN 20
7 static gchar mkdgLogDomain[MKDG_LOG_DOMAIN_LEN] = "MKDG";
8
9 static FILE *logFile = NULL;
mkdg_log_set_level(MkdgLogLevel level)10 void mkdg_log_set_level(MkdgLogLevel level)
11 {
12 debugLevel = level;
13 }
14
mkdg_log_set_domain(const gchar * domain)15 void mkdg_log_set_domain(const gchar * domain)
16 {
17 g_strlcpy(mkdgLogDomain, domain, MKDG_LOG_DOMAIN_LEN);
18 }
19
mkdg_log_set_file(FILE * file)20 void mkdg_log_set_file(FILE * file)
21 {
22 logFile = file;
23 }
24
mkdg_logv_domain(const gchar * domain,MkdgLogLevel level,const gchar * format,va_list argList)25 void mkdg_logv_domain(const gchar * domain, MkdgLogLevel level,
26 const gchar * format, va_list argList)
27 {
28 if (level > debugLevel)
29 return;
30 GLogLevelFlags flagSet;
31 gchar *levelStr = NULL;
32 switch (level) {
33 case ERROR:
34 flagSet = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR;
35 levelStr = "ERROR";
36 break;
37 case WARN:
38 flagSet = G_LOG_LEVEL_WARNING;
39 levelStr = "WARN";
40 break;
41 case MSG:
42 flagSet = G_LOG_LEVEL_MESSAGE;
43 levelStr = "MSG";
44 break;
45 case INFO:
46 flagSet = G_LOG_LEVEL_INFO;
47 levelStr = "INFO";
48 break;
49 default:
50 flagSet = G_LOG_LEVEL_DEBUG;
51 levelStr = "DEBUG";
52 break;
53 }
54 g_logv(domain, flagSet, format, argList);
55 if (logFile != NULL) {
56 fprintf(logFile, "%s-%s: ", domain, levelStr);
57 vfprintf(logFile, format, argList);
58 fprintf(logFile, "\n");
59 }
60 }
61
mkdg_log(MkdgLogLevel level,const gchar * format,...)62 void mkdg_log(MkdgLogLevel level, const gchar * format, ...)
63 {
64 if (level > debugLevel)
65 return;
66 va_list argList;
67 va_start(argList, format);
68 mkdg_logv_domain(mkdgLogDomain, level, format, argList);
69 va_end(argList);
70 }
71
mkdg_log_domain(const gchar * domain,MkdgLogLevel level,const gchar * format,...)72 void mkdg_log_domain(const gchar * domain, MkdgLogLevel level,
73 const gchar * format, ...)
74 {
75 if (level > debugLevel)
76 return;
77 va_list argList;
78 va_start(argList, format);
79 mkdg_logv_domain(domain, level, format, argList);
80 va_end(argList);
81 }
82
mkdg_g_value_reset(GValue * value,GType type,gboolean overwrite)83 gboolean mkdg_g_value_reset(GValue * value, GType type, gboolean overwrite)
84 {
85 if (!G_IS_VALUE(value)) {
86 g_value_init(value, type);
87 }
88 if (G_VALUE_TYPE(value) != type) {
89 if (!overwrite) {
90 mkdg_log(ERROR, "mkdg_g_value_reset(): type incompatible");
91 return FALSE;
92 }
93 }
94 g_value_reset(value);
95 return TRUE;
96 }
97
98
mkdg_g_value_to_string(GValue * value)99 gchar *mkdg_g_value_to_string(GValue * value)
100 {
101 static gchar result[MAKER_DIALOG_VALUE_LENGTH];
102 result[0] = '\0';
103 GType gType = G_VALUE_TYPE(value);
104 guint uintValue;
105 gint intValue;
106 switch (gType) {
107 case G_TYPE_BOOLEAN:
108 if (g_value_get_boolean(value)) {
109 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "1");
110 } else {
111 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "0");
112 }
113 break;
114 case G_TYPE_UINT:
115 uintValue = g_value_get_uint(value);
116 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%u", uintValue);
117 break;
118 case G_TYPE_INT:
119 intValue = g_value_get_int(value);
120 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%d", intValue);
121 break;
122 case G_TYPE_STRING:
123 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%s",
124 g_value_get_string(value));
125 break;
126 default:
127 break;
128 }
129 return result;
130 }
131
mkdg_g_value_from_string(GValue * value,const gchar * str)132 gboolean mkdg_g_value_from_string(GValue * value, const gchar * str)
133 {
134 mkdg_log(DEBUG, "mkdg_g_value_from_string(-,%s)", str);
135 if (!G_IS_VALUE(value)) {
136 mkdg_log(ERROR, "mkdg_g_value_from_string(): Failed to get GType");
137 return FALSE;
138 }
139 GType gType = G_VALUE_TYPE(value);
140 mkdg_log(DEBUG, "mkdg_g_value_from_string() gType=%s",
141 g_type_name(gType));
142 if (!mkdg_g_value_reset(value, gType, FALSE)) {
143 return FALSE;
144 }
145
146 guint uintValue;
147 gint intValue;
148 gchar *endPtr = NULL;
149 switch (gType) {
150 case G_TYPE_BOOLEAN:
151 if (STRING_IS_EMPTY(str)) {
152 g_value_set_boolean(value, FALSE);
153 } else if (STRING_EQUALS(str, "0")) {
154 g_value_set_boolean(value, FALSE);
155 } else if (STRING_EQUALS(str, "F")) {
156 g_value_set_boolean(value, FALSE);
157 } else if (STRING_EQUALS(str, "f")) {
158 g_value_set_boolean(value, FALSE);
159 } else if (STRING_EQUALS(str, "FALSE")) {
160 g_value_set_boolean(value, FALSE);
161 } else if (STRING_EQUALS(str, "false")) {
162 g_value_set_boolean(value, FALSE);
163 } else {
164 g_value_set_boolean(value, TRUE);
165 }
166 return TRUE;
167 case G_TYPE_UINT:
168 uintValue = g_ascii_strtoull(str, &endPtr, 10);
169 if (uintValue == 0 && endPtr == str) {
170 return FALSE;
171 }
172 g_value_set_uint(value, uintValue);
173 return TRUE;
174 case G_TYPE_INT:
175 intValue = g_ascii_strtoll(str, &endPtr, 10);
176 if (intValue == 0 && endPtr == str) {
177 return FALSE;
178 }
179 g_value_set_int(value, intValue);
180 return TRUE;
181 case G_TYPE_STRING:
182 g_value_set_string(value, str);
183 return TRUE;
184 default:
185 break;
186 }
187 return FALSE;
188 }
189
mkdg_g_variant_to_g_value(GVariant * gVar,GValue * value)190 void mkdg_g_variant_to_g_value(GVariant * gVar, GValue * value)
191 {
192 const GVariantType *gVType = g_variant_get_type(gVar);
193 if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_BOOLEAN)) {
194 g_value_set_boolean(value, g_variant_get_boolean(gVar));
195 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_UINT16)) {
196 g_value_set_uint(value, g_variant_get_uint16(gVar));
197 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_UINT32)) {
198 g_value_set_uint(value, g_variant_get_uint32(gVar));
199 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_UINT64)) {
200 g_value_set_uint64(value, g_variant_get_uint64(gVar));
201 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_INT16)) {
202 g_value_set_int(value, g_variant_get_int16(gVar));
203 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_INT32)) {
204 g_value_set_int(value, g_variant_get_int32(gVar));
205 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_INT64)) {
206 g_value_set_int64(value, g_variant_get_int64(gVar));
207 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_STRING)) {
208 g_value_set_string(value, g_variant_get_string(gVar, NULL));
209 }
210 }
211
mkdg_g_value_to_g_variant(GValue * value)212 GVariant *mkdg_g_value_to_g_variant(GValue * value)
213 {
214 GType gType = G_VALUE_TYPE(value);
215 GVariant *gVar = NULL;
216 switch (gType) {
217 case G_TYPE_BOOLEAN:
218 gVar = g_variant_new_boolean(g_value_get_boolean(value));
219 break;
220 case G_TYPE_UINT:
221 gVar = g_variant_new_uint32(g_value_get_uint(value));
222 break;
223 case G_TYPE_UINT64:
224 gVar = g_variant_new_uint64(g_value_get_uint(value));
225 break;
226 case G_TYPE_INT:
227 gVar = g_variant_new_int32(g_value_get_int(value));
228 break;
229 case G_TYPE_INT64:
230 gVar = g_variant_new_int64(g_value_get_int(value));
231 break;
232 case G_TYPE_STRING:
233 gVar = g_variant_new_string(g_value_get_string(value));
234 break;
235 default:
236 break;
237 }
238 return gVar;
239 }
240
241 /*============================================
242 * MKDG Str functions
243 */
244
mkdg_str_dash_to_camel(const gchar * argStr)245 gchar *mkdg_str_dash_to_camel(const gchar * argStr)
246 {
247 GString *string = g_string_new(NULL);
248 gboolean upper = FALSE;
249 int i;
250 for (i = 0; i < strlen(argStr); i++) {
251 if (upper) {
252 g_string_append_c(string, g_ascii_toupper(argStr[i]));
253 upper = FALSE;
254 } else {
255 switch (argStr[i]) {
256 case '-':
257 case '_':
258 upper = TRUE;
259 break;
260 default:
261 g_string_append_c(string, argStr[i]);
262 break;
263 }
264
265 }
266 }
267 return g_string_free(string, FALSE);
268 }
269
270 /*============================================
271 * MKDG XML functions
272 */
273
274 #define INDENT_SPACES 4
275
mkdg_xml_append_indent_space(GString * strBuf,gint indentLevel)276 static void mkdg_xml_append_indent_space(GString * strBuf,
277 gint indentLevel)
278 {
279 int i, indentLen = indentLevel * INDENT_SPACES;
280 for (i = 0; i < indentLen; i++) {
281 g_string_append_c(strBuf, ' ');
282 }
283 }
284
mkdg_xml_tags_to_string(const gchar * tagName,MkdgXmlTagType type,const gchar * attribute,const gchar * value,gint indentLevel)285 static GString *mkdg_xml_tags_to_string(const gchar * tagName,
286 MkdgXmlTagType type,
287 const gchar * attribute,
288 const gchar * value,
289 gint indentLevel)
290 {
291 GString *strBuf = g_string_new(NULL);
292 mkdg_xml_append_indent_space(strBuf, indentLevel);
293
294 if (type != MKDG_XML_TAG_TYPE_NO_TAG) {
295 g_string_append_printf(strBuf, "<%s%s%s%s%s>",
296 (type ==
297 MKDG_XML_TAG_TYPE_END_ONLY) ? "/" : "",
298 (!STRING_IS_EMPTY(tagName)) ? tagName : "",
299 (!STRING_IS_EMPTY(attribute)) ? " " : "",
300 (!STRING_IS_EMPTY(attribute)) ? attribute :
301 "",
302 (type ==
303 MKDG_XML_TAG_TYPE_EMPTY) ? "/" : "");
304 }
305 if (type == MKDG_XML_TAG_TYPE_EMPTY)
306 return strBuf;
307 if (type == MKDG_XML_TAG_TYPE_BEGIN_ONLY)
308 return strBuf;
309 if (type == MKDG_XML_TAG_TYPE_END_ONLY)
310 return strBuf;
311
312 if (type == MKDG_XML_TAG_TYPE_LONG) {
313 g_string_append_c(strBuf, '\n');
314 }
315
316 if (value) {
317 if (type == MKDG_XML_TAG_TYPE_LONG
318 || type == MKDG_XML_TAG_TYPE_NO_TAG) {
319 mkdg_xml_append_indent_space(strBuf, indentLevel + 1);
320 int i, valueLen = strlen(value);
321 for (i = 0; i < valueLen; i++) {
322 g_string_append_c(strBuf, value[i]);
323 if (value[i] == '\n') {
324 mkdg_xml_append_indent_space(strBuf, indentLevel + 1);
325 }
326 }
327 g_string_append_c(strBuf, '\n');
328 if (type == MKDG_XML_TAG_TYPE_LONG) {
329 mkdg_xml_append_indent_space(strBuf, indentLevel);
330 }
331 } else {
332 g_string_append(strBuf, value);
333 }
334 }
335
336 if (type == MKDG_XML_TAG_TYPE_LONG || type == MKDG_XML_TAG_TYPE_SHORT) {
337 g_string_append_printf(strBuf, "</%s>", tagName);
338 }
339 return strBuf;
340 }
341
mkdg_xml_attr_append(gchar * buf,gint bufferSize,const gchar * attr,const gchar * value)342 gchar *mkdg_xml_attr_append(gchar * buf, gint bufferSize,
343 const gchar * attr, const gchar * value)
344 {
345 if (STRING_IS_EMPTY(attr))
346 return buf;
347 if (!STRING_IS_EMPTY(buf))
348 g_strlcat(buf, " ", bufferSize);
349
350 g_strlcat(buf, attr, bufferSize);
351 if (STRING_IS_EMPTY(value))
352 return buf;
353
354 g_strlcat(buf, "=\"", bufferSize);
355 g_strlcat(buf, value, bufferSize);
356 g_strlcat(buf, "\"", bufferSize);
357 return buf;
358 }
359
mkdg_xml_tags_write(FILE * outF,const gchar * tagName,MkdgXmlTagType type,const gchar * attribute,const gchar * value)360 gboolean mkdg_xml_tags_write(FILE * outF, const gchar * tagName,
361 MkdgXmlTagType type, const gchar * attribute,
362 const gchar * value)
363 {
364 static int indentLevel = 0;
365 if (type == MKDG_XML_TAG_TYPE_END_ONLY)
366 indentLevel--;
367
368 GString *strBuf =
369 mkdg_xml_tags_to_string(tagName, type, attribute, value,
370 indentLevel);
371 mkdg_log(INFO, "xml_tags_write:%s", strBuf->str);
372 fprintf(outF, "%s\n", strBuf->str);
373
374 if (type == MKDG_XML_TAG_TYPE_BEGIN_ONLY)
375 indentLevel++;
376 g_string_free(strBuf, TRUE);
377 return TRUE;
378 }
379