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