ARB
NT_main.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : NT_main.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include "NT_local.h"
12 
13 #include <mg_merge.hxx>
14 #include <awti_import.hxx>
15 #include <insdel.h>
16 #include <macros.hxx>
17 #include <mod_rlimit.h>
18 #include <TreeDisplay.hxx>
19 
20 #include <app.hxx>
21 #include <sel_boxes.hxx>
22 #include <TreeAwars.hxx>
23 
24 #include <aw_advice.hxx>
25 #include <aw_question.hxx>
26 #include <aw_awars.hxx>
27 #include <aw_edit.hxx>
28 #include <aw_file.hxx>
29 #include <aw_msg.hxx>
30 #include <aw_root.hxx>
31 #include <aw_global_awars.hxx>
32 #include <aw_system.hxx>
33 #include <aw_color_groups.hxx>
34 
35 #include <adGene.h>
36 
37 #include <arb_version.h>
38 #include <arb_progress.h>
39 #include <arb_file.h>
40 
41 #include <signal.h>
42 
43 using namespace std;
44 
46 
48 
49 // NT_format_all_alignments may be called after any operation which causes
50 // unformatted alignments (e.g importing sequences)
51 //
52 // It tests all alignments whether they need to be formatted
53 // and asks the user if they should be formatted.
54 
56  GB_ERROR err = NULp;
57  GB_transaction ta(gb_main);
58  GB_topSecurityLevel unsecured(gb_main);
59 
60  long ali_count = GBT_count_alignments(gb_main);
61  if (ali_count) {
62  arb_progress progress("Formatting alignments", ali_count);
63  err = GBT_check_data(gb_main, NULp);
64 
65  AW_repeated_question question;
66  question.add_help("prompt/format_alignments.hlp");
67 
68  GBDATA *gb_presets = GBT_get_presets(gb_main);
69  for (GBDATA *gb_ali = GB_entry(gb_presets, "alignment");
70  gb_ali && !err;
71  gb_ali = GB_nextEntry(gb_ali))
72  {
73  GBDATA *gb_aligned = GB_search(gb_ali, "aligned", GB_INT);
74 
75  if (GB_read_int(gb_aligned) == 0) { // sequences in alignment are not formatted
76  enum FormatAction {
77  FA_ASK_USER = 0, // ask user
78  FA_FORMAT_ALL = 1, // format automatically w/o asking
79  FA_SKIP_ALL = 2, // skip automatically w/o asking
80  };
81  FormatAction format_action = FA_ASK_USER;
82  GBDATA *gb_ali_name = GB_entry(gb_ali, "alignment_name");
83  const char *ali_name = GB_read_char_pntr(gb_ali_name);
84 
85  {
86  bool is_ali_genom = strcmp(ali_name, GENOM_ALIGNMENT) == 0;
87  GBDATA *gb_auto_format = GB_entry(gb_ali, "auto_format");
88 
89  if (gb_auto_format) {
90  format_action = FormatAction(GB_read_int(gb_auto_format));
91  if (is_ali_genom) {
92  if (format_action != FA_SKIP_ALL) {
93  format_action = FA_SKIP_ALL; // always skip ali_genom
94  err = GB_write_int(gb_auto_format, FA_SKIP_ALL);
95  }
96  }
97  }
98  else if (is_ali_genom) {
99  format_action = FA_SKIP_ALL;
100  err = GBT_write_int(gb_ali, "auto_format", FA_SKIP_ALL); // always skip
101  }
102  }
103 
104  bool perform_format = false;
105  if (!err) {
106  switch (format_action) {
107  case FA_FORMAT_ALL: perform_format = true; break;
108  case FA_SKIP_ALL: perform_format = false; break;
109  default: {
110  char *qtext = GBS_global_string_copy("Alignment '%s' is not formatted. Format?", ali_name);
111  int answer = question.get_answer("format_alignments", qtext, "Format,Skip,Always format,Always skip", "all", false);
112 
113  switch (answer) {
114  case 2:
115  err = GBT_write_int(gb_ali, "auto_format", FA_FORMAT_ALL);
116  // fall-through
117  case 0:
118  perform_format = true;
119  break;
120 
121  case 3:
122  err = GBT_write_int(gb_ali, "auto_format", FA_SKIP_ALL);
123  break;
124  }
125 
126  free(qtext);
127  break;
128  }
129  }
130  }
131  if (!err && perform_format) {
132  err = ARB_format_alignment(gb_main, ali_name);
133  }
134  }
135  progress.inc_and_check_user_abort(err);
136  }
137 
138  if (err) progress.done();
139  }
140 
141  err = ta.close(err);
142  return err;
143 }
144 
145 
146 // --------------------------------------------------------------------------------
147 
148 
150  // called once on ARB_NTREE startup
151  arb_progress cons_progress("Checking consistency");
152 
154  if (!err) err = NT_repair_DB(GLOBAL.gb_main);
155 
156  return err;
157 }
158 
159 __ATTR__USERESULT static GB_ERROR startup_mainwindow_and_dbserver(AW_root *aw_root, const char *autorun_macro, TREE_canvas*& result_ntw) {
161 
162  GB_ERROR error = configure_macro_recording(aw_root, "ARB_NT", GLOBAL.gb_main);
163  if (!error) {
164  result_ntw = NT_create_main_window(aw_root);
165  if (GB_is_server(GLOBAL.gb_main)) {
167  if (!error) NT_repair_userland_problems();
168  }
169  }
170 
171  if (!error) {
172  error = GBK_system("arb_macro_compatibility.sh &"); // run async to avoid (DB) lock problems
173  }
174 
175  if (!error && autorun_macro) execute_macro(aw_root, autorun_macro);
176 
177  return error;
178 }
179 
180 static ARB_ERROR load_and_startup_main_window(AW_root *aw_root, const char *autorun_macro) {
181  char *db_server = aw_root->awar(AWAR_DB_PATH)->read_string();
182  GLOBAL.gb_main = GBT_open(db_server, "rw");
183 
185  if (!GLOBAL.gb_main) {
186  error = GB_await_error();
187  }
188  else {
189  aw_root->awar(AWAR_DB_PATH)->write_string(db_server);
190  aw_root->awar(AWAR_SAVED_DB_PATH)->write_string(db_server);
191 
192 #define MAXNAMELEN 35
193  int len = strlen(db_server);
194  if (len>MAXNAMELEN) {
195  char *nameOnly = strrchr(db_server, '/');
196  if (nameOnly) {
197  nameOnly++;
198  len -= (nameOnly-db_server);
199  memmove(db_server, nameOnly, len+1);
200  if (len>MAXNAMELEN) {
201  strcpy(db_server+MAXNAMELEN-3, "...");
202  }
203  }
204  }
205 #if defined(DEBUG)
206  AWT_announce_db_to_browser(GLOBAL.gb_main, GBS_global_string("ARB database (%s)", db_server));
207 #endif // DEBUG
208 
209  TREE_canvas *dummy = NULp;
210  GB_ERROR problem = startup_mainwindow_and_dbserver(aw_root, autorun_macro, dummy);
211  aw_message_if(problem); // no need to terminate ARB
212  }
213 
214  free(db_server);
215  return error;
216 }
217 
218 #define AWAR_DB_FILTER AWAR_DBBASE "/filter"
219 #define AWAR_DB_DIRECTORY AWAR_DBBASE "/directory"
220 
222  AW_root *aw_root = aww->get_root();
223  char *db_server = aw_root->awar(AWAR_DB_PATH)->read_string();
224 
225  if (strlen(db_server)) {
226  if (aw_ask_sure(NULp, GBS_global_string("Are you sure to delete database %s\nNote: there is no way to undelete it afterwards", db_server))) {
227  GB_ERROR error = GB_delete_database(db_server);
228  if (error) {
229  aw_message(error);
230  }
231  else {
232  aw_root->awar(AWAR_DB_FILTER)->touch();
233  }
234  }
235  }
236  else {
237  aw_message("No database selected");
238  }
239  free(db_server);
240 }
241 
243  GLOBAL.aw_root = aw_root;
244 
246  nt_assert(gb_imported == GLOBAL.gb_main); // import-DB should already be used as main-DB
247  GLOBAL.gb_main = gb_imported;
248 
249  TREE_canvas *ntw = NULp;
251 
252  if (aw_root->awar(AWAR_IMPORT_AUTOCONF)->read_int()) {
254  }
255 
256  aw_root->awar(AWAR_TREE_REFRESH)->touch();
257 }
258 
259 static void nt_intro_start_existing(AW_window *aw_intro) {
260  aw_intro->hide();
262  nt_assert(contradicted(error, got_macro_ability(aw_intro->get_root())));
263  if (error) {
264  aw_intro->show();
265  aw_popup_ok(error.deliver());
266  }
267  else {
268  error.expect_no_error();
269  }
270 }
271 
272 static void nt_intro_start_merge(AW_window *aw_intro) {
273  AW_root *aw_root = aw_intro->get_root();
274  const char *dir = aw_root->awar(AWAR_DB_DIRECTORY)->read_char_pntr();
275  char *merge_args = GBS_global_string_copy("'%s' '%s'", dir, dir);
276 
277  NT_confirm_exit_restart_if(aw_root, EXIT_SUCCESS, merge_args); // call arb_ntree as merge-tool on exit
278 }
279 
280 static void nt_intro_start_import(AW_window *aw_intro) {
281  aw_intro->hide();
282 
283  AW_root *aw_root = aw_intro->get_root();
284  aw_root->awar_string(AWAR_DB_PATH)->write_string("noname.arb");
285 
286  AWTI_open_import_window(aw_root, NULp, true, NULp, makeRootCallback(start_main_window_after_import));
288 
289  nt_assert(got_macro_ability(aw_root));
290 }
291 
293  AW_window_simple *aws = new AW_window_simple;
294  aws->init(awr, "ARB_INTRO", "ARB INTRO");
295  aws->load_xfig("arb_intro.fig");
296 
297  aws->at("close");
298  aws->callback(makeWindowCallback(NT_confirm_exit, EXIT_SUCCESS));
299  aws->create_button("EXIT", "Exit", "x");
300 
301  aws->at("help");
302  aws->callback(makeHelpCallback("arb_intro.hlp"));
303  aws->create_button("HELP", "HELP", "H");
304 
306 
307  aws->button_length(0);
308 
309  aws->at("logo");
310  aws->create_button(NULp, "#logo.xpm");
311 
312  aws->at("version");
313  aws->create_button(NULp, GBS_global_string("Version " ARB_VERSION "\n(" ARB_BUILD_DATE ")")); // version + date
314 
315  aws->at("copyright");
316  aws->create_button(NULp, GBS_global_string("(C) 1993-" ARB_BUILD_YEAR));
317 
318  aws->at("old");
319  aws->callback(nt_intro_start_existing);
320  aws->create_autosize_button("OPEN_SELECTED", "OPEN SELECTED", "O");
321 
322  aws->at("del");
323  aws->callback(nt_delete_database);
324  aws->create_autosize_button("DELETE_SELECTED", "DELETE SELECTED");
325 
326  aws->at("new_complex");
327  aws->callback(nt_intro_start_import);
328  aws->create_autosize_button("CREATE_AND_IMPORT", "CREATE AND IMPORT", "I");
329 
330  aws->at("merge");
331  aws->callback(nt_intro_start_merge);
332  aws->create_autosize_button("MERGE_TWO_DATABASES", "MERGE TWO ARB DATABASES", "O");
333 
334  aws->at("expert");
335  aws->create_toggle(AWAR_EXPERT);
336 
337  return aws;
338 }
339 
341  static bool avoid_recursion = false;
342 
343  if (!avoid_recursion) {
344  LocallyModify<bool> flag(avoid_recursion, true);
345 
346  char *value = awr->awar(AWAR_SAVED_DB_PATH)->read_string();
347  char *lslash = strrchr(value, '/');
348 
349  char *name = lslash ? lslash+1 : value;
350 #if defined(DEBUG)
351  printf("writing '%s' to AWAR_DB_NAME\n", name);
352 #endif // DEBUG
353  awr->awar(AWAR_DB_NAME)->write_string(name);
354 
355  if (lslash) { // update value of directory
356  lslash[0] = 0;
357  awr->awar(AWAR_DB_DIRECTORY)->write_string(value);
358  lslash[0] = '/';
359  }
360 
361  free(value);
362  }
363 }
364 
365 class NtreeCommandLine : virtual Noncopyable {
366  int arg_count;
367  char const*const* args;
368 
369  bool help_requested;
370  bool do_import;
371 
372  const char *macro_name;
373 
374 public:
375  NtreeCommandLine(int argc_, char const*const* argv_)
376  : arg_count(argc_-1),
377  args(argv_+1),
378  help_requested(false),
379  do_import(false),
380  macro_name(NULp)
381  {}
382 
383  void shift() { ++args; --arg_count; }
384 
385  int free_args() const { return arg_count; }
386  const char *get_arg(int num) const { return num<arg_count ? args[num] : NULp; }
387 
388  bool wants_help() const { return help_requested; }
389  bool wants_import() const { return do_import; }
390  bool wants_merge() const { return arg_count == 2; }
391 
392  const char *autorun_macro() const { return macro_name; }
393 
394  void print_help(FILE *out) const {
395  fprintf(out,
396  "\n"
397  "arb_ntree version " ARB_VERSION_DETAILED "\n"
398  "(C) 1993-" ARB_BUILD_YEAR " The ARB-project\n"
399  "http://www.arb-home.de/\n"
400  "(version build by: " ARB_BUILD_USER "@" ARB_BUILD_HOST ")\n"
401  "\n"
402  "Possible usage:\n"
403  " arb_ntree => start ARB (intro)\n"
404  " arb_ntree DB => start ARB with DB\n"
405  " arb_ntree DB1 DB2 => merge from DB1 into DB2\n"
406  " arb_ntree --import FILE => import FILE into new database (FILE may be a filemask)\n"
407  "\n"
408  "Additional arguments possible with command lines above:\n"
409  " --execute macroname => execute macro 'macroname' after startup\n"
410  "\n"
411  "Each DB argument may be one of the following:\n"
412  " database.arb -> use existing or new database\n"
413  " \":\" -> connect to database of a running instance of ARB\n"
414  " directory -> prompt for databases inside directory\n"
415  " filemask -> also prompt for DB, but more specific (e.g. \"prot*.arb\")\n"
416  "\n"
417  );
418  }
419 
422 
423  while (!error && arg_count>0 && args[0][0] == '-') {
424  const char *opt = args[0]+1;
425  if (opt[0] == '-') ++opt; // accept '-' or '--'
426  if (strcmp(opt, "help") == 0 || strcmp(opt, "h") == 0) { help_requested = true; }
427  else if (strcmp(opt, "execute") == 0) { shift(); macro_name = *args; }
428  else if (strcmp(opt, "import") == 0) { do_import = true; }
429 
430  // bunch of test switches to provoke various ways to terminate (see also http://bugs.arb-home.de/ticket/538)
431  else if (strcmp(opt, "crash") == 0) { GBK_terminate("crash requested"); }
432  else if (strcmp(opt, "trap") == 0) { arb_assert(0); }
433  else if (strcmp(opt, "sighup") == 0) { raise(SIGHUP); }
434  else if (strcmp(opt, "sigsegv") == 0) { raise(SIGSEGV); }
435  else if (strcmp(opt, "sigterm") == 0) { raise(SIGTERM); }
436  else if (strcmp(opt, "fail") == 0) { exit(EXIT_FAILURE); }
437  else if (strcmp(opt, "exit") == 0) { exit(EXIT_SUCCESS); }
438  // end of test switches ----------------------------------------
439 
440  else error = GBS_global_string("Unknown switch '%s'", args[0]);
441  shift();
442  }
443  // non-switch arguments remain in arg_count/args
444  if (!error) {
445  if (do_import && arg_count != 1) error = "expected exactly one file-name or file-mask behind --import";
446  else if (arg_count>2) error = "too many stray arguments given (max. 2 accepted)";
447  }
448  return error;
449  }
450 };
451 
452 enum ArgType { // args that might be specified on command line (for DB or FILE; see above)
460 };
461 
462 inline bool has_arb_suffix(const char *arg) {
463  const char *suffix = strstr(arg, ".arb");
464  if (suffix) {
465  return strcmp(suffix, ".arb") == 0;
466  }
467  return false;
468 }
469 
470 static ArgType detectArgType(const char *arg) {
471  if (strcmp(arg, ":") == 0) return RUNNING_DB;
472  if (GB_is_directory(arg)) return DIRECTORY;
473  if (strpbrk(arg, "*?")) return FILEMASK;
474  if (has_arb_suffix(arg)) {
475  return GB_is_regularfile(arg) ? EXISTING_DB : NEW_DB;
476  }
477 
478  GB_ERROR load_file_err = GBT_check_arb_file(arg);
479  if (!load_file_err) return EXISTING_DB;
480 
482 }
483 
485 
486 #define ABORTED_BY_USER "aborted by user"
487 
488 static ARB_ERROR check_argument_for_mode(const char *database, char *&browser_startdir, RunMode& mode) {
489  // Check whether 'database' is a
490  // - ARB database
491  // - directory name
492  // - file to import
493  //
494  // Modify 'mode' occordingly.
495  // Set 'browser_startdir'
496 
498  if (mode != IMPORT) {
499  if (!database) mode = BROWSE;
500  else {
501  GB_ERROR load_file_err = GBT_check_arb_file(database);
502  if (load_file_err) {
503  char *full_path = AW_unfold_path("PWD", database);
504 
505  enum Action { LOAD_DB, CONVERT_DB, BROWSE_DB, EXIT, NOIDEA };
506  Action action = NOIDEA;
507  if (GB_is_directory(full_path)) {
508  action = BROWSE_DB;
509  }
510  else {
511  if (!GB_is_regularfile(full_path)) {
512  const char *msg = GBS_global_string("'%s' is neither a known option nor a legal file- or directory-name.\n(Error: %s)",
513  full_path, load_file_err);
514 
515  int ans = aw_question(NULp, msg, "Browser,Exit");
516  action = ans ? EXIT : BROWSE_DB;
517  }
518  else {
519  const char *msg = GBS_global_string("Your file is not an original arb file\n(%s)", load_file_err);
520  action = (Action)aw_question(NULp, msg, "Continue (dangerous),Start Converter,Browser,Exit");
521  }
522  }
523 
524  switch (action) {
525  case CONVERT_DB: mode = IMPORT; break;
526  case LOAD_DB: break;
527  case NOIDEA: nt_assert(0); FALLTHROUGH; // in NDEBUG
528  case EXIT: error = ABORTED_BY_USER; break;
529  case BROWSE_DB: {
530  char *dir = nulldup(full_path);
531  while (dir && !GB_is_directory(dir)) freeset(dir, AW_extract_directory(dir));
532 
533  if (dir) {
535  reassign(browser_startdir, dir);
536  mode = BROWSE;
537  }
538  free(dir);
539  break;
540  }
541 
542  }
543  free(full_path);
544  }
545  }
546  }
547 
548  return error;
549 }
550 
551 class SelectedDatabase : virtual Noncopyable {
552  GBDATA*& gb_main;
553  char *name;
554  ArgType type;
555  char *role;
556 
557  void fix_name() {
558  if (type != RUNNING_DB && name[0]) {
559  const char *changed;
560 
561  if (type == NEW_DB) {
562  changed = GB_unfold_in_directory(GB_getcwd(), name);
563  }
564  else {
565  changed = GB_canonical_path(name);
566  }
567 
568  if (strcmp(name, changed) != 0) {
569  reselect_file(changed);
570  }
571  }
572  }
573 
574 public:
575  SelectedDatabase(GBDATA*& gb_main_, const char *name_, const char *role_)
576  : gb_main(gb_main_),
577  name(ARB_strdup(name_)),
578  type(detectArgType(name)),
579  role(ARB_strdup(role_))
580  {
581  fix_name();
582  }
584  free(role);
585  free(name);
586  }
587 
588  ArgType arg_type() const { return type; }
589 
590  bool needs_to_prompt() const {
591  return type == DIRECTORY || type == FILEMASK || type == UNKNOWN_ARG;
592  }
593 
594  const char *get_fullname() const { return name; }
595  const char *get_nameonly() const {
596  const char *slash = strrchr(name, '/');
597  return slash ? slash+1 : name;
598  }
599  const char *get_role() const { return role; }
600  const char *get_description() const { return GBS_global_string("%s (%s)", get_role(), get_nameonly()); }
601 
602  ArgType get_type() const { return type; }
603 
604  const char *get_dir() const {
605  const char *dir = NULp;
606  switch (type) {
607  case DIRECTORY:
608  dir = get_fullname();
609  break;
610 
611  case NEW_DB:
612  case FILEMASK:
613  case EXISTING_FILE:
614  case EXISTING_DB: {
615  char *dir_copy;
616  GB_split_full_path(name, &dir_copy, NULp, NULp, NULp);
617 
618  static SmartCharPtr dir_store;
619  dir_store = dir_copy;
620 
621  dir = dir_copy;
622  break;
623  }
624  case UNKNOWN_ARG:
625  case RUNNING_DB:
626  dir = ".";
627  break;
628  }
629  return dir;
630  }
631 
632  const char *get_mask() const {
633  const char *mask;
634  switch (type) {
635  case FILEMASK: {
636  char *mask_copy;
637  GB_split_full_path(name, NULp, &mask_copy, NULp, NULp);
638 
639  static SmartCharPtr mask_store;
640  mask_store = mask_copy;
641 
642  mask = mask_copy;
643  break;
644  }
645  default:
646  mask = ".arb";
647  break;
648  }
649  return mask;
650  }
651 
652  void reselect_file(const char *file) {
653  freedup(name, file);
654  type = detectArgType(name);
655  fix_name();
656  }
657  void reselect_from_awar(AW_root *aw_root, const char *awar_name) {
658  if (awar_name) {
659  const char *file = aw_root->awar(awar_name)->read_char_pntr();
660  if (file) reselect_file(file);
661  }
662  }
663 
664  GB_ERROR open_db_for_merge(bool is_source_db);
665  void close_db() { if (gb_main) GB_close(gb_main); }
666 };
667 
669  GB_ERROR error = NULp;
670  const char *openMode = "rw";
671 
672  switch (get_type()) {
673  case DIRECTORY:
674  case FILEMASK:
675  GBK_terminate("Program logic error (should have been prompted for explicit DB name)");
676  break;
677 
678  case UNKNOWN_ARG:
679  case EXISTING_FILE:
680  error = GBS_global_string("'%s' is no arb-database", get_fullname());
681  break;
682 
683  case NEW_DB:
684  if (is_source_db) {
685  error = GBS_global_string("'%s' has to exist", get_fullname());
686  break;
687  }
688  openMode = "crw"; // allow to create DB
689  break;
690 
691  case EXISTING_DB:
692  case RUNNING_DB:
693  break;
694  }
695 
696  if (!error) {
697  gb_main = GBT_open(get_fullname(), openMode);
698  if (!gb_main) error = GB_await_error();
699  else {
700  IF_DEBUG(AWT_announce_db_to_browser(gb_main, get_description()));
701  }
702  }
703 
704  return error;
705 }
706 
707 struct merge_scheme : virtual Noncopyable {
710 
711  char *awar_src;
712  char *awar_dst;
713 
715 
717  : src(src_),
718  dst(dst_),
719  awar_src(NULp),
720  awar_dst(NULp),
721  error(NULp)
722  {}
724  if (error) {
725  src->close_db();
726  dst->close_db();
727  }
728  delete src;
729  delete dst;
730  free(awar_src);
731  free(awar_dst);
732  }
733 
734 
735  void open_dbs() {
736  if (!error) error = src->open_db_for_merge(true);
737  if (!error) error = dst->open_db_for_merge(false);
738  }
739 
740  void fix_dst(AW_root *aw_root) { dst->reselect_from_awar(aw_root, awar_dst); }
741  void fix_src(AW_root *aw_root) { src->reselect_from_awar(aw_root, awar_src); }
742 
743  bool knows_dbs() const { return !src->needs_to_prompt() && !dst->needs_to_prompt(); }
744 };
745 
746 static bool merge_tool_running_as_client = true; // default to safe state (true avoids call of 'arb_clean' at exit)
747 __ATTR__NORETURN static void exit_from_merge(const char *restart_args) {
748  // if 'restart_args' is null (or an empty string) => do not restart
749  //
750  // Note: macro will already have terminated here (see logic in MG_confirm_exit_restart_if)
751 
752  if (merge_tool_running_as_client) { // there is a main ARB running
753  NT_start_if(restart_args);
754  exit(EXIT_SUCCESS); // exit w/o killing clients (in contrast to else-branch)
755  }
756  else {
757  // Note: this branch also kills all client processes
759  }
760  // expected to be never reached. Anyway: caller chain will terminate
761  // (in MacroExitor::perform_exit_or_terminate) if this function returns.
762 }
763 
765  fputs("Error: merge aborted by user\n", stderr);
767 }
768 
770  AW_window_simple *aw_msg = new AW_window_simple;
771 
772  aw_msg->init(aw_root, "arb_merge_error", "ARB merge error");
773  aw_msg->recalc_size_atShow(AW_RESIZE_DEFAULT); // force size recalc (ignores user size)
774 
775  aw_msg->at(10, 10);
776  aw_msg->auto_space(10, 10);
777 
778  aw_msg->create_autosize_button(NULp, error, "", 2);
779  aw_msg->at_newline();
780 
781  aw_msg->callback(merge_startup_abort_cb);
782  aw_msg->create_autosize_button("OK", "Ok", "O", 2);
783 
784  aw_msg->window_fit();
785 
786  return aw_msg;
787 }
788 static AW_window *startup_merge_main_window(AW_root *aw_root, merge_scheme *ms, const char *autorun_macro) {
789  ms->fix_src(aw_root);
790  ms->fix_dst(aw_root);
791 
792  if (ms->knows_dbs()) {
793  ms->open_dbs();
794  }
795  else {
796  ms->error = "Need two databases to merge";
797  }
798 
799  AW_window *aw_result;
800  if (!ms->error) {
802  AW_init_color_group_defaults("arb_ntree");
803 
804  bool dst_is_new = ms->dst->arg_type() == NEW_DB;
805  aw_result = MERGE_create_main_window(aw_root, dst_is_new, exit_from_merge);
806 
807  nt_assert(got_macro_ability(aw_root));
808 
809  if (autorun_macro) {
810  execute_macro(aw_root, autorun_macro);
811  }
812  }
813  else {
814  aw_result = merge_startup_error_window(aw_root, ms->error);
815  }
816  delete ms; // was allocated in startup_gui()
817  return aw_result;
818 }
819 
820 static AW_window *startup_merge_prompting_for_nonexplicit_dst_db(AW_root *aw_root, merge_scheme *ms, const char *autorun_macro) {
821  AW_window *aw_result;
822  if (ms->dst->needs_to_prompt()) {
823  aw_result = awt_create_load_box(aw_root, "Select", ms->dst->get_role(),
824  ms->dst->get_dir(), ms->dst->get_mask(),
825  &(ms->awar_dst),
826  AW_window::makeWindowReplacer(makeCreateWindowCallback(startup_merge_main_window, ms, autorun_macro)),
827  makeWindowCallback(merge_startup_abort_cb), "Cancel");
828  }
829  else {
830  aw_result = startup_merge_main_window(aw_root, ms, autorun_macro);
831  }
832  return aw_result;
833 }
834 
835 static AW_window *startup_merge_prompting_for_nonexplicit_dbs(AW_root *aw_root, merge_scheme *ms, const char *autorun_macro) {
836  // if src_spec or dst_spec needs to be prompted for -> startup prompters with callbacks bound to continue
837  // otherwise just startup merge
838 
839  AW_window *aw_result;
840  if (ms->src->needs_to_prompt()) {
841  aw_result = awt_create_load_box(aw_root, "Select", ms->src->get_role(),
842  ms->src->get_dir(), ms->src->get_mask(),
843  &(ms->awar_src),
844  AW_window::makeWindowReplacer(makeCreateWindowCallback(startup_merge_prompting_for_nonexplicit_dst_db, ms, autorun_macro)),
845  makeWindowCallback(merge_startup_abort_cb), "Cancel");
846  }
847  else {
848  aw_result = startup_merge_prompting_for_nonexplicit_dst_db(aw_root, ms, autorun_macro);
849  }
850  return aw_result;
851 }
852 
854  {
855  char *message = ARB_strdup(GB_path_in_ARBLIB("message"));
856  char *stamp = ARB_strdup(GB_path_in_arbprop("msgtime"));
857  if (GB_time_of_file(message)>GB_time_of_file(stamp)) {
858  AW_edit(message);
859  AW_system(GBS_global_string("touch %s", stamp));
860  }
861  free(stamp);
862  free(message);
863  }
864 
865  // create some early awars
866  // Note: normally you don't like to add your awar-init-function here, but into nt_create_all_awars()
867 
868  AW_root* aw_root = GLOBAL.aw_root;
869 
870  AW_create_fileselection_awars(aw_root, AWAR_DBBASE, "", ".arb", "noname.arb"); // creates AWAR_DB_PATH
871  aw_root->awar_string(AWAR_DB_NAME, "noname.arb");
872 
873  aw_root->awar_int(AWAR_EXPERT, 0);
874 
876 
879 
880  aw_root->setUserActionTracker(new NullTracker); // no macro recording inside prompters that may popup
881  if (!error) {
882  nt_assert(!cl.wants_help());
883 
884  RunMode mode = NORMAL;
885 
886  if (cl.wants_merge()) mode = MERGE;
887  else if (cl.wants_import()) mode = IMPORT;
888 
889  if (mode == MERGE) {
891 
892  merge_scheme *ms = new merge_scheme( // freed in startup_merge_main_window()
893  new SelectedDatabase(GLOBAL_gb_src, cl.get_arg(0), "Source DB for merge"),
894  new SelectedDatabase(GLOBAL_gb_dst, cl.get_arg(1), "Destination DB for merge"));
895 
897 
898  if (ms->src->arg_type() == RUNNING_DB && ms->dst->arg_type() == RUNNING_DB) {
899  error = "You cannot merge from running to running DB";
900  }
901  else {
902  aw_root->setUserActionTracker(new NullTracker); // no macro recording during startup of merge tool (file prompts)
904 
905  nt_assert(contradicted(aww, error));
906 
907  if (!error) {
908  aww->show();
909  aw_root->main_loop();
910  nt_assert(0);
911  }
912  }
913  }
914  else {
915  const char *database = NULp;
916  char *browser_startdir = ARB_strdup(".");
917 
918  if (cl.free_args() > 0) database = cl.get_arg(0);
919 
920  error = check_argument_for_mode(database, browser_startdir, mode);
921  if (!error) {
922  if (mode == IMPORT) {
923  AWTI_open_import_window(aw_root, database, true, NULp, makeRootCallback(start_main_window_after_import));
925 
926  nt_assert(got_macro_ability(aw_root));
927  aw_root->main_loop();
928  }
929  else if (mode == NORMAL) {
930  aw_root->awar(AWAR_DB_PATH)->write_string(database);
931  error = load_and_startup_main_window(aw_root, cl.autorun_macro());
932  if (!error) {
933  nt_assert(got_macro_ability(aw_root));
934  aw_root->main_loop();
935  }
936  }
937  else if (mode == BROWSE) {
938  aw_root->awar(AWAR_DB_DIRECTORY)->write_string(browser_startdir);
939  char *latest = GB_find_latest_file(browser_startdir, "/\\.(arb|a[0-9]{2})$/");
940  if (latest) {
941  int l = strlen(latest);
942  strcpy(latest+l-3, "arb");
943  aw_root->awar(AWAR_DB_PATH)->write_string(latest);
944  free(latest);
945  }
946  nt_create_intro_window(aw_root)->show();
947  aw_root->setUserActionTracker(new NullTracker); // no macro recording inside intro window
948  aw_root->main_loop();
949  }
950  }
951  free(browser_startdir);
952  }
953  }
954 
955  if (error) {
956  const char *msg = error.preserve();
957  if (strcmp(msg, ABORTED_BY_USER) != 0) aw_popup_ok(msg);
958  }
959 }
960 
961 int ARB_main(int argc, char *argv[]) {
962  {
963  // i really dont want 'arb_ntree --help' to startup the GUI
964  // hack: parse CL twice
965  NtreeCommandLine cl(argc, argv);
966  bool cl_ok = !cl.parse().deliver();
967  if (cl_ok) {
968  if (cl.wants_help()) {
969  cl.print_help(stderr);
970  return EXIT_SUCCESS;
971  }
972  }
973  }
974 
975  aw_initstatus();
976  GB_set_verbose();
977 
978  GB_shell shell;
979  AW_root *aw_root = AWT_create_root("ntree.arb", "ARB_NT", need_macro_ability());
980 
981  GLOBAL.aw_root = aw_root;
982 
983  NtreeCommandLine cl(argc, argv);
984  ARB_ERROR error = cl.parse();
985 
986  if (!error) {
987  if (cl.wants_help()) {
988  cl.print_help(stderr);
989  }
990  else {
991  ModRLimit increase_stacksize(RLIMIT_STACK, TREEDISP_STACKSIZE);
992  startup_gui(cl, error);
993  }
994  }
995 
996  int exitcode = EXIT_SUCCESS;
997  if (error) {
998  exitcode = EXIT_FAILURE;
999  fprintf(stderr, "arb_ntree: Error: %s\n", error.deliver());
1000  }
1001  else {
1002  error.expect_no_error();
1003  }
1004 
1005  delete aw_root;
1006 
1007  return exitcode;
1008 }
1009 
void reselect_file(const char *file)
Definition: NT_main.cxx:652
GBDATA * AWTI_acquire_imported_DB_and_cleanup_importer(AW_root *awr)
static __ATTR__USERESULT GB_ERROR startup_mainwindow_and_dbserver(AW_root *aw_root, const char *autorun_macro, TREE_canvas *&result_ntw)
Definition: NT_main.cxx:159
GB_ERROR GBK_system(const char *system_command)
Definition: arb_msg.cxx:571
#define arb_assert(cond)
Definition: arb_assert.h:245
const char * GB_ERROR
Definition: arb_core.h:25
#define AWAR_DB_NAME
Definition: aw_awar_defs.hxx:6
GB_TYPES type
bool wants_merge() const
Definition: NT_main.cxx:390
const char * get_dir() const
Definition: NT_main.cxx:604
#define AWAR_SAVED_DB_PATH
void MERGE_create_db_file_awars(AW_root *awr, AW_default aw_def, const char *src_name, const char *dst_name)
Definition: MG_main.cxx:421
static GB_ERROR nt_check_database_consistency()
Definition: NT_main.cxx:149
#define AWAR_DB_DIRECTORY
Definition: NT_main.cxx:219
GB_ERROR preserve() const
Definition: arb_error.h:143
GB_CSTR GB_path_in_arbprop(const char *relative_path)
Definition: adsocket.cxx:1157
const char * get_mask() const
Definition: NT_main.cxx:632
void AWT_initTreeAwarRegistry(GBDATA *gbmain)
Definition: TreeAwars.cxx:189
void NT_create_config_after_import(TREE_canvas *ntw, bool imported_from_scratch)
Definition: NT_edconf.cxx:1328
const char * get_role() const
Definition: NT_main.cxx:599
long GB_read_int(GBDATA *gbd)
Definition: arbdb.cxx:729
ArgType arg_type() const
Definition: NT_main.cxx:588
bool wants_import() const
Definition: NT_main.cxx:389
bool GB_is_server(GBDATA *gbd)
Definition: adcomm.cxx:1697
bool knows_dbs() const
Definition: NT_main.cxx:743
void load_xfig(const char *file, bool resize=true)
Definition: AW_window.cxx:729
const char * get_arg(int num) const
Definition: NT_main.cxx:386
SelectedDatabase(GBDATA *&gb_main_, const char *name_, const char *role_)
Definition: NT_main.cxx:575
int GBT_count_alignments(GBDATA *gb_main)
Definition: adali.cxx:34
bool needs_to_prompt() const
Definition: NT_main.cxx:590
void AW_edit(const char *path)
Definition: AW_edit.cxx:16
void print_help(FILE *out) const
Definition: NT_main.cxx:394
void open_dbs()
Definition: NT_main.cxx:735
#define ARB_BUILD_USER
Definition: arb_build.h:6
GBDATA * GB_nextEntry(GBDATA *entry)
Definition: adquery.cxx:339
void AWTI_set_importDB_pointer(GBDATA *&dbPtr)
void aw_initstatus()
Definition: AW_status.cxx:966
static AW_window * merge_startup_error_window(AW_root *aw_root, GB_ERROR error)
Definition: NT_main.cxx:769
bool wants_help() const
Definition: NT_main.cxx:388
void AW_create_standard_fileselection(AW_window *aws, const char *awar_prefix)
Definition: aw_file.hxx:30
#define ARB_VERSION_DETAILED
Definition: arb_build.h:2
GB_ERROR GB_delete_database(GB_CSTR filename)
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
static void nt_intro_start_import(AW_window *aw_intro)
Definition: NT_main.cxx:280
long read_int() const
Definition: AW_awar.cxx:184
Action
Definition: NT_taxonomy.cxx:36
static WindowCallback makeWindowReplacer(const CreateWindowCallback &cwcb)
Definition: aw_window.hxx:573
#define MAXNAMELEN
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
AW_root * awr
Definition: canvas.hxx:348
AW_root * aw_root
Definition: NT_local.h:36
static void nt_intro_start_merge(AW_window *aw_intro)
Definition: NT_main.cxx:272
static void nt_intro_start_existing(AW_window *aw_intro)
Definition: NT_main.cxx:259
STL namespace.
#define ARB_VERSION
Definition: arb_build.h:1
void NT_confirm_exit(AW_window *aws, int exitcode)
Definition: NT_extern.cxx:402
NtreeCommandLine(int argc_, char const *const *argv_)
Definition: NT_main.cxx:375
#define ARB_BUILD_HOST
Definition: arb_build.h:5
#define EXIT_SUCCESS
Definition: arb_a2ps.c:154
static ARB_ERROR check_argument_for_mode(const char *database, char *&browser_startdir, RunMode &mode)
Definition: NT_main.cxx:488
__ATTR__USERESULT GB_ERROR configure_macro_recording(AW_root *aw_root, const char *client_id, GBDATA *gb_main)
Definition: trackers.cxx:502
const char * get_fullname() const
Definition: NT_main.cxx:594
bool has_arb_suffix(const char *arg)
Definition: NT_main.cxx:462
static void start_main_window_after_import(AW_root *aw_root)
Definition: NT_main.cxx:242
GB_CSTR GB_canonical_path(const char *anypath)
Definition: adsocket.cxx:991
void AW_init_color_group_defaults(const char *for_program)
Definition: AW_preset.cxx:1115
void NT_exit_now_restart_if(AW_root *aw_root, int exitcode, const char *restart_ntree_args)
Definition: NT_extern.cxx:351
GBDATA * GBT_open(const char *path, const char *opent)
Definition: adtools.cxx:524
GBDATA * GLOBAL_gb_dst
Definition: MG_main.cxx:31
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
void setUserActionTracker(UserActionTracker *user_tracker)
Definition: AW_root.cxx:211
#define AWAR_DB_FILTER
Definition: NT_main.cxx:218
GB_ERROR open_db_for_merge(bool is_source_db)
Definition: NT_main.cxx:668
ARB_ERROR parse()
Definition: NT_main.cxx:420
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
void AW_system(const char *command)
Definition: AW_help.cxx:32
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
static AW_root * SINGLETON
Definition: aw_root.hxx:102
void show()
Definition: AW_window.cxx:1704
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
GB_ERROR ARB_format_alignment(GBDATA *Main, const char *alignment_name)
Definition: insdel.cxx:1439
AW_root * AWT_create_root(const char *properties, const char *program, UserActionTracker *user_tracker)
static void merge_startup_abort_cb(AW_window *)
Definition: NT_main.cxx:764
#define ARB_BUILD_YEAR
Definition: arb_build.h:4
GB_ERROR deliver() const
Definition: arb_error.h:116
void AWT_install_cb_guards()
void MERGE_create_all_awars(AW_root *awr, AW_default aw_def)
Definition: MG_main.cxx:370
void aw_popup_ok(const char *msg)
void recalc_size_atShow(enum AW_SizeRecalc sr)
Definition: AW_window.cxx:1461
int ARB_main(int argc, char *argv[])
Definition: NT_main.cxx:961
#define AWAR_DB_PATH
Definition: aw_awar_defs.hxx:5
void GBK_terminate(const char *error) __ATTR__NORETURN
Definition: arb_msg.cxx:509
static AW_window * startup_merge_prompting_for_nonexplicit_dst_db(AW_root *aw_root, merge_scheme *ms, const char *autorun_macro)
Definition: NT_main.cxx:820
unsigned long GB_time_of_file(const char *path)
Definition: arb_file.cxx:44
char * GB_find_latest_file(const char *dir, const char *mask)
Definition: adfile.cxx:152
#define false
Definition: ureadseq.h:13
static ARB_ERROR load_and_startup_main_window(AW_root *aw_root, const char *autorun_macro)
Definition: NT_main.cxx:180
static bool merge_tool_running_as_client
Definition: NT_main.cxx:746
merge_scheme(SelectedDatabase *src_, SelectedDatabase *dst_)
Definition: NT_main.cxx:716
void message(char *errortext)
static char const * macro_name
Definition: mkptypes.cxx:81
void touch()
Definition: AW_awar.cxx:207
SelectedDatabase * dst
Definition: NT_main.cxx:709
AW_window * MERGE_create_main_window(AW_root *aw_root, bool dst_is_new, __ATTR__NORETURN void(*exit_cb)(const char *))
Definition: MG_main.cxx:179
void NT_start_if(const char *arb_ntree_args)
Definition: NT_extern.cxx:343
static void error(const char *msg)
Definition: mkptypes.cxx:96
#define AWAR_TREE_REFRESH
void AW_create_fileselection_awars(AW_root *awr, const char *awar_base, const char *directories, const char *filter, const char *file_name)
Definition: AW_file.cxx:72
#define ABORTED_BY_USER
Definition: NT_main.cxx:486
AW_HEADER_MAIN NT_global GLOBAL
Definition: NT_main.cxx:47
void fix_dst(AW_root *aw_root)
Definition: NT_main.cxx:740
void expect_no_error() const
Definition: arb_error.h:138
static ArgType detectArgType(const char *arg)
Definition: NT_main.cxx:470
#define AWAR_DBBASE
Definition: aw_awar_defs.hxx:4
SelectedDatabase * src
Definition: NT_main.cxx:708
#define AWAR_IMPORT_AUTOCONF
Definition: awti_import.hxx:26
void execute_macro(AW_root *root, const char *macroname)
Definition: macro_gui.cxx:242
ArgType
Definition: NT_main.cxx:452
static AW_window * nt_create_intro_window(AW_root *awr)
Definition: NT_main.cxx:292
char * AW_unfold_path(const char *pwd_envar, const char *path)
Definition: AW_file.cxx:51
UserActionTracker * need_macro_ability()
Definition: trackers.cxx:498
char * read_string() const
Definition: AW_awar.cxx:198
GB_CSTR GB_path_in_ARBLIB(const char *relative_path)
Definition: adsocket.cxx:1147
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:568
GB_CSTR GB_getcwd(void)
Definition: adfile.cxx:24
#define GENOM_ALIGNMENT
Definition: adGene.h:19
#define EXIT_FAILURE
Definition: arb_a2ps.c:157
GB_ERROR GB_write_int(GBDATA *gbd, long i)
Definition: arbdb.cxx:1250
GBDATA * GLOBAL_gb_src
Definition: MG_main.cxx:30
#define nt_assert(cond)
Definition: NT_local.h:27
static AW_window * startup_merge_main_window(AW_root *aw_root, merge_scheme *ms, const char *autorun_macro)
Definition: NT_main.cxx:788
TYPE get_type() const
Definition: probe_tree.h:64
bool got_macro_ability(AW_root *aw_root)
Definition: trackers.cxx:529
long int flag
Definition: f2c.h:39
#define AW_HEADER_MAIN
Definition: aw_window.hxx:36
static AW_window * startup_merge_prompting_for_nonexplicit_dbs(AW_root *aw_root, merge_scheme *ms, const char *autorun_macro)
Definition: NT_main.cxx:835
void ARB_declare_global_awars(AW_root *aw_root, AW_default aw_def)
bool aw_ask_sure(const char *unique_id, const char *msg)
void main_loop()
Definition: AW_root.cxx:639
int aw_question(const char *unique_id, const char *question, const char *buttons, bool sameSizeButtons, const char *helpfile)
Definition: AW_question.cxx:26
fputs(TRACE_PREFIX, stderr)
#define ARB_BUILD_DATE
Definition: arb_build.h:3
int free_args() const
Definition: NT_main.cxx:385
TREE_canvas * NT_create_main_window(AW_root *aw_root)
Definition: NT_extern.cxx:1830
ArgType get_type() const
Definition: NT_main.cxx:602
const char * get_nameonly() const
Definition: NT_main.cxx:595
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:594
GB_CSTR GB_unfold_in_directory(const char *relative_directory, const char *path)
Definition: adsocket.cxx:1114
GB_ERROR close(GB_ERROR error)
Definition: arbdbpp.cxx:35
static void nt_delete_database(AW_window *aww)
Definition: NT_main.cxx:221
bool GB_is_directory(const char *path)
Definition: arb_file.cxx:176
static __ATTR__NORETURN void exit_from_merge(const char *restart_args)
Definition: NT_main.cxx:747
#define __ATTR__USERESULT
Definition: attributes.h:58
GB_ERROR NT_format_all_alignments(GBDATA *gb_main)
Definition: NT_main.cxx:55
#define TREEDISP_STACKSIZE
Definition: TreeDisplay.hxx:32
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
GB_ERROR error
Definition: NT_main.cxx:714
void hide()
Definition: AW_window.cxx:1856
GB_ERROR NT_repair_DB(GBDATA *gb_main)
AW_root * get_root()
Definition: aw_window.hxx:359
void GB_set_verbose()
Definition: ad_load.cxx:31
void GB_split_full_path(const char *fullpath, char **res_dir, char **res_fullname, char **res_name_only, char **res_suffix)
Definition: adsocket.cxx:1259
#define NULp
Definition: cxxforward.h:116
GBDATA * gb_main
Definition: NT_local.h:37
bool GB_is_regularfile(const char *path)
Definition: arb_file.cxx:76
FormatAction
Definition: AWTI_edit.cxx:35
void reselect_from_awar(AW_root *aw_root, const char *awar_name)
Definition: NT_main.cxx:657
void fix_src(AW_root *aw_root)
Definition: NT_main.cxx:741
char * awar_src
Definition: NT_main.cxx:711
#define __ATTR__NORETURN
Definition: attributes.h:56
GB_ERROR write_string(const char *aw_string)
static void startup_gui(NtreeCommandLine &cl, ARB_ERROR &error)
Definition: NT_main.cxx:853
void AWTI_open_import_window(AW_root *awr, const char *def_importname, bool do_exit, GBDATA *gb_main, const RootCallback &after_import_cb)
#define FALLTHROUGH
Definition: cxxforward.h:136
char * AW_extract_directory(const char *path)
Definition: AW_file.cxx:59
const char * autorun_macro() const
Definition: NT_main.cxx:392
GB_transaction ta(gb_var)
GB_ERROR GBT_write_int(GBDATA *gb_container, const char *fieldpath, long content)
Definition: adtools.cxx:471
GB_CSTR GB_read_char_pntr(GBDATA *gbd)
Definition: arbdb.cxx:904
#define AWAR_EXPERT
GBDATA * gb_main
Definition: adname.cxx:32
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:584
GB_ERROR GBT_check_data(GBDATA *Main, const char *alignment_name)
Definition: adali.cxx:218
AW_window * aww
Definition: canvas.hxx:347
GBDATA * GBT_get_presets(GBDATA *gb_main)
Definition: adali.cxx:30
#define IF_DEBUG(x)
Definition: arb_assert.h:303
GB_ERROR GBT_check_arb_file(const char *name)
Definition: ad_load.cxx:1369
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
AW_window * awt_create_load_box(AW_root *aw_root, const char *action, const char *what, const char *default_directory, const char *file_extension, char **set_file_name_awar, const WindowCallback &ok_cb, const WindowCallback &close_cb, const char *close_button_text)
Definition: sel_boxes.cxx:896
RunMode
Definition: NT_main.cxx:484
const char * get_description() const
Definition: NT_main.cxx:600
void NT_confirm_exit_restart_if(AW_root *aw_root, int exitcode, const char *restart_ntree_args)
Definition: NT_extern.cxx:389
void NT_repair_userland_problems(void)
static void AWAR_DB_PATH_changed_cb(AW_root *awr)
Definition: NT_main.cxx:340
#define AW_ROOT_DEFAULT
Definition: aw_base.hxx:106
char * awar_dst
Definition: NT_main.cxx:712
GBDATA * GB_entry(GBDATA *father, const char *key)
Definition: adquery.cxx:334
void inc_and_check_user_abort(GB_ERROR &error)
Definition: arb_progress.h:332
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
void GB_close(GBDATA *gbd)
Definition: arbdb.cxx:655
Definition: arbdb.h:66