ARB
ad_config.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : ad_config.cxx //
4 // Purpose : editor configurations (aka species selections) //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in May 2005 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =============================================================== //
11 
12 #include "gb_local.h"
13 
14 #include <ad_config.h>
15 #include <arbdbt.h>
16 
17 #include <arb_strbuf.h>
18 #include <arb_defs.h>
19 #include <arb_strarray.h>
20 
22  /* returns existing configurations in 'configNames'
23  * Note: automatically generates names for configs w/o legal name.
24  */
25 
26  GB_transaction ta(gb_main);
27  GBDATA *gb_config_data = GB_search(gb_main, CONFIG_DATA_PATH, GB_CREATE_CONTAINER);
28 
29  if (gb_config_data) {
30  int unnamed_count = 0;
31 
32  configNames.reserve(GB_number_of_subentries(gb_config_data));
33 
34  for (GBDATA *gb_config = GB_entry(gb_config_data, CONFIG_ITEM);
35  gb_config;
36  gb_config = GB_nextEntry(gb_config))
37  {
38  const char *name = GBT_read_char_pntr(gb_config, "name");
39 
40  if (!name || name[0] == 0) { // no name or empty name
41  char *new_name = GBS_global_string_copy("<unnamed%i>", ++unnamed_count);
42  GB_ERROR error = GBT_write_string(gb_config, "name", new_name);
43 
44  if (error) {
45  GB_warningf("Failed to rename unnamed configuration to '%s'", new_name);
46  freenull(new_name);
47  name = NULp;
48  }
49  else {
50  name = GBT_read_char_pntr(gb_config, "name");
51  }
52  }
53 
54  if (name) configNames.put(name);
55  }
56  }
57 }
58 
60  GBDATA *gb_config_data = GB_search(gb_main, CONFIG_DATA_PATH, GB_DB);
61  GBDATA *gb_config_name = GB_find_string(gb_config_data, "name", name, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
62  return gb_config_name ? GB_get_father(gb_config_name) : NULp;
63 }
64 
65 static GBDATA *findOrCreate_configuration(GBDATA *gb_main, const char *name) {
66  GBDATA *gb_config = GBT_find_configuration(gb_main, name);
67  if (!gb_config) {
68  GBDATA *gb_config_data = GB_search(gb_main, CONFIG_DATA_PATH, GB_DB);
69 
70  gb_config = GB_create_container(gb_config_data, CONFIG_ITEM); // create new container
71  if (gb_config) {
72  GB_ERROR error = GBT_write_string(gb_config, "name", name);
73  if (error) GB_export_error(error);
74  }
75  }
76  return gb_config;
77 }
78 
80  GB_transaction ta(gb_main);
81  GBDATA *gb_config = GBT_find_configuration(gb_main, name);
82 
83  error = NULp;
84  if (!gb_config) {
85  error = GBS_global_string("No such configuration '%s'", name);
86  top_area = NULp;
87  middle_area = NULp;
88  comment = NULp;
89  }
90  else {
91  top_area = GBT_read_string(gb_config, "top_area");
92  middle_area = GBT_read_string(gb_config, "middle_area");
93 
94  if (!top_area || !middle_area) {
95  error = GBS_global_string("Configuration '%s' is corrupted (Reason: %s)", name, GB_await_error());
96  }
97 
98  comment = GBT_read_string(gb_config, "comment");
99  }
100 }
101 
102 GB_ERROR GBT_config::saveAsOver(GBDATA *gb_main, const char *name, const char *oldName, bool warnIfSavingDefault) const {
106  GB_ERROR error = NULp;
107 
108  GB_push_transaction(gb_main);
109 
110  GBDATA *gb_config = findOrCreate_configuration(gb_main, oldName);
111  if (!gb_config) {
112  error = GBS_global_string("Can't create configuration '%s' (Reason: %s)", oldName, GB_await_error());
113  }
114  else {
115  if (strcmp(name, oldName) != 0) error = GBT_write_string(gb_config, "name", name);
116 
117  error = GBT_write_string(gb_config, "top_area", top_area);
118  if (!error) error = GBT_write_string(gb_config, "middle_area", middle_area);
119 
120  if (!error) {
121  if (comment && comment[0]) { // non-empty
122  error = GBT_write_string(gb_config, "comment", comment);
123  }
124  else {
125  GBDATA *gb_comment = GB_entry(gb_config, "comment");
126  if (gb_comment) error = GB_delete(gb_comment); // delete field if comment empty
127  }
128  }
129 
130  if (error) error = GBS_global_string("%s (in configuration '%s')", error, name);
131  }
132 
133  if (warnIfSavingDefault && strcmp(name, DEFAULT_CONFIGURATION) == 0) {
134  GBT_message(gb_main, "Note: You saved the '" DEFAULT_CONFIGURATION "'.\nStarting ARB_EDIT4 will probably overwrite it!");
135  }
136 
137  return GB_end_transaction(gb_main, error);
138 }
139 
141  error = NULp;
142 
143  freenull(item.name);
144  item.type = CI_END_OF_CONFIG;
145 
146  if (config_string[parse_pos]) { // if not at 0-byte
147  char label = config_string[parse_pos+1];
148  item.type = CI_UNKNOWN;
149 
150  switch (label) {
151  case 'L': item.type = CI_SPECIES; break;
152  case 'S': item.type = CI_SAI; break;
153  case 'F': item.type = CI_FOLDED_GROUP; break;
154  case 'G': item.type = CI_GROUP; break;
155  case 'E': item.type = CI_CLOSE_GROUP; break;
156  default: item.type = CI_UNKNOWN; break;
157  }
158 
159  if (item.type == CI_CLOSE_GROUP) {
160  parse_pos += 2;
161  }
162  else {
163  const char *start_of_name = config_string+parse_pos+2;
164  const char *behind_name = strchr(start_of_name, '\1');
165 
166  if (!behind_name) behind_name = strchr(start_of_name, '\0'); // eos
167  gb_assert(behind_name);
168 
169  char *data = ARB_strpartdup(start_of_name, behind_name-1);
170  if (item.type == CI_UNKNOWN) {
171  error = GBS_global_string_copy("Unknown flag '%c' (followed by '%s')", label, data);
172  free(data);
173  }
174  else {
175  item.name = data;
176  parse_pos = behind_name-config_string;
177  }
178  }
179 
180  if (error) { // stop parser
181  const char *end_of_config = strchr(config_string+parse_pos, '\0');
182  parse_pos = end_of_config-config_string;
183  gb_assert(config_string[parse_pos] == 0);
184  }
185  }
186 
187  return item;
188 }
189 
190 void GBT_append_to_config_string(const GBT_config_item& item, struct GBS_strstruct *strstruct) {
191  // strstruct has to be created by GBS_stropen()
192 
193  gb_assert((item.type & (CI_UNKNOWN|CI_END_OF_CONFIG)) == 0);
194 
195  char prefix[] = "\1?";
196  if (item.type == CI_CLOSE_GROUP) {
197  prefix[1] = 'E';
198  GBS_strcat(strstruct, prefix);
199  }
200  else {
201  char label = 0;
202  switch (item.type) {
203  case CI_SPECIES: label = 'L'; break;
204  case CI_SAI: label = 'S'; break;
205  case CI_GROUP: label = 'G'; break;
206  case CI_FOLDED_GROUP: label = 'F'; break;
207 
208  default: gb_assert(0); break;
209  }
210  prefix[1] = label;
211  GBS_strcat(strstruct, prefix);
212  GBS_strcat(strstruct, item.name);
213  }
214 }
215 
216 // --------------------------------------------------------------------------------
217 
218 #ifdef UNIT_TESTS
219 #include <test_unit.h>
220 
221 void TEST_GBT_get_configuration_names() {
222  GB_shell shell;
223  GBDATA *gb_main = GB_open("nosuch.arb", "c");
224 
225  {
226  GB_transaction ta(gb_main);
227 
228  const char *configs[] = { "arb", "BASIC", "Check it", "dummy" };
229  for (size_t i = 0; i<ARRAY_ELEMS(configs); ++i) {
230  TEST_EXPECT_RESULT__NOERROREXPORTED(findOrCreate_configuration(gb_main, configs[i]));
231  }
232 
233  ConstStrArray cnames;
234  GBT_get_configuration_names(cnames, gb_main);
235 
236  TEST_EXPECT_EQUAL(cnames.size(), 4U);
237 
238  char *joined = GBT_join_strings(cnames, '*');
239  TEST_EXPECT_EQUAL(joined, "arb*BASIC*Check it*dummy");
240  free(joined);
241  }
242 
243  GB_close(gb_main);
244 }
245 
246 #endif // UNIT_TESTS
247 
248 
static GBDATA * findOrCreate_configuration(GBDATA *gb_main, const char *name)
Definition: ad_config.cxx:65
const char * GB_ERROR
Definition: arb_core.h:25
GBDATA * GB_open(const char *path, const char *opent)
Definition: ad_load.cxx:1363
void put(const char *elem)
Definition: arb_strarray.h:199
size_t size() const
Definition: arb_strarray.h:85
GBDATA * GB_nextEntry(GBDATA *entry)
Definition: adquery.cxx:339
GB_ERROR GB_end_transaction(GBDATA *gbd, GB_ERROR error)
Definition: arbdb.cxx:2549
#define CONFIG_ITEM
Definition: ad_config.h:25
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
char * ARB_strpartdup(const char *start, const char *end)
Definition: arb_string.h:51
#define ARRAY_ELEMS(array)
Definition: arb_defs.h:19
GBDATA * GB_get_father(GBDATA *gbd)
Definition: arbdb.cxx:1720
GB_ERROR GB_push_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2482
#define DEFAULT_CONFIGURATION
Definition: ad_config.h:27
GB_ERROR GB_delete(GBDATA *&source)
Definition: arbdb.cxx:1904
GB_ERROR GB_export_error(const char *error)
Definition: arb_msg.cxx:259
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:353
GBDATA * GB_create_container(GBDATA *father, const char *key)
Definition: arbdb.cxx:1827
char * GBT_read_string(GBDATA *gb_container, const char *fieldpath)
Definition: adtools.cxx:267
Definition: arbdb.h:78
void GB_warningf(const char *templat,...)
Definition: arb_msg.cxx:490
long GB_number_of_subentries(GBDATA *gbd)
Definition: arbdb.cxx:2880
GBT_CONFIG_ITEM_TYPE type
Definition: ad_config.h:80
#define CONFIG_DATA_PATH
Definition: ad_config.h:24
void GBS_strcat(GBS_strstruct *strstr, const char *ptr)
Definition: arb_strbuf.cxx:108
static void error(const char *msg)
Definition: mkptypes.cxx:96
GB_ERROR saveAsOver(GBDATA *gb_main, const char *name, const char *oldName, bool warnIfSavingDefault) const
Definition: ad_config.cxx:102
GBDATA * GBT_find_configuration(GBDATA *gb_main, const char *name)
Definition: ad_config.cxx:59
char * GBT_join_strings(const CharPtrArray &strings, char separator)
#define gb_assert(cond)
Definition: arbdbt.h:11
GB_ERROR GBT_write_string(GBDATA *gb_container, const char *fieldpath, const char *content)
Definition: adtools.cxx:451
const GBT_config_item & nextItem(GB_ERROR &error)
Definition: ad_config.cxx:140
void GBT_append_to_config_string(const GBT_config_item &item, struct GBS_strstruct *strstruct)
Definition: ad_config.cxx:190
void GBT_message(GBDATA *gb_main, const char *msg)
Definition: adtools.cxx:238
GBDATA * GB_find_string(GBDATA *gbd, const char *key, const char *str, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
Definition: adquery.cxx:302
void GBT_get_configuration_names(ConstStrArray &configNames, GBDATA *gb_main)
Definition: ad_config.cxx:21
#define NULp
Definition: cxxforward.h:97
void reserve(size_t forElems)
Definition: arb_strarray.h:82
GB_transaction ta(gb_var)
GBDATA * gb_main
Definition: adname.cxx:33
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
const char * GBT_read_char_pntr(GBDATA *gb_container, const char *fieldpath)
Definition: adtools.cxx:307
#define TEST_EXPECT_EQUAL(expr, want)
Definition: test_unit.h:1283
GBT_config()
Definition: ad_config.h:38
GBDATA * GB_entry(GBDATA *father, const char *key)
Definition: adquery.cxx:334
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:195
void GB_close(GBDATA *gbd)
Definition: arbdb.cxx:649
static Score ** U
Definition: align.cxx:67
const char * label