1 /*
2  * mape - C4 Landscape.txt editor
3  *
4  * Copyright (c) 2005-2009, Armin Burgmeier
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include "mape/configfile.h"
20 
mape_config_file_new(const gchar * filename)21 MapeConfigFile* mape_config_file_new(const gchar* filename)
22 {
23 	/* If filename does not exist, we return an empty config file. */
24 	MapeConfigFile* file;
25 	gchar* contents;
26 	gchar** lines;
27 	gchar** cur_line;
28 	gchar* sep;
29 	gsize length;
30 
31 	file = malloc(sizeof(MapeConfigFile) );
32 	file->file_path = g_strdup(filename);
33 	file->entries = NULL;
34 	file->entry_count = 0;
35 
36 	if(g_file_get_contents(filename, &contents, &length, NULL) == FALSE)
37 		return file;
38 
39 	lines = g_strsplit(contents, "\n", 0);
40 	g_free(contents);
41 
42 	for(cur_line = lines; *cur_line != NULL; ++ cur_line)
43 	{
44 		sep = strchr(*cur_line, '=');
45 		if(sep == NULL) continue;
46 
47 		*sep = '\0';
48 		mape_config_file_set_entry(file, *cur_line, sep + 1);
49 		*sep = '=';
50 	}
51 
52 	g_strfreev(lines);
53 	return file;
54 }
55 
mape_config_file_destroy(MapeConfigFile * file)56 void mape_config_file_destroy(MapeConfigFile* file)
57 {
58 	gsize i;
59 	for(i = 0; i < file->entry_count; ++ i)
60 	{
61 		g_free(file->entries[i].key);
62 		g_free(file->entries[i].value);
63 	}
64 
65 	g_free(file->entries);
66 	g_free(file->file_path);
67 	free(file);
68 }
69 
mape_config_file_serialise(MapeConfigFile * file,GError ** error)70 gboolean mape_config_file_serialise(MapeConfigFile* file,
71                                     GError** error)
72 {
73 	gchar* dir;
74 	gchar* content;
75 	gchar* temp;
76 	gsize i;
77 
78 	int dir_result;
79 	gboolean cont_result;
80 
81 	dir = g_dirname(file->file_path);
82 	dir_result = g_mkdir_with_parents(dir, 0755);
83 
84 	g_free(dir);
85 	if(dir_result == -1)
86 	{
87 		g_set_error(
88 			error,
89 			g_quark_from_static_string("MAPE_CONFIG_FILE_ERROR"),
90 			errno,
91 			"%s",
92 			g_strerror(errno)
93 		);
94 
95 		return FALSE;
96 	}
97 
98 	content = g_strdup("");
99 	for(i = 0; i < file->entry_count; ++ i)
100 	{
101 		temp = g_strconcat(
102 			content,
103 			file->entries[i].key,
104 			"=",
105 			file->entries[i].value,
106 			"\n",
107 			NULL
108 		);
109 
110 		g_free(content);
111 		content = temp;
112 	}
113 
114 	cont_result = g_file_set_contents(file->file_path, content, -1, error);
115 	g_free(content);
116 
117 	return(cont_result);
118 }
119 
mape_config_file_get_entry_count(MapeConfigFile * file)120 gsize mape_config_file_get_entry_count(MapeConfigFile* file)
121 {
122 	return file->entry_count;
123 }
124 
mape_config_file_get_entry(MapeConfigFile * file,gsize index)125 MapeConfigFileEntry* mape_config_file_get_entry(MapeConfigFile* file,
126                                                 gsize index)
127 {
128 	g_assert(index < file->entry_count);
129 	return &file->entries[index];
130 }
131 
mape_config_file_get_entry_by_key(MapeConfigFile * file,const gchar * key)132 MapeConfigFileEntry* mape_config_file_get_entry_by_key(MapeConfigFile* file,
133                                                        const gchar* key)
134 {
135 	gsize i;
136 	for(i = 0; i < file->entry_count; ++ i)
137 		if(g_strcasecmp(file->entries[i].key, key) == 0)
138 			return &file->entries[i];
139 
140 	return NULL;
141 }
142 
mape_config_file_set_entry(MapeConfigFile * file,const gchar * key,const gchar * value)143 void mape_config_file_set_entry(MapeConfigFile* file,
144                                 const gchar* key,
145                                 const gchar* value)
146 {
147 	MapeConfigFileEntry* entry;
148 	entry = mape_config_file_get_entry_by_key(file, key);
149 
150 	if(entry != NULL)
151 	{
152 		g_free(entry->value);
153 		entry->value = g_strdup(value);
154 	}
155 	else
156 	{
157 		++ file->entry_count;
158 		file->entries = realloc(
159 			file->entries,
160 			sizeof(MapeConfigFileEntry) * file->entry_count
161 		);
162 
163 		entry = &file->entries[file->entry_count - 1];
164 		entry->key = g_strdup(key);
165 		entry->value = g_strdup(value);
166 	}
167 }
168 
mape_config_file_entry_get_key(MapeConfigFileEntry * entry)169 const gchar* mape_config_file_entry_get_key(MapeConfigFileEntry* entry)
170 {
171 	return entry->key;
172 }
173 
mape_config_file_entry_get_value(MapeConfigFileEntry * entry)174 const gchar* mape_config_file_entry_get_value(MapeConfigFileEntry* entry)
175 {
176 	return entry->value;
177 }
178