ARB
adlang1.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : adlang1.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include "gb_aci_impl.h"
12 #include "gb_key.h"
13 
14 #include "TreeNode.h"
15 
16 #include <aw_awar_defs.hxx>
17 
18 #include <adGene.h>
19 #include <ad_cb.h>
20 
21 #include <arb_defs.h>
22 #include <arb_strbuf.h>
23 #include <arb_file.h>
24 #include <arb_strarray.h>
25 #include <arb_sort.h>
26 
27 #include <cctype>
28 #include <cmath>
29 #include <algorithm>
30 
31 // hook for 'export_sequence'
32 
34 
36  gb_assert(!get_export_sequence || !escb); // avoid unwanted overwrite
37  get_export_sequence = escb;
38 }
39 
40 using namespace GBL_IMPL;
41 
42 namespace GBL_IMPL {
43  // global ACI/SRT debug switch
44  int traceACI = 0;
45  int traceIndent = 0;
46 
47  void print_trace(const char *text) {
48  FILE *DUMPOUT = stdout;
49 
50  gb_assert(traceACI>0);
51  if (traceIndent>0) {
53  GBT_split_string(line, text, "\n", SPLIT_DROPEMPTY);
54  for (unsigned L = 0; L<line.size(); ++L) {
55  for (int i = 0; i<traceIndent; ++i) {
56  fputc(' ', DUMPOUT);
57  }
58  fputs(line[L], DUMPOUT);
59  fputc('\n', DUMPOUT);
60  }
61  }
62  else {
63  fputs(text, DUMPOUT);
64  }
65  fflush(DUMPOUT);
66  }
67 
68  GB_ERROR trace_params(const GBL_streams& param, gbl_param *ppara, const char *com) {
70  int i;
71 
72  int argc = param.size();
73  for (i=0; i<argc; i++) {
74  gbl_param *para;
75  const char *argument = param.get(i);
76 
77  for (para = ppara; para && !error; para = para->next) {
78  if (para->param_name) { // NULp means param is inactive (see PARAM_IF)
79  int len = strlen(para->param_name);
80 
81  if (strncmp(argument, para->param_name, len) == 0) {
82  const char *value = argument+len; // set to start of value
83 
84  if (para->type == GB_BIT) {
85  // GB_BIT is special cause param_name does NOT contain trailing '='
86 
87  if (!value[0]) { // only 'name' -> handle like 'name=1'
88  ;
89  }
90  else if (value[0] == '=') {
91  value++;
92  }
93  }
94 
95  switch (para->type) {
96  case GB_STRING:
97  *(const char **)para->varaddr = value;
98  break;
99 
100  case GB_INT:
101  STATIC_ASSERT(sizeof(int) == sizeof(nat)); // assumed by GBL_PARAM_UINT
102  *(int *)para->varaddr = atoi(value);
103  break;
104 
105  case GB_BIT:
106  // 'param=' is same as 'param' or 'param=1' (historical reason, don't change)
107  *(int *)para->varaddr = (value[0] ? atoi(value) : 1);
108  break;
109 
110  case GB_BYTE:
111  *(char *)para->varaddr = *value; // this may use the terminal zero-byte (e.g. for p1 in 'p0=0,p1=,p2=2' )
112  if (value[0] && value[1]) { // found at least 2 chars
113  GB_warningf("Only one character expected in value '%s' of param '%s' - rest is ignored", value, para->param_name);
114  }
115  break;
116 
117  default:
118  gb_assert(0);
119  error = GBS_global_string("Parameter '%s': Unknown type %i (internal error)", para->param_name, para->type);
120  break;
121  }
122  break; // accept parameter
123  }
124  }
125  }
126 
127  if (!error && !para) { // no parameter found for argument
128  int pcount = 0;
129  for (para = ppara; para; para = para->next) pcount++;
130 
131  gbl_param **params;
132  ARB_calloc(params, pcount);
133  {
134  int k;
135  for (k = 0, para = ppara; para; para = para->next) params[k++] = para;
136  }
137 
138  GBS_strstruct str(1000);
139 
140  for (pcount--; pcount>=0; pcount--) {
141  para = params[pcount];
142  if (para->param_name) {
143  str.cat(" ");
144  str.cat(para->param_name);
145  switch (para->type) {
146  case GB_STRING: str.cat("STRING"); break;
147  case GB_INT: str.cat("INT"); break;
148  case GB_FLOAT: str.cat("FLOAT"); break;
149  case GB_BYTE: str.cat("CHAR"); break;
150  case GB_BIT: str.cat(" "); break;
151  default: str.cat("????"); gb_assert(0); break;
152  }
153  str.cat("\t\t;");
154  str.cat(para->help_text);
155  str.cat("\n");
156  }
157  }
158 
159  freenull(params);
160 
161  return GB_export_errorf("Unknown Parameter '%s' in command '%s'\n PARAMETERS:\n%s",
162  argument, com, str.get_data());
163  }
164  }
165 
166  return error;
167  }
168 };
169 
170 
171 
172 // -------------------------
173 // String functions
174 
175 static int gbl_stricmp(const char *s1, const char *s2) {
176  // case insensitive strcmp
177  int i;
178  for (i = 0; ; ++i) {
179  char c1 = tolower(s1[i]);
180  char c2 = tolower(s2[i]);
181 
182  if (c1 == c2) {
183  if (!c1) break; // equal strings
184  }
185  else {
186  if (c1<c2) return -1;
187  return 1;
188  }
189  }
190  return 0;
191 }
192 static int gbl_strincmp(const char *s1, const char *s2, int size2) {
193  // case insensitive strcmp
194  int i;
195  for (i = 0; i<size2; ++i) {
196  char c1 = tolower(s1[i]);
197  char c2 = tolower(s2[i]);
198 
199  if (c1 == c2) {
200  if (!c1) break; // equal strings
201  }
202  else {
203  if (c1<c2) return -1;
204  return 1;
205  }
206  }
207  return 0;
208 }
209 static const char *gbl_stristr(const char *haystack, const char *needle) {
210  // case insensitive strstr
211  const char *hp = haystack;
212  char c1 = toupper(needle[0]);
213  char c2 = tolower(c1);
214  int needle_size = strlen(needle);
215 
216  if (c1 == c2) {
217  hp = strchr(hp, c1);
218  while (hp) {
219  if (gbl_strincmp(hp, needle, needle_size) == 0) return hp;
220  hp = strchr(hp+1, c1);
221  }
222  }
223  else {
224  while (hp) {
225  const char *h1 = strchr(hp, c1);
226  const char *h2 = strchr(hp, c2);
227 
228  if (h1 && h2) {
229  if (h1<h2) {
230  if (gbl_strincmp(h1, needle, needle_size) == 0) return h1;
231  hp = h1+1;
232  }
233  else {
234  gb_assert(h1>h2);
235  if (gbl_strincmp(h2, needle, needle_size) == 0) return h2;
236  hp = h2+1;
237  }
238  }
239  else {
240  if (h1) { hp = h1; }
241  else if (h2) { hp = h2; c1 = c2; }
242  else { hp = NULp; }
243 
244  while (hp) {
245  if (gbl_strincmp(hp, needle, needle_size) == 0) return hp;
246  hp = strchr(hp+1, c1);
247  }
248  }
249  }
250  }
251  return NULp;
252 }
253 
254 inline int approve_pos(int pos, int len) { return pos<0 ? (-pos<len ? len+pos : 0) : pos; }
255 
256 static GB_ERROR gbl_mid_streams(const GBL_streams& arg_input, GBL_streams& arg_out, int start, int end) {
257  // used as well to copy all streams (e.g. by 'dd')
258  for (int i=0; i<arg_input.size(); i++) {
259  const char *p = arg_input.get(i);
260  int len = strlen(p);
261 
262  int s = approve_pos(start, len);
263  int e = approve_pos(end, len);
264 
265  char *res;
266  if (s >= len || e<s) {
267  res = ARB_strdup("");
268  }
269  else {
270  gb_assert(s >= 0);
271  res = ARB_strpartdup(p+s, p+e);
272  }
273  arg_out.insert(res);
274  }
275  return NULp;
276 }
277 
279  int tmp_trace;
280 
281  EXPECT_PARAMS(args, 1, "0|1");
282 
283  tmp_trace = atoi(args->get_param(0));
284  if (tmp_trace<0 || tmp_trace>1) return GBS_global_string("Illegal value %i to trace", tmp_trace);
285 
286  if (tmp_trace != traceACI) {
287  traceACI = 1;
288  print_trace(GBS_global_string("%sctivated ACI trace\n", tmp_trace ? "A" : "De-a"));
289  traceACI = tmp_trace;
290  }
291 
292  return gbl_mid_streams(args->input, args->output, 0, -1); // copy all streams
293 }
294 
295 /* ---------------------------------------------------------------------------------------
296  * Binary operators work on pairs of values.
297  * Three different operational modes are implemented for all binary operators:
298  *
299  * 1. inputstreams|operator
300  *
301  * The number of inputstreams has to be even and the operator will be
302  * applied to pairs of them.
303  *
304  * Example : a;b;c;d;e;f | plus
305  * Result : a+b;c+d;e+f
306  *
307  * 2. inputstreams|operator(x)
308  *
309  * The number of inputstreams has to be at least 1.
310  * The operator is applied to each inputstream.
311  *
312  * Example : a;b;c | plus(d)
313  * Result : a+d;b+d;c+d
314  *
315  * 3. operator(x, y)
316  *
317  * @@@ this decription does not match behavior!
318  * @@@ check description in helpfile as well
319  *
320  * Inputstreams will be ignored and the operator is applied
321  * to the arguments
322  *
323  * Example : a;b | plus(c,d)
324  * Result : c+d
325  */
326 
327 template <typename T>
328 GB_ERROR gbl_apply_binary_operator(GBL_command_arguments *args, char *(*op)(const char *, const char *, T), T client_data) {
329  GB_ERROR error = NULp;
330  switch (args->param_count()) {
331  case 0:
332  gb_assert(args->set_params_checked());
333  if (args->input.size() == 0) error = "Expect at least two input streams if called with 0 parameters";
334  else if (args->input.size()%2) error = "Expect an even number of input streams if called with 0 parameters";
335  else {
336  int inputpairs = args->input.size()/2;
337  int i;
338  for (i = 0; i<inputpairs; ++i) {
339  PASS_2_OUT(args, op(args->input.get(i*2), args->input.get(i*2+1), client_data));
340  }
341  }
342  break;
343 
344  case 1:
345  gb_assert(args->set_params_checked());
346  if (args->input.size() == 0) error = "Expect at least one input stream if called with 1 parameter";
347  else {
348  int i;
349  const char *argument = args->get_param(0);
350  for (i = 0; i<args->input.size(); ++i) {
351  PASS_2_OUT(args, op(args->input.get(i), argument, client_data));
352  }
353  }
354  break;
355 
356  case 2:
357  gb_assert(args->set_params_checked());
358  for (int i = 0; i<args->input.size(); ++i) {
359  char *result1 = args->get_callEnv().interpret_subcommand(args->input.get(i), args->get_param(0)); // @@@ EVALUATED_PARAM (#768)
360  if (!result1) error = GB_await_error();
361  else {
362  char *result2 = args->get_callEnv().interpret_subcommand(args->input.get(i), args->get_param(1)); // @@@ EVALUATED_PARAM (#768)
363  if (!result2) error = GB_await_error();
364  else {
365  PASS_2_OUT(args, op(result1, result2, client_data));
366  free(result2);
367  }
368  free(result1);
369  }
370  }
371  break;
372 
373  default:
374  error = check_optional_parameters(args, 0, NULp, 2, "Expr1[,Expr2]", true, false);
375  break;
376  }
377 
378  return error;
379 }
380 
381 // --------------------------------
382 // escape/unescape strings
383 
384 static char *unEscapeString(const char *escapedString) {
385  // replaces all \x by x
386  char *result = nulldup(escapedString);
387  char *to = result;
388  char *from = result;
389 
390  while (1) {
391  char c = *from++;
392  if (!c) break;
393 
394  if (c=='\\') {
395  *to++ = *from++;
396  }
397  else {
398  *to++ = c;
399  }
400  }
401  *to = 0;
402  return result;
403 }
404 static char *escapeString(const char *unescapedString) {
405  // replaces all '\' and '"' by '\\' and '\"'
406  int len = strlen(unescapedString);
407  char *result = ARB_alloc<char>(2*len+1);
408  char *to = result;
409  const char *from = unescapedString;
410 
411  while (1) {
412  char c = *from++;
413  if (!c) break;
414 
415  if (c=='\\' || c == '\"') {
416  *to++ = '\\';
417  *to++ = c;
418  }
419  else {
420  *to++ = c;
421  }
422  }
423  *to = 0;
424  return result;
425 }
426 
427 // ---------------------------------
428 // the commands themselves:
429 
431  EXPECT_NO_PARAM(args);
432 
433  for (int i=0; i<args->input.size(); i++) {
434  FORMAT_2_OUT(args, "\"%s\"", args->input.get(i));
435  }
436  return NULp;
437 }
439  EXPECT_NO_PARAM(args);
440 
441  for (int i=0; i<args->input.size(); i++) {
442  const char *str = args->input.get(i);
443  int len = strlen(str);
444 
445  if (str[0] == '\"' && str[len-1] == '\"') {
446  PASS_2_OUT(args, ARB_strpartdup(str+1, str+len-2));
447  }
448  else {
449  IN_2_OUT(args, i);
450  }
451  }
452  return NULp;
453 }
454 
456  EXPECT_NO_PARAM(args);
457 
458  for (int i=0; i<args->input.size(); i++) {
459  char *escaped = escapeString(args->input.get(i));
460  PASS_2_OUT(args, escaped);
461  }
462  return NULp;
463 }
465  EXPECT_NO_PARAM(args);
466 
467  for (int i=0; i<args->input.size(); i++) {
468  char *unescaped = unEscapeString(args->input.get(i));
469  PASS_2_OUT(args, unescaped);
470  }
471  return NULp;
472 }
473 
475  EXPECT_PARAMS(args, 1, "\"ACI command\"");
476 
477  GB_ERROR error = NULp;
478  char *command = unEscapeString(args->get_param(0));
479 
480  if (traceACI) {
481  print_trace(GBS_global_string("executing command '%s'\n", command));
482  }
483 
484  for (int i=0; i<args->input.size() && !error; i++) {
485  char *result = args->get_callEnv().interpret_subcommand(args->input.get(i), command);
486  if (!result) error = GB_await_error();
487  else PASS_2_OUT(args, result);
488  }
489  free(command);
490  return error;
491 }
492 
494  EXPECT_PARAMS(args, 1, "\"expression evaluating to ACI command\"");
495 
496  GB_ERROR error = NULp;
497  char *to_eval = unEscapeString(args->get_param(0));
498  TRACE_ACI(GBS_global_string("evaluating '%s'\n", to_eval));
499 
500  char *command = args->get_callEnv().interpret_subcommand("", to_eval); // evaluate independent
501  if (!command) error = GB_await_error();
502  else {
503  TRACE_ACI(GBS_global_string("executing '%s'\n", command));
504 
505  for (int i=0; i<args->input.size() && !error; i++) {
506  char *result = args->get_callEnv().interpret_subcommand(args->input.get(i), command);
507  if (!result) error = GB_await_error();
508  else PASS_2_OUT(args, result);
509  }
510  free(command);
511  }
512  free(to_eval);
513  return error;
514 }
515 
516 class DefinedCommands : virtual Noncopyable {
517  GB_HASH *cmds;
518 public:
521 
522  void set(const char *name, char* cmd) { GBS_dynaval_free(GBS_write_hash(cmds, name, (long)cmd)); } // takes ownership of 'cmd'!
523  const char *get(const char *name) const { return (const char *)GBS_read_hash(cmds, name); }
524 };
525 
527 
530  EXPECT_PARAMS(args, 2, "name, \"ACI command\"");
531 
532  const char *name = args->get_param(0);
533  char *cmd = unEscapeString(args->get_param(1));
534 
535  defined_commands.set(name, cmd);
536  TRACE_ACI(GBS_global_string("defining command '%s'='%s'\n", name, cmd));
537  return NULp;
538 }
539 
541  EXPECT_PARAMS(args, 1, "definedCommandName");
542 
543  GB_ERROR error = NULp;
544  const char *name = args->get_param(0);
545  const char *cmd = defined_commands.get(name);
546 
547  if (!cmd) {
548  error = GBS_global_string("Can't do undefined command '%s' - use define(%s, ...) first", name, name);
549  }
550  else {
551  TRACE_ACI(GBS_global_string("executing defined command '%s'='%s' on %i streams\n", name, cmd, args->input.size()));
552 
553  for (int i=0; i<args->input.size() && !error; i++) {
554  char *result = args->get_callEnv().interpret_subcommand(args->input.get(i), cmd);
555  if (!result) error = GB_await_error();
556  else PASS_2_OUT(args, result);
557  }
558  }
559  return error;
560 }
561 
563  EXPECT_NO_PARAM(args);
564 
565  FORMAT_2_OUT(args, "%i", args->input.size());
566  return NULp;
567 }
568 
570  if (GEN_is_genome_db(args->get_gb_main(), -1)) return NULp;
571  return GBS_global_string("ACI command '%s' can only be used in genome databases.", args->get_cmdName());
572 }
573 
574 static GB_ERROR apply_to_origin(GBL_command_arguments *args, bool organism) {
575  EXPECT_PARAMS(args, 1, "\"ACI command\"");
577 
579  if (!error) {
581  error = GBS_global_string("'%s' applies to gene-species only", args->get_cmdName());
582  }
583  else {
584  GBDATA *gb_origin = NULp;
585  if (organism) {
586  gb_origin = GEN_find_origin_organism(args->get_item_ref(), NULp);
587  }
588  else {
589  gb_origin = GEN_find_origin_gene(args->get_item_ref(), NULp);
590  }
591 
592  if (!error && !gb_origin) error = GB_await_error();
593 
594  if (!error) {
595  char *command = unEscapeString(args->get_param(0));
596  GBL_call_env callEnv(gb_origin, args->get_env()); // refer to gb_origin for subcommands
597  // Note: if calling env has a FieldTracker, field access from 'command' is not tracked.
598  // That access applies to different item.
599 
600  for (int i=0; i<args->input.size() && !error; i++) {
601  char *result = callEnv.interpret_subcommand(args->input.get(i), command);
602  if (!result) error = GB_await_error();
603  else PASS_2_OUT(args, result);
604  }
605 
606  free(command);
607  }
608  }
609  }
610  return error;
611 }
612 
613 static GB_ERROR gbl_origin_gene(GBL_command_arguments *args) { return apply_to_origin(args, false); }
615 
616 
617 static GB_ERROR applyToItemFoundByKey(GBL_command_arguments *args, const char *itemname, GBDATA *gb_item_data, const char *key) {
618  GB_ERROR error = NULp;
619  char *command = unEscapeString(args->get_param(0));
620 
621  for (int i=0; i<args->input.size() && !error; i++) {
622  const char *in = args->input.get(i);
623  if (in[0]) { // silently ignore empty input streams
624  GBDATA *gb_item = NULp;
625  {
626  GBDATA *gb_field = GB_find_string(gb_item_data, key, in, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
627  if (gb_field) {
628  gb_item = GB_get_father(gb_field);
629  }
630  else {
631  error = GBS_global_string("No %s with %s '%s' found.", itemname, key, in);
632  }
633  }
634  if (gb_item) {
635  GBL_call_env callEnv(gb_item, args->get_env()); // refer to gb_item for subcommands
636  // Note: if calling env has a FieldTracker, field access from 'command' is not tracked.
637  // That access applies to different item.
638 
639  char *result = callEnv.interpret_subcommand("", command);
640  if (!result) error = GB_await_error();
641  else PASS_2_OUT(args, result);
642  }
643  else {
644  if (!error) error = GB_await_error();
645  }
646  }
647  }
648 
649  free(command);
650  return error;
651 }
653  EXPECT_PARAMS(args, 1, "\"ACI command\"");
654  return applyToItemFoundByKey(args, "species", GBT_get_species_data(args->get_gb_main()), "name");
655 }
657  EXPECT_PARAMS(args, 1, "\"ACI command\"");
658  return applyToItemFoundByKey(args, "species", GBT_get_species_data(args->get_gb_main()), "acc");
659 }
660 
662  EXPECT_PARAMS(args, 1, "\"ACI command\"");
664 
666  if (!error) {
667  GBDATA *gb_item = args->get_item_ref();
668  if (GEN_is_organism(gb_item)) {
669  error = applyToItemFoundByKey(args, "gene", GEN_find_gene_data(gb_item), "name");
670  }
671  else if (strcmp(GB_read_key_pntr(gb_item), "gene") == 0) {
672  // if applied to gene -> find "brother" of gene
673  GBDATA *gb_organism = GB_get_grandfather(gb_item);
674  if (GEN_is_organism(gb_organism)) {
675  error = applyToItemFoundByKey(args, "gene", GEN_find_gene_data(gb_organism), "name");
676  }
677  else {
678  error = "'findgene' cannot be used here (was applied to 'gene', but could not find gene-owning organism)";
679  }
680  }
681  else {
682  error = GBS_global_string("'findgene' cannot be applied to '%s' (need an organism)",
683  GBT_get_name_or_description(gb_item));
684  }
685  }
686  return error;
687 }
688 
689 class Tab {
690  bool tab[256];
691 public:
692  Tab(bool take, const char *invert) {
693  bool init = !take;
694  for (int i = 0; i<256; ++i) tab[i] = init;
695  for (int i = 0; invert[i]; ++i) tab[safeCharIndex(invert[i])] = take;
696  }
697  bool operator[](int i) const { return tab[i]; }
698 };
699 
701  for (int i=0; i<args->input.size(); ++i) {
702  long sum = 0; // count frequencies
703  const char *p = args->input.get(i);
704 
705  while (*p) sum += tab[safeCharIndex(*(p++))];
706  FORMAT_2_OUT(args, "%li", sum);
707  }
708  return NULp;
709 }
711  GBS_strstruct buf(1000);
712  for (int i=0; i<args->input.size(); ++i) {
713  buf.erase();
714  for (const char *p = args->input.get(i); *p; p++) {
715  if (!tab[(unsigned int)*p]) {
716  buf.put(*p);
717  }
718  }
719  PASS_2_OUT(args, buf.get_copy());
720  }
721  return NULp;
722 }
723 
725  EXPECT_PARAMS(args, 1, "\"characters to count\"");
726  return count_by_tab(args, Tab(true, args->get_param(0)));
727 }
729  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 1, "\"characters not to count\"");
730  const char *exclude = args->get_optional_param(0, "");
731  return count_by_tab(args, Tab(false, exclude));
732 }
734  EXPECT_PARAMS(args, 1, "\"characters to remove\"");
735  return remove_by_tab(args, Tab(true, args->get_param(0)));
736 }
738  EXPECT_PARAMS(args, 1, "\"characters to keep\"");
739  return remove_by_tab(args, Tab(false, args->get_param(0)));
740 }
741 
742 
743 static char *binop_compare(const char *arg1, const char *arg2, bool case_sensitive) {
744  int result;
745 
746  if (case_sensitive) result = strcmp(arg1, arg2);
747  else result = gbl_stricmp(arg1, arg2);
748 
749  return GBS_global_string_copy("%i", result<0 ? -1 : (result>0 ? 1 : 0));
750 }
751 static char *binop_equals(const char *arg1, const char *arg2, bool case_sensitive) {
752  int result;
753 
754  if (case_sensitive) result = strcmp(arg1, arg2);
755  else result = gbl_stricmp(arg1, arg2);
756 
757  return GBS_global_string_copy("%i", result == 0 ? 1 : 0);
758 }
759 static char *binop_contains(const char *arg1, const char *arg2, bool case_sensitive) {
760  const char *found = NULp;
761 
762  if (!arg2[0]) return strdup("0"); // do not report matches of empty string
763 
764  if (case_sensitive) found = strstr(arg1, arg2);
765  else found = gbl_stristr(arg1, arg2);
766 
767  return GBS_global_string_copy("%ti", found ? (found-arg1)+1 : 0);
768 }
769 static char *binop_partof(const char *arg1, const char *arg2, bool case_sensitive) {
770  return binop_contains(arg2, arg1, case_sensitive);
771 }
772 
781 
783  EXPECT_NO_PARAM(args);
784  for (int i=0; i<args->input.size(); i++) {
785  const char *str = args->input.get(i);
786  FORMAT_2_OUT(args, "%i", str[0] == 0);
787  }
788  return NULp;
789 }
791  EXPECT_PARAMS(args, 2, "low,high");
792 
793  double low = strtod(args->get_param(0), NULp);
794  double high = strtod(args->get_param(1), NULp);
795 
796  for (int i=0; i<args->input.size(); i++) {
797  double val = strtod(args->input.get(i), NULp);
798  bool inRange = low<=val && val<=high;
799  FORMAT_2_OUT(args, "%i", inRange);
800  }
801  return NULp;
802 }
803 
804 
806  EXPECT_OPTIONAL_PARAMS(args, 2, "old,new", 1, "other");
807 
808  const char *other = args->get_optional_param(2, NULp);
809  if (other && (other[0] == 0 || other[1] != 0)) {
810  return "third parameter of translate has to be one character (i.e. \"-\")";
811  }
812  const char replace_other = other ? other[0] : 0;
813 
814  // build translation table :
815  unsigned char tab[256];
816  {
817  const unsigned char *o = (const unsigned char *)args->get_param(0);
818  const unsigned char *n = (const unsigned char *)args->get_param(1);
819  char used[256];
820 
821  if (strlen((const char *)o) != strlen((const char *)n)) {
822  return "arguments 1 and 2 of translate should be strings with identical length";
823  }
824 
825  for (int i = 0; i<256; ++i) { // IRRELEVANT_LOOP
826  tab[i] = replace_other ? replace_other : i; // replace unused or identity translation
827  used[i] = 0;
828  }
829 
830  for (int i = 0; o[i]; ++i) {
831  if (used[o[i]]) return GBS_global_string("character '%c' used twice in argument 1 of translate", o[i]);
832  used[o[i]] = 1;
833  tab[o[i]] = n[i]; // real translation
834  }
835  }
836 
837  GBS_strstruct buf(1000);
838  for (int i=0; i<args->input.size(); i++) {
839  buf.erase();
840  for (const char *p = args->input.get(i); *p; p++) {
841  buf.put(tab[(unsigned char)*p]);
842  }
843  PASS_2_OUT(args, buf.get_copy());
844  }
845  return NULp;
846 }
847 
848 
850  ACCEPT_ANY_PARAMS(args);
852  for (int i=0; i<args->param_count(); i++) PARAM_2_OUT(args, i);
853  return NULp;
854 }
855 
857  EXPECT_NO_PARAM(args);
858  return gbl_mid_streams(args->input, args->output, 0, -1); // copy all streams
859 }
860 
861 enum Case { UPPER, LOWER, CAPS };
862 
864  EXPECT_NO_PARAM(args);
865 
866  for (int i=0; i<args->input.size(); i++) {
867  char *p = ARB_strdup(args->input.get(i));
868  bool last_was_alnum = false;
869 
870  for (char *pp = p; pp[0]; ++pp) {
871  switch (convTo) {
872  case LOWER: pp[0] = tolower(pp[0]); break;
873  case UPPER: pp[0] = toupper(pp[0]); break;
874  case CAPS: {
875  bool alnum = isalnum(pp[0]);
876  if (alnum) pp[0] = (last_was_alnum ? tolower : toupper)(pp[0]);
877  last_was_alnum = alnum;
878  break;
879  }
880  default: gb_assert(0); break;
881  }
882  }
883 
884  PASS_2_OUT(args, p);
885  }
886 
887  return NULp;
888 }
889 
890 static GB_ERROR gbl_caps (GBL_command_arguments *args) { return convert_case(args, CAPS); }
893 
895  EXPECT_PARAMS(args, 1, "length_of_head");
896  int start = atoi(args->get_param(0));
897  if (start <= 0) return gbl_mid_streams(args->input, args->output, 1, 0); // empty all streams
898  return gbl_mid_streams(args->input, args->output, 0, start-1);
899 }
901  EXPECT_PARAMS(args, 1, "length_of_tail");
902  int end = atoi(args->get_param(0));
903  if (end <= 0) return gbl_mid_streams(args->input, args->output, 1, 0); // empty all streams
904  return gbl_mid_streams(args->input, args->output, -end, -1);
905 }
906 
907 inline GB_ERROR mid(GBL_command_arguments *args, int start_index) {
908  EXPECT_PARAMS(args, 2, "start,end");
909  return gbl_mid_streams(args->input, args->output, atoi(args->get_param(0))-start_index, atoi(args->get_param(1))-start_index);
910 }
911 static GB_ERROR gbl_mid0(GBL_command_arguments *args) { return mid(args, 0); }
912 static GB_ERROR gbl_mid (GBL_command_arguments *args) { return mid(args, 1); }
913 
914 static GB_ERROR tab(GBL_command_arguments *args, bool pretab) {
915  EXPECT_PARAMS(args, 1, "tabstop");
916 
917  int tab = atoi(args->get_param(0));
918  for (int i=0; i<args->input.size(); i++) {
919  int len = strlen(args->input.get(i));
920  if (len >= tab) IN_2_OUT(args, i);
921  else {
922  char *p = ARB_alloc<char>(tab+1);
923  if (pretab) {
924  int spaces = tab-len;
925  for (int j = 0; j<spaces; ++j) p[j] = ' ';
926  strcpy(p+spaces, args->input.get(i));
927  }
928  else {
929  strcpy(p, args->input.get(i));
930  for (int j=len; j<tab; j++) p[j] = ' ';
931  p[tab] = 0;
932  }
933  PASS_2_OUT(args, p);
934  }
935  }
936  return NULp;
937 }
938 static GB_ERROR gbl_tab (GBL_command_arguments *args) { return tab(args, false); }
939 static GB_ERROR gbl_pretab(GBL_command_arguments *args) { return tab(args, true); }
940 
942  EXPECT_PARAMS(args, 1, "\"chars_to_crop\"");
943 
944  const char *chars_to_crop = args->get_param(0);
945  for (int i=0; i<args->input.size(); i++) {
946  const char *s = args->input.get(i);
947  while (s[0] && strchr(chars_to_crop, s[0])) s++; // crop at beg of line
948 
949  int len = strlen(s);
950  char *p = ARB_alloc<char>(len+1);
951  strcpy(p, s);
952 
953  {
954  char *pe = p+len-1;
955 
956  while (pe >= p && strchr(chars_to_crop, pe[0])) { // crop at end of line
957  --pe;
958  }
959  gb_assert(pe >= (p-1));
960  pe[1] = 0;
961  }
962  PASS_2_OUT(args, p);
963  }
964  return NULp;
965 }
966 
967 
968 
970  EXPECT_PARAMS_PASSED(args, "streamnumber[,streamnumber]+");
971 
972  for (int i=0; i<args->param_count(); i++) {
973  int stream = atoi(args->get_param(i));
974  EXPECT_LEGAL_STREAM_INDEX(args, stream);
975  IN_2_OUT(args, bio2info(stream));
976  }
977  return NULp;
978 }
980  EXPECT_PARAMS_PASSED(args, "streamnumber[,streamnumber]+");
981 
982  GB_ERROR error = NULp;
983  bool *dropped = ARB_alloc<bool>(args->input.size());
984 
985  for (int i=0; i<args->input.size(); ++i) dropped[i] = false;
986 
987  for (int i=0; i<args->param_count() && !error; ++i) {
988  int stream = atoi(args->get_param(i));
989  error = check_valid_stream_index(args, stream);
990  if (!error) dropped[bio2info(stream)] = true;
991  }
992 
993  if (!error) {
994  for (int i=0; i<args->input.size(); ++i) {
995  if (!dropped[i]) IN_2_OUT(args, i);
996  }
997  }
998  free(dropped);
999 
1000  return error;
1001 }
1002 
1004  EXPECT_NO_PARAM(args);
1005 
1006  for (int i=0; i<args->input.size(); ++i) {
1007  if (args->input.get(i)[0]) { // if non-empty
1008  IN_2_OUT(args, i);
1009  }
1010  }
1011  return NULp;
1012 }
1013 
1015  EXPECT_NO_PARAM(args);
1016 
1017  for (int i=0; i<args->input.size(); ++i) {
1018  if (atoi(args->input.get(i))) { // if non-zero
1019  IN_2_OUT(args, i);
1020  }
1021  }
1022  return NULp;
1023 }
1024 
1026  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 2, "streamnumber,streamnumber");
1027 
1028  if (args->input.size()<2) return "need at least two input streams";
1029 
1030  int swap1;
1031  int swap2;
1032  if (args->param_count() == 0) {
1033  swap1 = args->input.size()-1;
1034  swap2 = args->input.size()-2;
1035  }
1036  else {
1037  gb_assert(args->param_count() == 2);
1038 
1039  swap1 = atoi(args->get_param(0));
1040  swap2 = atoi(args->get_param(1));
1041 
1042  EXPECT_LEGAL_STREAM_INDEX(args, swap1);
1043  EXPECT_LEGAL_STREAM_INDEX(args, swap2);
1044 
1045  swap1 = bio2info(swap1);
1046  swap2 = bio2info(swap2);
1047  }
1048 
1049  for (int i = 0; i<args->input.size(); ++i) {
1050  int j = i == swap1 ? swap2 : (i == swap2 ? swap1 : i);
1051  IN_2_OUT(args, j);
1052  }
1053 
1054  return NULp;
1055 }
1056 
1058  EXPECT_PARAMS(args, 1, "streamnumber");
1059  if (args->input.size()<1) return "need at least one input stream";
1060 
1061  int stream_to_move = atoi(args->get_param(0));
1062  EXPECT_LEGAL_STREAM_INDEX(args, stream_to_move);
1063  stream_to_move = bio2info(stream_to_move);
1064 
1065  if (!toback) IN_2_OUT(args, stream_to_move);
1066  for (int i = 0; i<args->input.size(); ++i) {
1067  if (i != stream_to_move) IN_2_OUT(args, i);
1068  }
1069  if (toback) IN_2_OUT(args, stream_to_move);
1070 
1071  return NULp;
1072 }
1073 static GB_ERROR gbl_toback (GBL_command_arguments *args) { return backfront_stream(args, 1); }
1075 
1077  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 1, "\"separator\"");
1078  const char *separator = args->get_optional_param(0, NULp);
1079 
1080  if (args->input.size()) {
1081  GBS_strstruct str(1000);
1082  str.cat(args->input.get(0));
1083 
1084  for (int i = 1; i<args->input.size(); ++i) {
1085  if (separator) str.cat(separator);
1086  str.cat(args->input.get(i));
1087  }
1088 
1089  PASS_2_OUT(args, str.release());
1090  }
1091  return NULp;
1092 }
1093 
1095  EXPECT_OPTIONAL_PARAMS_CUSTOM(args, 0, NULp, 2, "\"separator\"[,mode]", true, false);
1096 
1097  const char *separator = args->get_optional_param(0, "\n");
1098  int split_mode = atoi(args->get_optional_param(1, "0")); // 0: remove separator, 1: split before separator, 2: split behind separator
1099 
1100  if (!separator[0]) {
1101  // e.g. happens if trying to specify character ';' or ','
1102  return "Invalid separator (cannot be empty; please try to quote the parameter)";
1103  }
1104 
1105  if (split_mode<0 || split_mode>2) return GBS_global_string("Illegal split mode '%i' (valid: 0..2)", split_mode);
1106 
1107  {
1108  size_t sepLen = strlen(separator);
1109 
1110  for (int i = 0; i<args->input.size(); ++i) {
1111  const char *in = args->input.get(i);
1112  const char *from = in; // search from here
1113 
1114  while (in) {
1115  const char *splitAt = strstr(from, separator);
1116  if (splitAt) {
1117  size_t len;
1118  char *copy;
1119 
1120  if (split_mode == 2) splitAt += sepLen; // split behind separator
1121 
1122  len = splitAt-in;
1123  copy = ARB_strndup(in, len);
1124 
1125  PASS_2_OUT(args, copy);
1126 
1127  in = splitAt + (split_mode == 0 ? sepLen : 0);
1128  from = in+(split_mode == 1 ? sepLen : 0);
1129  }
1130  else {
1131  COPY_2_OUT(args, in); // last part
1132  in = NULp;
1133  }
1134  }
1135  }
1136  }
1137 
1138  return NULp;
1139 }
1140 
1142  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 1, "width");
1143 
1144  int width = atoi(args->get_optional_param(0, "1"));
1145  if (width<1) return "Invalid width";
1146 
1147  for (int i = 0; i<args->input.size(); ++i) {
1148  const char *in = args->input.get(i);
1149  int len = strlen(in);
1150 
1151  while (len>0) {
1152  char *part = ARB_strpartdup(in, in+width-1);
1153  PASS_2_OUT(args, part);
1154 
1155  in += width;
1156  len -= width;
1157  }
1158  }
1159 
1160  return NULp;
1161 }
1162 // ----------------------------------
1163 // Extended string functions
1164 
1165 static char *do_extract_words(const char *source, const char *chars, float minlen, bool sort_output) {
1166  /* extract all words in a text that:
1167  * if minlen < 1.0 -> contain more than minlen*len_of_text characters that also exists in chars
1168  * if minlen > 1.0 -> contain more than minlen characters that also exists in chars
1169  */
1170 
1171  int count = 0;
1172  int iminlen = int(minlen+.5);
1173 
1174  char *s = ARB_strdup(source);
1175  char *f = s;
1176  char **ps = ARB_calloc<char*>((strlen(source)>>1) + 1);
1177 
1178  while (char *p = strtok(f, " \t,;:|")) {
1179  f = NULp;
1180  int cnt = 0;
1181  const int len = strlen(p);
1182  for (char *h=p; *h; h++) {
1183  if (strchr(chars, *h)) ++cnt;
1184  }
1185 
1186  if (minlen == 1.0) {
1187  if (cnt != len) continue;
1188  }
1189  else if (minlen > 1.0) {
1190  if (cnt < iminlen) continue;
1191  }
1192  else {
1193  if (len < 3 || cnt < minlen*len) continue;
1194  }
1195  ps[count] = p;
1196  count ++;
1197  }
1198 
1199  if (sort_output) {
1200  GB_sort((void **)ps, 0, count, GB_string_comparator, NULp);
1201  }
1202 
1203  GBS_strstruct buf(1000);
1204 
1205  for (int cnt = 0; cnt<count; ++cnt) {
1206  if (cnt) buf.put(' ');
1207  buf.cat(ps[cnt]);
1208  }
1209 
1210  free(ps);
1211  free(s);
1212 
1213  return buf.release_memfriendly();
1214 }
1215 
1217  EXPECT_PARAMS(args, 2, "\"chars\", minchars");
1218 
1219  float len = atof(args->get_param(1));
1220  for (int i=0; i<args->input.size(); i++) {
1221  char *res = do_extract_words(args->input.get(i), args->get_param(0), len, 1);
1222  gb_assert(res);
1223  PASS_2_OUT(args, res);
1224  }
1225  return NULp;
1226 }
1227 
1229  EXPECT_PARAMS(args, 2, "\"chars\",minFrequency");
1230 
1231  const char *chars = args->get_param(0);
1232  float minFreq = atof(args->get_param(1));
1233 
1234  if (minFreq <0.0 || minFreq > 1.0) return GBS_global_string("Illegal minFrequency=%f (allowed: ]0.0 .. 1.0[)", minFreq);
1235 
1236  for (int i=0; i<args->input.size(); i++) {
1237  char *res = do_extract_words(args->input.get(i), chars, minFreq, 0);
1238  gb_assert(res);
1239  PASS_2_OUT(args, res);
1240  }
1241  return NULp;
1242 }
1243 
1246  GBL_PARAM_STRING(exclude, "exclude=", "", "Remove given characters before calculating");
1247  GBL_PARAM_BIT (upper, "toupper", 0, "Convert all characters to uppercase before calculating");
1248  GBL_TRACE_PARAMS(args);
1250 
1251  for (int i=0; i<args->input.size(); i++) {
1252  long id = GBS_checksum(args->input.get(i), upper, exclude);
1253  FORMAT_2_OUT(args, "%lX", id);
1254  }
1255  return NULp;
1256 }
1257 
1259  EXPECT_NO_PARAM(args);
1260 
1261  for (int i=0; i<args->input.size(); i++) {
1262  long id = GBS_gcgchecksum(args->input.get(i));
1263  FORMAT_2_OUT(args, "%li", id);
1264  }
1265  return NULp;
1266 }
1267 
1268 // ------------
1269 // SRT
1270 
1272  EXPECT_PARAMS_PASSED(args, "expr[,expr]+");
1273 
1274  GB_ERROR error = NULp;
1275  for (int i=0; i<args->input.size() && !error; i++) {
1276  char *modsource = NULp;
1277 
1278  for (int j=0; j<args->param_count() && !error; j++) {
1279  char *hs = GBS_string_eval_in_env(modsource ? modsource : args->input.get(i), args->get_param(j), args->get_callEnv());
1280 
1281  if (hs) freeset(modsource, hs);
1282  else {
1283  error = GB_await_error();
1284  free(modsource);
1285  }
1286  }
1287 
1288  if (!error) {
1289  if (modsource) PASS_2_OUT(args, modsource);
1290  else IN_2_OUT(args, i);
1291  }
1292  }
1293  return error;
1294 }
1295 
1296 // -----------------------------
1297 // Calculator Functions
1298 
1299 struct binop_pair {
1300  int (*INT) (int, int);
1301  double (*DOUBLE)(double, double);
1302  binop_pair(int (*INT_)(int, int), double (*DOUBLE_)(double, double)) : INT(INT_), DOUBLE(DOUBLE_) {}
1303 };
1304 
1305 static char *apply_numeric_binop(const char *arg1, const char *arg2, int (*num_bin_op)(int,int)) {
1306  int v1 = atoi(arg1);
1307  int v2 = atoi(arg2);
1308  int result = num_bin_op(v1, v2);
1309 
1310  return GBS_global_string_copy("%i", result);
1311 }
1312 
1313 static char *apply_double_binop(const char *arg1, const char *arg2, double (*num_bin_op)(double,double)) {
1314  double v1 = strtod(arg1, NULp);
1315  double v2 = strtod(arg2, NULp);
1316  double result = num_bin_op(v1, v2);
1317 
1318  return GBS_global_string_copy("%g", result);
1319 }
1320 
1321 static char *apply_auto_numeric_binop(const char *arg1, const char *arg2, binop_pair multiop) {
1322  // argument type detection (int vs double)
1323  int i1 = atoi(arg1);
1324  int i2 = atoi(arg2);
1325  double d1 = strtod(arg1, NULp);
1326  double d2 = strtod(arg2, NULp);
1327 
1328  if (double(i1) == d1 || double(i2) == d2) {
1329  int result = multiop.INT(i1, i2);
1330  return GBS_global_string_copy("%i", result);
1331  }
1332  else {
1333  double result = multiop.DOUBLE(d1, d2);
1334  return GBS_global_string_copy("%g", result);
1335  }
1336 }
1337 
1338 
1339 
1340 template <typename T> static T binop_plus (T v1, T v2) { return v1+v2; }
1341 template <typename T> static T binop_minus (T v1, T v2) { return v1-v2; }
1342 template <typename T> static T binop_mult (T v1, T v2) { return v1*v2; }
1343 template <typename T> static T binop_div (T v1, T v2) { return v2 ? v1/v2 : 0; }
1344 template <typename T> static T binop_per_cent(T v1, T v2) { return v2 ? (v1*100)/v2 : 0; }
1345 
1346 static int binop_rest(int i1, int i2) { return i2 ? i1%i2 : 0; }
1347 
1348 
1350 static GB_ERROR gbl_fplus (GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_double_binop, binop_plus<double>); }
1351 static GB_ERROR gbl_minus (GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_numeric_binop, binop_minus<int>); }
1352 static GB_ERROR gbl_fminus (GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_double_binop, binop_minus<double>); }
1354 static GB_ERROR gbl_fmult (GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_double_binop, binop_mult<double>); }
1356 static GB_ERROR gbl_fdiv (GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_double_binop, binop_div<double>); }
1358 static GB_ERROR gbl_per_cent (GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_numeric_binop, binop_per_cent<int>); }
1359 static GB_ERROR gbl_fper_cent(GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_double_binop, binop_per_cent<double>); }
1360 
1361 template <typename T> static T binop_isAbove(T i1, T i2) { return i1>i2; }
1362 template <typename T> static T binop_isBelow(T i1, T i2) { return i1<i2; }
1363 template <typename T> static T binop_isEqual(T i1, T i2) { return i1 == i2; }
1364 
1365 static GB_ERROR gbl_isAbove(GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_auto_numeric_binop, binop_pair(binop_isAbove<int>, binop_isAbove<double>)); }
1366 static GB_ERROR gbl_isBelow(GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_auto_numeric_binop, binop_pair(binop_isBelow<int>, binop_isBelow<double>)); }
1367 static GB_ERROR gbl_isEqual(GBL_command_arguments *args) { return gbl_apply_binary_operator(args, apply_auto_numeric_binop, binop_pair(binop_isEqual<int>, binop_isEqual<double>)); }
1368 
1369 inline double float_shift_factor(int digits) {
1370  if (digits<0) {
1371  return 1.0/float_shift_factor(-digits);
1372  }
1373  int factor = 1;
1374  while (digits>0) { // IRRELEVANT_LOOP (gcc 9.x refuses to optimize)
1375  factor *= 10;
1376  --digits;
1377  }
1378  return factor;
1379 }
1380 
1382  EXPECT_PARAMS(args, 1, "digits");
1383  int digits = atoi(args->get_param(0));
1384 
1385  double factor = float_shift_factor(digits);
1386  for (int i=0; i<args->input.size(); ++i) {
1387  double val = strtod(args->input.get(i), NULp);
1388  val = round(val*factor)/factor;
1389  FORMAT_2_OUT(args, "%g", val);
1390  }
1391  return NULp;
1392 }
1393 
1394 
1395 
1396 // boolean operators
1397 
1399  EXPECT_NO_PARAM(args);
1400 
1401  for (int i=0; i<args->input.size(); ++i) {
1402  const char *s = args->input.get(i);
1403  int val = atoi(s);
1404  FORMAT_2_OUT(args, "%i", !val);
1405  }
1406  return NULp;
1407 }
1408 
1410  EXPECT_NO_PARAM(args);
1411  bool conjunction = true;
1412  for (int i=0; conjunction && i<args->input.size(); ++i) {
1413  const char *s = args->input.get(i);
1414  conjunction = conjunction && atoi(s);
1415  }
1416  FORMAT_2_OUT(args, "%i", conjunction);
1417  return NULp;
1418 }
1420  EXPECT_NO_PARAM(args);
1421  bool disjunction = false;
1422  for (int i=0; !disjunction && i<args->input.size(); ++i) {
1423  const char *s = args->input.get(i);
1424  disjunction = disjunction || atoi(s);
1425  }
1426  FORMAT_2_OUT(args, "%i", disjunction);
1427  return NULp;
1428 }
1429 
1431  ACCEPT_ANY_PARAMS(args);
1432 
1433  GB_ERROR error = NULp;
1434  for (int i=0; i<args->input.size() && !error; i++) {
1435  int paraidx = atoi(args->input.get(i));
1436  error = check_valid_param_index(args, paraidx);
1437  if (!error) {
1438  char *result = args->get_callEnv().interpret_subcommand("", args->get_param(paraidx)); // @@@ EVALUATED_PARAM (#768)
1439  if (!result) error = GB_await_error();
1440  else PASS_2_OUT(args, result);
1441  }
1442  }
1443  return error;
1444 }
1445 
1447  EXPECT_PARAMS_PASSED(args, "fieldname[,fieldname]+");
1448  EXPECT_ITEM_REFERENCED(args);
1450 
1451  GBS_strstruct buf(1024);
1452  for (int i=0; i<args->param_count(); i++) {
1453  char *val = GBT_read_as_string(args->get_item_ref(),
1454  args->track_field_access(args->get_param(i)));
1455  if (val) {
1456  buf.cat(val);
1457  free(val);
1458  }
1459  }
1460  PASS_2_OUT(args, buf.release());
1461  return NULp;
1462 }
1463 
1464 
1469 };
1470 
1472  /* returns: GBT_ITEM_UNKNOWN -> unknown database_item
1473  * GBT_ITEM_SPECIES -> /species_data/species
1474  * GBT_ITEM_GENE -> /species_data/species/gene_data/gene */
1475 
1477  if (gb_item) {
1478  GBDATA *gb_father = GB_get_father(gb_item);
1479  if (gb_father) {
1480  const char *key = GB_KEY(gb_item);
1481 
1482  if (strcmp(key, "species") == 0 &&
1483  strcmp(GB_KEY(gb_father), "species_data") == 0) {
1484  res = GBT_ITEM_SPECIES;
1485  }
1486  else if (strcmp(key, "gene") == 0 &&
1487  strcmp(GB_KEY(gb_father), "gene_data") == 0 &&
1489  res = GBT_ITEM_GENE;
1490  }
1491  }
1492  }
1493  return res;
1494 }
1495 
1496 // --------------------------------------------------------------------------------
1497 // taxonomy caching
1498 
1499 #if defined(DEBUG)
1500 // #define DUMP_TAXONOMY_CACHING
1501 #endif
1502 
1503 
1504 #define GROUP_COUNT_CHARS 6 // characters in taxonomy-key reserved for group-counter (hex number)
1505 #define BITS_PER_HEXCHAR 4
1506 #define MAX_GROUPS (1 << (GROUP_COUNT_CHARS*BITS_PER_HEXCHAR)) // resulting number of groups
1507 
1509  char *tree_name; // tree for which taxonomy is cached here
1510  int groups; // number of named groups in tree (at time of caching)
1511  GB_HASH *taxonomy; /* keys: "!species", ">XXXXgroup" and "<root>".
1512  * Species and groups contain their first parent (i.e. '>XXXXgroup' or '<root>').
1513  * Species not in hash are not members of tree.
1514  * The 'XXXX' in groupname is simply a counter to avoid multiple groups with same name.
1515  * The group-db-entries are stored in hash as pointers ('>>%p') and
1516  * point to their own group entry ('>XXXXgroup')
1517  *
1518  * Note: the number of 'X's in 'XXXX' above is defined by GROUP_COUNT_CHARS!
1519  */
1520 };
1521 
1523  free(ct->tree_name);
1524  GBS_free_hash(ct->taxonomy);
1525  free(ct);
1526 }
1527 
1528 static void build_taxonomy_rek(TreeNode *node, GB_HASH *tax_hash, const char *parent_group, int *group_counter) {
1529  if (node->is_leaf()) {
1530  GBDATA *gb_species = node->gb_node;
1531  if (gb_species) { // not zombie
1532  const char *name = GBT_get_name(gb_species);
1533  if (name) GBS_write_hash(tax_hash, GBS_global_string("!%s", name), (long)ARB_strdup(parent_group));
1534  }
1535  }
1536  else {
1537  if (node->has_group_info()) { // node with name
1538  char *hash_entry;
1539  const char *hash_binary_entry;
1540  (*group_counter)++;
1541 
1542  gb_assert((*group_counter)<MAX_GROUPS); // overflow - increase GROUP_COUNT_CHARS
1543 
1544  TreeNode *keelTarget = node->keelTarget();
1545  char keelIndicator[2] = { char(keelTarget ? KEELED_INDICATOR : 0), 0 };
1546 
1547  hash_entry = GBS_global_string_copy(">%0*x%s%s",
1548  GROUP_COUNT_CHARS, *group_counter,
1549  keelIndicator,
1550  node->name);
1551  GBS_write_hash(tax_hash, hash_entry, (long)ARB_strdup(parent_group));
1552 
1553  hash_binary_entry = GBS_global_string(">>%p", node->gb_node);
1554  GBS_write_hash(tax_hash, hash_binary_entry, (long)ARB_strdup(hash_entry));
1555 
1556  if (keelTarget) { // keeled group (projected to son)
1557  if (keelTarget->is_leftson()) {
1558  build_taxonomy_rek(node->get_leftson(), tax_hash, hash_entry, group_counter); // pass down hash_entry only to keelTarget
1559  build_taxonomy_rek(node->get_rightson(), tax_hash, parent_group, group_counter);
1560  }
1561  else {
1562  build_taxonomy_rek(node->get_leftson(), tax_hash, parent_group, group_counter);
1563  build_taxonomy_rek(node->get_rightson(), tax_hash, hash_entry, group_counter);
1564  }
1565  }
1566  else { // normal group
1567  build_taxonomy_rek(node->get_leftson(), tax_hash, hash_entry, group_counter); // pass down hash_entry to both sons
1568  build_taxonomy_rek(node->get_rightson(), tax_hash, hash_entry, group_counter);
1569  }
1570 
1571  free(hash_entry);
1572  }
1573  else {
1574  build_taxonomy_rek(node->get_leftson(), tax_hash, parent_group, group_counter);
1575  build_taxonomy_rek(node->get_rightson(), tax_hash, parent_group, group_counter);
1576  }
1577  }
1578 }
1579 
1581 
1582 static bool is_cached_taxonomy(const char */*key*/, long val, void *cl_ct) {
1583  cached_taxonomy *ct1 = (cached_taxonomy *)val;
1584  cached_taxonomy *ct2 = (cached_taxonomy *)cl_ct;
1585 
1586  return ct1 == ct2;
1587 }
1588 
1589 static const char *tree_of_cached_taxonomy(cached_taxonomy *ct) {
1590  /* search the hash to find the correct cached taxonomy.
1591  * searching for tree name does not work, because the tree possibly already was deleted
1592  */
1593  const char *tree = GBS_hash_next_element_that(cached_taxonomies, NULp, is_cached_taxonomy, ct);
1594 #ifdef DUMP_TAXONOMY_CACHING
1595  if (tree) printf("tree_of_cached_taxonomy: tree='%s' ct->tree_name='%s'\n", tree, ct->tree_name);
1596 #endif // DUMP_TAXONOMY_CACHING
1597  return tree;
1598 }
1599 
1600 static void flush_taxonomy_cb(GBDATA *gbd, cached_taxonomy *ct) {
1601  /* this cb is bound all tree db members below "/tree_data/tree_xxx" which
1602  * may have an effect on the displayed taxonomy
1603  * it invalidates cached taxonomies for that tree (when changed or deleted)
1604  */
1605 
1606  GB_ERROR error = NULp;
1607  const char *found = tree_of_cached_taxonomy(ct);
1608 
1609  if (found) {
1610 #ifdef DUMP_TAXONOMY_CACHING
1611  fprintf(stderr, "Deleting cached taxonomy ct=%p (tree='%s')\n", ct, found);
1612 #endif // DUMP_TAXONOMY_CACHING
1613  GBS_write_hash(cached_taxonomies, found, 0); // delete cached taxonomy from hash
1615  }
1616 #ifdef DUMP_TAXONOMY_CACHING
1617  else {
1618  fprintf(stderr, "No tree found for cached_taxonomies ct=%p (already deleted?)\n", ct);
1619  }
1620 #endif // DUMP_TAXONOMY_CACHING
1621 
1622  if (!GB_inside_callback(gbd, GB_CB_DELETE)) {
1624  }
1625 
1626  if (found && !error) {
1628  if (gb_main) {
1629  GBDATA *gb_tree_refresh = GB_search(gb_main, AWAR_TREE_REFRESH, GB_INT);
1630  if (!gb_tree_refresh) {
1631  error = GBS_global_string("%s (while trying to force refresh)", GB_await_error());
1632  }
1633  else {
1634  GB_touch(gb_tree_refresh); // Note : force tree update
1635  }
1636  }
1637  }
1638 
1639  if (error) {
1640  fprintf(stderr, "Error in flush_taxonomy_cb: %s\n", error);
1641  }
1642 }
1643 
1645  // detects the creation of new groups and call flush_taxonomy_cb() manually
1646 #ifdef DUMP_TAXONOMY_CACHING
1647  fputs("flush_taxonomy_if_new_group_cb() has been called\n", stderr);
1648 #endif // DUMP_TAXONOMY_CACHING
1649 
1650  const char *tree_name = tree_of_cached_taxonomy(ct);
1651  if (tree_name) {
1652  int groups = 0;
1653  GBDATA *gb_group_node;
1654 
1655  for (gb_group_node = GB_entry(gb_tree, "node");
1656  gb_group_node;
1657  gb_group_node = GB_nextEntry(gb_group_node))
1658  {
1659  if (GB_entry(gb_group_node, "group_name")) {
1660  groups++; // count named groups only
1661  }
1662  }
1663 
1664 #ifdef DUMP_TAXONOMY_CACHING
1665  fprintf(stderr, "cached_groups=%i counted_groups=%i\n", ct->groups, groups);
1666 #endif // DUMP_TAXONOMY_CACHING
1667  if (groups != ct->groups) {
1668 #ifdef DUMP_TAXONOMY_CACHING
1669  fprintf(stderr, "Number of groups changed -> invoking flush_taxonomy_cb() manually\n");
1670 #endif // DUMP_TAXONOMY_CACHING
1671  flush_taxonomy_cb(gb_tree, ct);
1672  }
1673  }
1674 #ifdef DUMP_TAXONOMY_CACHING
1675  else {
1676  fprintf(stderr, "cached taxonomy no longer valid.\n");
1677  }
1678 #endif // DUMP_TAXONOMY_CACHING
1679 }
1680 
1681 static cached_taxonomy *get_cached_taxonomy(GBDATA *gb_main, const char *tree_name, GB_ERROR *error) {
1682  long cached;
1683  *error = NULp;
1684  if (!cached_taxonomies) {
1685  cached_taxonomies = GBS_create_hash(20, GB_IGNORE_CASE);
1686  }
1687  cached = GBS_read_hash(cached_taxonomies, tree_name);
1688  if (!cached) {
1689  TreeNode *tree = GBT_read_tree(gb_main, tree_name, new SimpleRoot);
1690  if (!tree) *error = GB_await_error();
1691  else *error = GBT_link_tree(tree, gb_main, false, NULp, NULp);
1692 
1693  if (!*error) {
1694  GBDATA *gb_tree = GBT_find_tree(gb_main, tree_name);
1695  if (!gb_tree) {
1696  *error = GBS_global_string("Can't find tree '%s'", tree_name);
1697  }
1698  else {
1699  cached_taxonomy *ct = ARB_alloc<cached_taxonomy>(1);
1700  long nodes = GBT_count_leafs(tree);
1701  int group_counter = 0;
1702 
1703  ct->tree_name = ARB_strdup(tree_name);
1705  ct->groups = 0; // counted below
1706 
1707  build_taxonomy_rek(tree, ct->taxonomy, "<root>", &group_counter);
1708  cached = (long)ct;
1709  GBS_write_hash(cached_taxonomies, tree_name, (long)ct);
1710 
1712  GB_add_callback(gb_tree, GB_CB_SON_CREATED, makeDatabaseCallback(flush_taxonomy_if_new_group_cb, ct));
1713 
1714  {
1715  GBDATA *gb_tree_entry = GB_entry(gb_tree, "tree");
1716  GBDATA *gb_group_node;
1717 
1718  if (gb_tree_entry) {
1720  GB_add_callback(gb_tree_entry, GB_CB_CHANGED_OR_DELETED, makeDatabaseCallback(flush_taxonomy_cb, ct));
1721  }
1722 
1723  // add callbacks for all node/group_name subentries
1724  for (gb_group_node = GB_entry(gb_tree, "node");
1725  gb_group_node;
1726  gb_group_node = GB_nextEntry(gb_group_node))
1727  {
1728  GBDATA *gb_group_name = GB_entry(gb_group_node, "group_name");
1729  if (gb_group_name) { // group with id = 0 has no name
1731  GB_add_callback(gb_group_name, GB_CB_CHANGED_OR_DELETED, makeDatabaseCallback(flush_taxonomy_cb, ct));
1732  ct->groups++;
1733  }
1734  }
1735  }
1736 #ifdef DUMP_TAXONOMY_CACHING
1737  fprintf(stderr, "Created taxonomy hash for '%s' (ct=%p)\n", tree_name, ct);
1738 #endif // DUMP_TAXONOMY_CACHING
1739  }
1740  }
1741 
1742  destroy(tree);
1743  }
1744 
1745  if (!*error) {
1746  cached_taxonomy *ct = (cached_taxonomy*)cached;
1747  gb_assert(ct);
1748  return ct;
1749  }
1750 
1751  return NULp;
1752 }
1753 
1754 static char *get_taxonomy_string(GB_HASH *tax_hash, const char *group_key, int depth, GB_ERROR *error) {
1755  long found;
1756  char *result = NULp;
1757 
1758  gb_assert(depth>0);
1759  gb_assert(!(group_key[0] == '>' && group_key[1] == '>')); // internal group-pointers not allowed here!
1760 
1761  found = GBS_read_hash(tax_hash, group_key);
1762  if (found) {
1763  const char *parent_group_key = (const char *)found;
1764  if (strcmp(parent_group_key, "<root>") == 0) { // root reached
1765  result = ARB_strdup(group_key+(GROUP_COUNT_CHARS+1)); // return own group name
1766  }
1767  else {
1768  if (depth>1) {
1769  char *parent_name = get_taxonomy_string(tax_hash, parent_group_key, depth-1, error);
1770  if (parent_name) {
1771  result = GBS_global_string_copy("%s/%s", parent_name, group_key+(GROUP_COUNT_CHARS+1));
1772  free(parent_name);
1773  }
1774  else {
1775  *error = GBS_global_string("In get_taxonomy_string(%s): %s", group_key, *error);
1776  result = NULp;
1777  }
1778  }
1779  else {
1780  result = ARB_strdup(group_key+(GROUP_COUNT_CHARS+1)); // return own group name
1781  }
1782  }
1783  }
1784  else {
1785  *error = GBS_global_string("Not in tax_hash: '%s'", group_key);
1786  }
1787  return result;
1788 }
1789 
1790 static const char *get_taxonomy(GBDATA *gb_species_or_group, const char *tree_name, bool is_current_tree, int depth, GB_ERROR *error) {
1791  GBDATA *gb_main = GB_get_root(gb_species_or_group);
1792  cached_taxonomy *tax = get_cached_taxonomy(gb_main, tree_name, error);
1793  const char *result = NULp;
1794 
1795  if (tax) {
1796  GBDATA *gb_name = GB_entry(gb_species_or_group, "name");
1797  GBDATA *gb_group_name = GB_entry(gb_species_or_group, "group_name");
1798 
1799  if (gb_name && !gb_group_name) { // it's a species
1800  char *name = GB_read_string(gb_name);
1801  if (name) {
1802  GB_HASH *tax_hash = tax->taxonomy;
1803  long found = GBS_read_hash(tax_hash, GBS_global_string("!%s", name));
1804 
1805  if (found) {
1806  const char *parent_group = (const char *)found;
1807 
1808  if (strcmp(parent_group, "<root>") == 0) {
1809  result = ""; // not member of any group
1810  }
1811  else {
1812  static char *parent = NULp;
1813 
1814  freeset(parent, get_taxonomy_string(tax_hash, parent_group, depth, error));
1815  result = parent;
1816  }
1817  }
1818  else {
1819  result = GBS_global_string("Species '%s' not in '%s'", name, tree_name);
1820  }
1821  free(name);
1822  }
1823  else {
1824  *error = GBS_global_string("Species without 'name' entry!");
1825  }
1826  }
1827  else if (gb_group_name && !gb_name) { // it's a group
1828  char *group_name = GB_read_string(gb_group_name);
1829  if (group_name) {
1830  if (is_current_tree) {
1831  GB_HASH *tax_hash = tax->taxonomy;
1832  long found = GBS_read_hash(tax_hash, GBS_global_string(">>%p", gb_species_or_group));
1833 
1834  if (found) {
1835  static char *full_group = NULp;
1836  const char *group_id = (const char *)found;
1837 
1838  freeset(full_group, get_taxonomy_string(tax_hash, group_id, depth, error));
1839  result = full_group;
1840  }
1841  else {
1842  result = GBS_global_string("Group '%s' not in '%s'", group_name, tree_name);
1843  }
1844  }
1845  else {
1846  *error = "It's not possible to specify the tree name in taxonomy() for groups";
1847  }
1848  free(group_name);
1849  }
1850  else {
1851  *error = "Group without 'group_name' entry";
1852  }
1853  }
1854  else if (gb_group_name) {
1855  *error = "Container has 'name' and 'group_name' entry - can't detect container type";
1856  }
1857  else {
1858  *error = "Container has neither 'name' nor 'group_name' entry - can't detect container type";
1859  }
1860  }
1861 
1862  return result;
1863 }
1864 
1866  GB_ERROR error = check_optional_parameters(args, 1, "count", 1, "tree_name", false, true);
1867  if (!error) {
1868  EXPECT_ITEM_REFERENCED(args);
1870 
1871  char *tree_name = NULp;
1872  bool is_current_tree = false;
1873  int depth = -1;
1874  char *result = NULp;
1875 
1876  if (args->param_count() == 1) { // only 'depth'
1877  if (!args->get_treename()) {
1878  result = ARB_strdup("No default tree");
1879  }
1880  else {
1881  tree_name = ARB_strdup(args->get_treename());
1882  depth = atoi(args->get_param(0));
1883  is_current_tree = true;
1884  }
1885  }
1886  else { // 'tree_name', 'depth'
1887  tree_name = ARB_strdup(args->get_param(0));
1888  depth = atoi(args->get_param(1));
1889  }
1890 
1891  if (!result) {
1892  if (depth<1) {
1893  error = GBS_global_string("Illegal depth '%i' (allowed 1..n)", depth);
1894  }
1895  if (!error) {
1896  const char *taxonomy_string = get_taxonomy(args->get_item_ref(), tree_name, is_current_tree, depth, &error);
1897  if (taxonomy_string) result = ARB_strdup(taxonomy_string);
1898  }
1899  }
1900 
1901  gb_assert(contradicted(result, error));
1902  if (result) PASS_2_OUT(args, result);
1903  free(tree_name);
1904  }
1905  return error;
1906 }
1907 
1909  EXPECT_ITEM_REFERENCED(args);
1911 
1913  if (!error) {
1914  switch (identify_gb_item(args->get_item_ref())) {
1915  case GBT_ITEM_UNKNOWN: {
1916  error = "'sequence' used for unknown item";
1917  break;
1918  }
1919  case GBT_ITEM_SPECIES: {
1920  char *use = GBT_get_default_alignment(args->get_gb_main());
1921 
1922  if (!use) {
1923  error = GB_await_error();
1924  }
1925  else {
1926  GBDATA *gb_seq = GBT_find_sequence(args->get_item_ref(), use);
1927 
1928  if (gb_seq) PASS_2_OUT(args, GB_read_string(gb_seq));
1929  else COPY_2_OUT(args, ""); // if current alignment does not exist -> return empty string
1930 
1931  free(use);
1932  }
1933  break;
1934  }
1935  case GBT_ITEM_GENE: {
1936  char *seq = GBT_read_gene_sequence(args->get_item_ref(), true, 0);
1937 
1938  if (!seq) error = GB_await_error();
1939  else PASS_2_OUT(args, seq);
1940 
1941  break;
1942  }
1943  }
1944  }
1945  return error;
1946 }
1947 
1949  EXPECT_ITEM_REFERENCED(args);
1951 
1953  if (!error) {
1954  switch (identify_gb_item(args->get_item_ref())) {
1955  case GBT_ITEM_UNKNOWN: {
1956  error = "'export_sequence' used for unknown item";
1957  break;
1958  }
1959  case GBT_ITEM_SPECIES: {
1960  if (!get_export_sequence) {
1961  error = "No export-sequence-hook defined (can't use 'export_sequence' here)";
1962  }
1963  else {
1964  size_t len;
1965  const char *seq = get_export_sequence(args->get_item_ref(), &len, &error);
1966 
1967  gb_assert(error || seq);
1968 
1969  if (seq) PASS_2_OUT(args, ARB_strduplen(seq, len));
1970  }
1971  break;
1972  }
1973  case GBT_ITEM_GENE: {
1974  error = "'export_sequence' cannot be used for gene";
1975  break;
1976  }
1977  }
1978  }
1979  return error;
1980 }
1981 
1984 
1986  if (!error) {
1987  GBDATA *gb_main = args->get_gb_main();
1988  char *use = GBT_get_default_alignment(gb_main);
1989  if (!use) error = GB_await_error();
1990  else PASS_2_OUT(args, use);
1991  }
1992  return error;
1993 }
1994 
1997 
1999  if (!error) {
2000  GBDATA *gb_main = args->get_gb_main();
2001  char *use = GBT_get_default_alignment(gb_main);
2002  if (!use) error = GB_await_error();
2003  else PASS_2_OUT(args, GBT_get_alignment_type_string(gb_main, use));
2004  free(use);
2005  }
2006 
2007  return error;
2008 }
2009 
2010 static GB_ERROR format(GBL_command_arguments *args, bool simple_format) {
2011  // simple_format: true = "format", false="format_sequence"
2012 
2013  GB_ERROR error = NULp;
2014  int ic;
2015 
2017  GBL_PARAM_INT(firsttab, "firsttab=", 10, "Indent first line");
2018  GBL_PARAM_INT(tab, "tab=", 10, "Indent not first line");
2019  GBL_PARAM_INT(width, "width=", 50, "Sequence width (bases only)");
2020 
2021  // "format_sequence"-only
2022  GBL_PARAM_BIT (numleft, PARAM_IF(!simple_format, "numleft"), 0, "Numbers left of sequence");
2023  GBL_PARAM_INT (numright, PARAM_IF(!simple_format, "numright="), 0, "Numbers right of sequence (specifies width; -1 -> auto-width)");
2024  GBL_PARAM_UINT(gap, PARAM_IF(!simple_format, "gap="), 10, "Insert ' ' every n sequence characters");
2025 
2026  // "format"-only
2027  GBL_PARAM_STRING(nl, PARAM_IF(simple_format, "nl="), " ", "Break line at characters 'str' if wrapping needed");
2028  GBL_PARAM_STRING(forcenl, PARAM_IF(simple_format, "forcenl="), "\n", "Always break line at characters 'str'");
2029 
2030  GBL_TRACE_PARAMS(args);
2032 
2033  if (tab < 0) tab = 0;
2034  if (firsttab < 0) firsttab = 0;
2035 
2036  if (width == 0) return "Illegal zero width";
2037  if (numleft && numright != 0) return "You may only specify 'numleft' OR 'numright', not both.";
2038 
2039  if (gap<1) gap = UINT_MAX;
2040 
2041  for (ic = 0; ic<args->input.size(); ++ic) {
2042  const char *src = args->input.get(ic);
2043  size_t data_size = strlen(src);
2044  size_t needed_size;
2045  size_t line_size;
2046  int numright_used = numright;
2047 
2048  if (numright_used<0) {
2049  numright_used = calc_digits(data_size);
2050  }
2051 
2052  {
2053  size_t lines;
2054 
2055  if (simple_format) {
2056  lines = data_size/2 + 1; // worst case
2057  line_size = tab + (width>0 ? width : data_size) + 1;
2058  }
2059  else {
2060  size_t gapsPerLine = (width-1)/gap;
2061  lines = data_size/width+1;
2062  line_size = tab + width + gapsPerLine + 1;
2063 
2064  if (numright_used) {
2065  // add space for numright
2066  line_size += numright_used+1; // plus space
2067  }
2068  }
2069 
2070  needed_size = lines*line_size + firsttab + 1 + 10;
2071  }
2072 
2073  char *result = ARB_alloc<char>(needed_size);
2074  if (!result) {
2075  error = GBS_global_string("Out of memory (tried to alloc %zu bytes)", needed_size);
2076  }
2077  else {
2078  char *dst = result;
2079  size_t rest_data = data_size;
2080 
2081  if (simple_format) {
2082  /* format string w/o gaps or numleft
2083  * does word-wrapping at chars in nl
2084  */
2085 
2086  // build wrap table
2087  unsigned char isWrapChar[256];
2088  memset(isWrapChar, 0, sizeof(isWrapChar));
2089  for (int i = 0; nl[i]; ++i) isWrapChar[(unsigned char)nl[i]] = 1;
2090  for (int i = 0; forcenl[i]; ++i) isWrapChar[(unsigned char)forcenl[i]] = 2;
2091 
2092  if (firsttab>0) {
2093  memset(dst, ' ', firsttab);
2094  dst += firsttab;
2095  }
2096 
2097  while (width>0 && rest_data>unsigned(width)) {
2098  int take;
2099  int move;
2100  int took;
2101 
2102  for (take = width; take > 0; --take) {
2103  if (isWrapChar[(unsigned char)src[take]]) break;
2104  }
2105  if (take <= 0) { // no wrap character found -> hard wrap at width
2106  take = move = width;
2107  }
2108  else { // soft wrap at last found wrap character
2109  move = take+1;
2110  }
2111 
2112  for (took = 0; took<take; took++) {
2113  char c = src[took];
2114  if (isWrapChar[(unsigned char)c] == 2) { // forced newline
2115  take = took;
2116  move = take+1;
2117  break;
2118  }
2119  dst[took] = c;
2120  }
2121 
2122  dst += take;
2123  src += move;
2124  rest_data -= move;
2125 
2126  if (rest_data>0) {
2127  *dst++ = '\n';
2128  if (tab>0) {
2129  memset(dst, ' ', tab);
2130  dst += tab;
2131  }
2132  }
2133  }
2134 
2135  if (rest_data>0) {
2136  size_t j, k;
2137  for (j = 0, k = 0; j<rest_data; ++j) {
2138  char c = src[j];
2139 
2140  if (isWrapChar[(unsigned char)c] == 2) {
2141  dst[k++] = '\n';
2142  if (tab>0) {
2143  memset(dst+k, ' ', tab);
2144  k += tab;
2145  }
2146  }
2147  else {
2148  dst[k++] = c;
2149  }
2150  }
2151  src += j;
2152  dst += k;
2153  rest_data = 0;
2154  }
2155  }
2156  else {
2157  // "format_sequence" with gaps and numleft
2158  char *format = NULp;
2159  const char *src_start = src;
2160  const char *dst_linestart = dst;
2161 
2162  if (numleft) {
2163  /* Warning: Be very careful, when you change format strings here!
2164  * currently all format strings result in '%u' or '%-##u' (where # are digits)
2165  */
2166  if (firsttab>0) {
2167  char *firstFormat = GBS_global_string_copy("%%-%iu ", firsttab-1);
2168  dst += sprintf(dst, firstFormat, (unsigned)1);
2169  free(firstFormat);
2170  }
2171  else {
2172  dst += sprintf(dst, "%u ", (unsigned)1);
2173  }
2174  format = tab>0 ? GBS_global_string_copy("%%-%iu ", tab-1) : ARB_strdup("%u ");
2175  }
2176  else if (firsttab>0) {
2177  memset(dst, ' ', firsttab);
2178  dst += firsttab;
2179  }
2180 
2181  while (rest_data>0) {
2182  size_t take = (width>0 && rest_data>unsigned(width)) ? width : rest_data;
2183 
2184  rest_data -= take;
2185 
2186  while (take>gap) {
2187  memcpy(dst, src, gap);
2188  dst += gap;
2189  src += gap;
2190  *dst++ = ' ';
2191  take -= gap;
2192  }
2193 
2194  memcpy(dst, src, take);
2195  dst += take;
2196  src += take;
2197 
2198  if (numright_used) {
2199  if (rest_data) *dst++ = ' ';
2200  else {
2201  // fill in missing spaces for proper alignment of numright
2202  size_t currSize = dst-dst_linestart;
2203  size_t wantSize = line_size-numright_used-1;
2204  if (currSize<wantSize) {
2205  size_t spaces = wantSize-currSize;
2206  memset(dst, ' ', spaces);
2207  dst += spaces;
2208  }
2209  }
2210  unsigned int num = (src-src_start);
2211  dst += sprintf(dst, "%*u", numright_used, num);
2212  }
2213 
2214  if (rest_data>0) {
2215  *dst++ = '\n';
2216  dst_linestart = dst;
2217  if (numleft) {
2218  unsigned int num = (src-src_start)+1; // this goes to the '%u' (see comment above)
2219  dst += sprintf(dst, format, num);
2220  }
2221  else if (tab>0) {
2222  memset(dst, ' ', tab);
2223  dst += tab;
2224  }
2225  }
2226  }
2227 
2228  free(format);
2229  }
2230 
2231  *dst++ = 0; // close str
2232 
2233 #if defined(DEBUG)
2234  { // check for array overflow
2235  size_t used_size = dst-result;
2236  gb_assert(used_size <= needed_size);
2237  ARB_realloc(result, used_size);
2238  }
2239 #endif // DEBUG
2240  }
2241 
2242  if (!error) PASS_2_OUT(args, result);
2243  else free(result);
2244  }
2245  return error;
2246 }
2247 
2248 static GB_ERROR gbl_format (GBL_command_arguments *args) { return format(args, true); }
2249 static GB_ERROR gbl_format_sequence(GBL_command_arguments *args) { return format(args, false); }
2250 
2251 
2252 static char *gbl_read_seq_sai_or_species(GBDATA *gb_main, const char *species, const char *sai, const char *ali, size_t *seqLen) {
2253  /* Reads the alignment 'ali' of 'species' or 'sai'.
2254  * If 'ali' is NULp, use default alignment.
2255  * Returns NULp in case of error (which is exported then)
2256  */
2257 
2258  char *seq = NULp;
2259  GB_ERROR error = NULp;
2260 
2261  int sources = !!species + !!sai;
2262  if (sources != 1) {
2263  error = "Either parameters 'species' or 'SAI' must be specified";
2264  }
2265  else {
2266  GBDATA *gb_item = NULp;
2267  const char *what = NULp;
2268  const char *name = NULp;
2269 
2270  if (species) {
2271  gb_item = GBT_find_species(gb_main, species);
2272  what = "species";
2273  name = species;
2274  }
2275  else {
2276  gb_item = GBT_find_SAI(gb_main, sai);
2277  what = "SAI";
2278  name = sai;
2279  }
2280 
2281  if (!gb_item) error = GBS_global_string("Can't find %s '%s'", what, name);
2282  else {
2283  char *freeMe = NULp;
2284 
2285  if (!ali) {
2286  ali = freeMe = GBT_get_default_alignment(gb_main);
2287  if (!ali) error = GB_await_error();
2288  }
2289 
2290  if (ali) {
2291  GBDATA *gb_ali = GB_entry(gb_item, ali);
2292 
2293  if (gb_ali) {
2294  GBDATA *gb_seq;
2295 
2296  for (gb_seq = GB_child(gb_ali); gb_seq; gb_seq = GB_nextChild(gb_seq)) {
2297  long type = GB_read_type(gb_seq);
2298  if (type == GB_BITS) {
2299  seq = GB_read_bits(gb_seq, '-', '+');
2300  if (seqLen) *seqLen = GB_read_bits_count(gb_seq);
2301  break;
2302  }
2303  if (type == GB_STRING) {
2304  seq = GB_read_string(gb_seq);
2305  if (seqLen) *seqLen = GB_read_string_count(gb_seq);
2306  break;
2307  }
2308  }
2309  }
2310 
2311  if (!seq) error = GBS_global_string("%s '%s' has no (usable) data in alignment '%s'", what, name, ali);
2312  }
2313  free(freeMe);
2314  }
2315  }
2316 
2317  if (error) {
2318  gb_assert(!seq);
2319  GB_export_error(error);
2320  }
2321 
2322  return seq;
2323 }
2324 
2326  const char *align;
2327  const char *sai;
2328  const char *species;
2329  int first;
2331 };
2332 
2333 #define GBL_COMMON_FILTER_PARAMS \
2334  common_filter_params common_param; \
2335  GBL_STRUCT_PARAM_STRING(common_param, align, "align=", NULp, "alignment to use (defaults to default alignment)"); \
2336  GBL_STRUCT_PARAM_STRING(common_param, sai, "SAI=", NULp, "Use default sequence of given SAI as a filter"); \
2337  GBL_STRUCT_PARAM_STRING(common_param, species, "species=", NULp, "Use default sequence of given species as a filter"); \
2338  GBL_STRUCT_PARAM_BIT (common_param, first, "first=", 0, "Use 1st stream as filter for other streams"); \
2339  GBL_STRUCT_PARAM_BIT (common_param, pairwise, "pairwise=", 0, "Use 1st stream as filter for 2nd, 3rd for 4th, ...")
2340 
2341 typedef char* (*filter_fun)(const char *seq, const char *filter, size_t flen, void *param);
2342 /* Note:
2343  * filter_fun has to return a heap copy of the filter-result.
2344  * if 'flen' != 0, it contains the length of 'filter'
2345  * 'param' may be any client data
2346  */
2347 
2348 static GB_ERROR apply_filters(GBL_command_arguments *args, common_filter_params *common, filter_fun filter_one, void *param) {
2349  GB_ERROR error = NULp;
2350 
2351  if (args->input.size()==0) error = "No input stream";
2352  else {
2353  int methodCount = !!common->sai + !!common->species + !!common->pairwise + !!common->first;
2354 
2355  if (methodCount != 1) error = "Need exactly one of the parameters 'SAI', 'species', 'pairwise' or 'first'";
2356  else {
2357  if (common->pairwise) {
2358  if (args->input.size() % 2) error = "Using 'pairwise' requires an even number of input streams";
2359  else {
2360  int i;
2361  for (i = 1; i<args->input.size(); i += 2) {
2362  PASS_2_OUT(args, filter_one(args->input.get(i), args->input.get(i-1), 0, param));
2363  }
2364  }
2365  }
2366  else {
2367  int i = 0;
2368  char *filter = NULp;
2369  size_t flen = 0;
2370 
2371  if (common->first) {
2372  if (args->input.size()<2) error = "Using 'first' needs at least 2 input streams";
2373  else {
2374  const char *in = args->input.get(i++);
2375  gb_assert(in);
2376 
2377  flen = strlen(in);
2378  filter = ARB_strduplen(in, flen);
2379  }
2380  }
2381  else {
2382  filter = gbl_read_seq_sai_or_species(args->get_gb_main(), common->species, common->sai, common->align, &flen);
2383  if (!filter) error = GB_await_error();
2384  }
2385 
2386  gb_assert(filter || error);
2387  if (filter) {
2388  for (; i<args->input.size(); ++i) {
2389  PASS_2_OUT(args, filter_one(args->input.get(i), filter, flen, param));
2390  }
2391  }
2392  free(filter);
2393  }
2394  }
2395  }
2396  return error;
2397 }
2398 
2399 // -------------------------
2400 // calculate diff
2401 
2402 struct diff_params {
2403  char equalC;
2404  char diffC;
2405 };
2406 static char *calc_diff(const char *seq, const char *filter, size_t /*flen*/, void *paramP) {
2407  // filters 'seq' through 'filter'
2408  // - replace all equal positions by 'equal_char' (if != 0)
2409  // - replace all differing positions by 'diff_char' (if != 0)
2410 
2411  diff_params *param = (diff_params*)paramP;
2412  char equal_char = param->equalC;
2413  char diff_char = param->diffC;
2414 
2415  char *result = ARB_strdup(seq);
2416  int p;
2417 
2418  for (p = 0; result[p] && filter[p]; ++p) {
2419  if (result[p] == filter[p]) {
2420  if (equal_char) result[p] = equal_char;
2421  }
2422  else {
2423  if (diff_char) result[p] = diff_char;
2424  }
2425  }
2426 
2427  // if 'seq' is longer than 'filter' and diff_char is given
2428  // -> fill rest of 'result' with 'diff_char'
2429  if (diff_char) {
2430  for (; result[p]; ++p) {
2431  result[p] = diff_char;
2432  }
2433  }
2434 
2435  return result;
2436 }
2440 
2441  diff_params param;
2442  GBL_STRUCT_PARAM_CHAR(param, equalC, "equal=", '.', "symbol for equal characters");
2443  GBL_STRUCT_PARAM_CHAR(param, diffC, "differ=", 0, "symbol for diff characters (default: use char from input stream)");
2444 
2445  GBL_TRACE_PARAMS(args);
2447 
2448  return apply_filters(args, &common_param, calc_diff, &param);
2449 }
2450 
2451 // -------------------------
2452 // standard filter
2453 
2455 
2456 struct filter_params { // used by gbl_filter and gbl_change_gc
2458 
2459  const char *include;
2460  const char *exclude;
2461 
2462  // FP_MODIFY only:
2464  const char *change_to;
2465 };
2466 
2467 static char *filter_seq(const char *seq, const char *filter, size_t flen, void *paramP) {
2468  filter_params *param = (filter_params*)paramP;
2469 
2470  size_t slen = strlen(seq);
2471  if (!flen) flen = strlen(filter);
2472  size_t mlen = slen<flen ? slen : flen;
2473 
2474  GBS_strstruct out(mlen+1); // +1 to avoid invalid, zero-length buffer
2475 
2476  const char *charset;
2477  int include;
2478 
2479  if (param->include) {
2480  charset = param->include;
2481  include = 1;
2482  }
2483  else {
2484  gb_assert(param->exclude);
2485  charset = param->exclude;
2486  include = 0;
2487  }
2488 
2489  size_t pos = 0;
2490  size_t rest = slen;
2491  size_t ctl = 0;
2492  if (param->function == FP_MODIFY) ctl = strlen(param->change_to);
2493 
2494  int inset = 1; // 1 -> check chars in charset, 0 -> check chars NOT in charset
2495  while (rest) {
2496  size_t count;
2497  if (pos >= flen) { // behind filter
2498  // trigger last loop
2499  count = rest;
2500  inset = 0; // if 'include' -> 'applies' will get false, otherwise true
2501  // (meaning is: behind filter nothing can match 'include' or 'exclude')
2502  }
2503  else {
2504  count = (inset ? strspn : strcspn)(filter+pos, charset); // count how many chars are 'inset'
2505  }
2506  if (count) {
2507  int applies = !!include == !!inset; // true -> 'filter' matches 'include' or doesn't match 'exclude'
2508  if (count>rest) count = rest;
2509 
2510  switch (param->function) {
2511  case FP_FILTER:
2512  if (applies) out.ncat(seq+pos, count);
2513  break;
2514 
2515  case FP_MODIFY:
2516  if (applies) { // then modify
2517  size_t i;
2518  for (i = 0; i<count; i++) {
2519  char c = seq[pos+i];
2520  if (isalpha(c) && GB_random(100)<param->change_pc) c = param->change_to[GB_random(ctl)];
2521  out.put(c);
2522  }
2523  }
2524  else { // otherwise simply copy
2525  out.ncat(seq+pos, count);
2526  }
2527  break;
2528  }
2529 
2530  pos += count;
2531  rest -= count;
2532  }
2533  inset = 1-inset; // toggle
2534  }
2535  return out.release();
2536 }
2537 
2541 
2542  filter_params param;
2543  GBL_STRUCT_PARAM_STRING(param, exclude, "exclude=", NULp, "Exclude colums");
2544  GBL_STRUCT_PARAM_STRING(param, include, "include=", NULp, "Include colums");
2545  param.function = FP_FILTER;
2546 
2547  GBL_TRACE_PARAMS(args);
2549 
2550  GB_ERROR error = NULp;
2551  int inOrEx = !!param.include + !!param.exclude;
2552 
2553  if (inOrEx != 1) error = "Need exactly one parameter of: 'include', 'exclude'";
2554  else error = apply_filters(args, &common_param, filter_seq, &param);
2555 
2556  return error;
2557 }
2558 
2562 
2563  filter_params param;
2564  GBL_STRUCT_PARAM_STRING(param, exclude, "exclude=", NULp, "Exclude colums");
2565  GBL_STRUCT_PARAM_STRING(param, include, "include=", NULp, "Include colums");
2566  GBL_STRUCT_PARAM_INT (param, change_pc, "change=", 0, "percentage of changed columns (default: silently change nothing)");
2567  GBL_STRUCT_PARAM_STRING(param, change_to, "to=", "GC", "change to one of this");
2568  param.function = FP_MODIFY;
2569 
2570  GBL_TRACE_PARAMS(args);
2572 
2573  GB_ERROR error = NULp;
2574  int inOrEx = !!param.include + !!param.exclude;
2575 
2576  if (inOrEx != 1) error = "Need exactly one parameter of: 'include', 'exclude'";
2577  else {
2578  error = apply_filters(args, &common_param, filter_seq, &param);
2579  }
2580 
2581  return error;
2582 }
2583 
2585  EXPECT_PARAMS_PASSED(args, "command[,arguments]+");
2586 
2587  // write inputstreams to temp file:
2588  GB_ERROR error = NULp;
2589  char *inputname;
2590  {
2591  char *filename = GB_unique_filename("arb_exec_input", "tmp");
2592  FILE *out = GB_fopen_tempfile(filename, "wt", &inputname);
2593 
2594  if (!out) error = GB_await_error();
2595  else {
2596  for (int i = 0; i<args->input.size(); i++) {
2597  fprintf(out, "%s\n", args->input.get(i));
2598  }
2599  fclose(out);
2600  }
2601  free(filename);
2602  }
2603 
2604  if (!error) {
2605  // build shell command to execute
2606  char *sys;
2607  {
2608  GBS_strstruct str(1000);
2609 
2610  str.cat(args->get_param(0));
2611  for (int i = 1; i<args->param_count(); i++) {
2612  str.cat(" \'");
2613  str.cat(args->get_param(i)); // @@@ use GBK_singlequote here?
2614  str.put('\'');
2615  }
2616  str.cat(" <");
2617  str.cat(inputname);
2618 
2619  sys = str.release();
2620  }
2621 
2622  char *result = NULp;
2623  {
2624  FILE *in = popen(sys, "r");
2625  if (in) {
2626  GBS_strstruct str(4096);
2627 
2628  int i;
2629  while ((i=getc(in)) != EOF) { str.put(i); }
2630  result = str.release();
2631  pclose(in);
2632  }
2633  else {
2634  error = GBS_global_string("Cannot execute shell command '%s'", sys);
2635  }
2636  }
2637 
2638  if (!error) {
2639  gb_assert(result);
2640  PASS_2_OUT(args, result);
2641  }
2642 
2643  free(sys);
2644  }
2645 
2646  gb_assert(GB_is_privatefile(inputname, false));
2647  GB_unlink_or_warn(inputname, &error);
2648  free(inputname);
2649 
2650  return error;
2651 }
2652 
2653 
2655  { "ali_name", gbl_ali_name },
2656  { "caps", gbl_caps },
2657  { "change", gbl_change_gc },
2658  { "checksum", gbl_checksum },
2659  { "command", gbl_command },
2660  { "compare", gbl_compare },
2661  { "colsplit", gbl_colsplit },
2662  { "icompare", gbl_icompare },
2663  { "contains", gbl_contains },
2664  { "icontains", gbl_icontains },
2665  { "count", gbl_count },
2666  { "crop", gbl_crop },
2667  { "cut", gbl_cut },
2668  { "dd", gbl_dd },
2669  { "define", gbl_define },
2670  { "diff", gbl_diff },
2671  { "div", gbl_div },
2672  { "fdiv", gbl_fdiv },
2673  { "do", gbl_do },
2674  { "drop", gbl_drop },
2675  { "dropempty", gbl_dropempty },
2676  { "dropzero", gbl_dropzero },
2677  { "echo", gbl_echo },
2678  { "equals", gbl_equals },
2679  { "iequals", gbl_iequals },
2680  { "escape", gbl_escape },
2681  { "unescape", gbl_unescape },
2682  { "eval", gbl_eval },
2683  { "exec", gbl_exec },
2684  { "export_sequence", gbl_export_sequence },
2685  { "extract_sequence", gbl_extract_sequence },
2686  { "extract_words", gbl_extract_words },
2687  { "filter", gbl_filter },
2688  { "findspec", gbl_findspec },
2689  { "findacc", gbl_findacc },
2690  { "findgene", gbl_findgene },
2691  { "format", gbl_format },
2692  { "format_sequence", gbl_format_sequence },
2693  { "gcgchecksum", gbl_gcgchecksum },
2694  { "head", gbl_head },
2695  { "inRange", gbl_inRange },
2696  { "isAbove", gbl_isAbove },
2697  { "isBelow", gbl_isBelow },
2698  { "isEqual", gbl_isEqual },
2699  { "isEmpty", gbl_isEmpty },
2700  { "keep", gbl_keep },
2701  { "left", gbl_head },
2702  { "len", gbl_len },
2703  { "lower", gbl_lower },
2704  { "merge", gbl_merge },
2705  { "mid", gbl_mid },
2706  { "mid0", gbl_mid0 },
2707  { "minus", gbl_minus },
2708  { "fminus", gbl_fminus },
2709  { "mult", gbl_mult },
2710  { "fmult", gbl_fmult },
2711  { "and", gbl_and },
2712  { "or", gbl_or },
2713  { "not", gbl_not },
2714  { "origin_gene", gbl_origin_gene },
2715  { "origin_organism", gbl_origin_organism },
2716  { "partof", gbl_partof },
2717  { "ipartof", gbl_ipartof },
2718  { "per_cent", gbl_per_cent },
2719  { "fper_cent", gbl_fper_cent },
2720  { "plus", gbl_plus },
2721  { "fplus", gbl_fplus },
2722  { "pretab", gbl_pretab },
2723  { "quote", gbl_quote },
2724  { "unquote", gbl_unquote },
2725  { "readdb", gbl_readdb },
2726  { "remove", gbl_remove },
2727  { "rest", gbl_rest },
2728  { "right", gbl_tail },
2729  { "round", gbl_round },
2730  { "select", gbl_select },
2731  { "sequence", gbl_sequence },
2732  { "sequence_type", gbl_sequence_type },
2733  { "split", gbl_split },
2734  { "srt", gbl_srt },
2735  { "streams", gbl_streams },
2736  { "swap", gbl_swap },
2737  { "tab", gbl_tab },
2738  { "tail", gbl_tail },
2739  { "taxonomy", gbl_taxonomy },
2740  { "toback", gbl_toback },
2741  { "tofront", gbl_tofront },
2742  { "trace", gbl_trace },
2743  { "translate", gbl_translate },
2744  { "upper", gbl_upper },
2745 
2746  { NULp, NULp }
2747 };
2748 
2750  static GBL_command_lookup_table clt(gbl_command_table, ARRAY_ELEMS(gbl_command_table)-1);
2751  return clt;
2752 }
2753 
static GB_ERROR gbl_drop(GBL_command_arguments *args)
Definition: adlang1.cxx:979
static GB_ERROR gbl_toback(GBL_command_arguments *args)
Definition: adlang1.cxx:1073
int traceACI
Definition: adlang1.cxx:44
static GBL_command_definition gbl_command_table[]
Definition: adlang1.cxx:2654
static char * binop_contains(const char *arg1, const char *arg2, bool case_sensitive)
Definition: adlang1.cxx:759
const char * GB_ERROR
Definition: arb_core.h:25
const char * param_name
Definition: gb_aci_impl.h:41
static T binop_per_cent(T v1, T v2)
Definition: adlang1.cxx:1344
string result
size_t GBT_count_leafs(const TreeNode *tree)
Definition: adtree.cxx:842
static GB_ERROR gbl_extract_words(GBL_command_arguments *args)
Definition: adlang1.cxx:1216
GB_TYPES type
void GB_remove_all_callbacks_to(GBDATA *gbd, GB_CB_TYPE type, GB_CB func)
Definition: ad_cb.cxx:364
static void flush_taxonomy_if_new_group_cb(GBDATA *gb_tree, cached_taxonomy *ct)
Definition: adlang1.cxx:1644
static char * calc_diff(const char *seq, const char *filter, size_t, void *paramP)
Definition: adlang1.cxx:2406
static GB_ERROR gbl_iequals(GBL_command_arguments *args)
Definition: adlang1.cxx:776
GB_ERROR check_optional_parameters(GBL_command_arguments *args, int fix, const char *fixParam, int opt, const char *optParam, bool opt_trailing, bool opt_expect_all)
Definition: gb_aci_impl.h:167
static GB_ERROR tab(GBL_command_arguments *args, bool pretab)
Definition: adlang1.cxx:914
static GB_ERROR gbl_and(GBL_command_arguments *args)
Definition: adlang1.cxx:1409
static GB_ERROR gbl_isBelow(GBL_command_arguments *args)
Definition: adlang1.cxx:1366
GBL_streams & output
Definition: gb_aci.h:212
static GB_ERROR gbl_keep(GBL_command_arguments *args)
Definition: adlang1.cxx:737
static GB_ERROR gbl_compare(GBL_command_arguments *args)
Definition: adlang1.cxx:773
#define GBL_STRUCT_PARAM_CHAR(strct,member, param_name, def, help_text)
Definition: gb_aci_impl.h:104
size_t size() const
Definition: arb_strarray.h:85
int(* INT)(int, int)
Definition: adlang1.cxx:1300
bool GEN_is_organism(GBDATA *gb_species)
Definition: adGene.cxx:721
bool operator[](int i) const
Definition: adlang1.cxx:697
#define EXPECT_OPTIONAL_PARAMS(args, fixCnt, fixhelp, optCnt, opthelp)
Definition: gb_aci_impl.h:207
static GB_ERROR gbl_icompare(GBL_command_arguments *args)
Definition: adlang1.cxx:774
Definition: arbdb.h:65
const char * help_text
Definition: gb_aci_impl.h:42
static GB_ERROR gbl_gcgchecksum(GBL_command_arguments *args)
Definition: adlang1.cxx:1258
GBDATA * GB_child(GBDATA *father)
Definition: adquery.cxx:322
static GB_ERROR gbl_icontains(GBL_command_arguments *args)
Definition: adlang1.cxx:778
static GB_ERROR gbl_mult(GBL_command_arguments *args)
Definition: adlang1.cxx:1353
long GBS_write_hash(GB_HASH *hs, const char *key, long val)
Definition: adhash.cxx:454
Definition: arbdb.h:69
static GB_ERROR gbl_fper_cent(GBL_command_arguments *args)
Definition: adlang1.cxx:1359
static GB_ERROR gbl_unescape(GBL_command_arguments *args)
Definition: adlang1.cxx:464
static GB_ERROR gbl_merge(GBL_command_arguments *args)
Definition: adlang1.cxx:1076
static GB_ERROR gbl_origin_organism(GBL_command_arguments *args)
Definition: adlang1.cxx:614
char * GBS_string_eval_in_env(const char *insource, const char *icommand, const GBL_call_env &callEnv)
Definition: admatch.cxx:493
CONSTEXPR_INLINE unsigned char safeCharIndex(char c)
Definition: dupstr.h:73
Definition: adlang1.cxx:689
#define GBL_PARAM_UINT(var,param_name, def, help_text)
Definition: gb_aci_impl.h:99
bool has_group_info() const
Definition: TreeNode.h:444
GB_ERROR GB_add_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
Definition: ad_cb.cxx:356
const char * get(int idx) const
Definition: gb_aci.h:37
static GB_ERROR gbl_dropzero(GBL_command_arguments *args)
Definition: adlang1.cxx:1014
#define EXPECT_OPTIONAL_PARAMS_CUSTOM(args, fixCnt, fixhelp, optCnt, opthelp, trail, all)
Definition: gb_aci_impl.h:208
static gb_export_sequence_cb get_export_sequence
Definition: adlang1.cxx:33
void GB_unlink_or_warn(const char *path, GB_ERROR *error)
Definition: arb_file.cxx:206
#define GBL_PARAM_INT(var,param_name, def, help_text)
Definition: gb_aci_impl.h:97
void GB_sort(void **array, size_t first, size_t behind_last, gb_compare_function compare, void *client_data)
Definition: arb_sort.cxx:27
GBDATA * get_gb_main() const
Definition: gb_aci.h:239
static char * apply_auto_numeric_binop(const char *arg1, const char *arg2, binop_pair multiop)
Definition: adlang1.cxx:1321
static GB_ERROR gbl_quote(GBL_command_arguments *args)
Definition: adlang1.cxx:430
GBDATA * GB_nextEntry(GBDATA *entry)
Definition: adquery.cxx:339
long
Definition: AW_awar.cxx:152
static GB_ERROR gbl_ali_name(GBL_command_arguments *args)
Definition: adlang1.cxx:1982
static GB_ERROR gbl_crop(GBL_command_arguments *args)
Definition: adlang1.cxx:941
#define GBL_BEGIN_PARAMS
Definition: gb_aci_impl.h:45
#define GBL_END_PARAMS
Definition: gb_aci_impl.h:117
static T binop_minus(T v1, T v2)
Definition: adlang1.cxx:1341
char * interpret_subcommand(const char *input, const char *command) const
Definition: gb_aci.h:172
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
const char * get_cmdName() const
Definition: gb_aci.h:241
static char * escapeString(const char *unescapedString)
Definition: adlang1.cxx:404
static GB_ERROR gbl_ipartof(GBL_command_arguments *args)
Definition: adlang1.cxx:780
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
Definition: adtree.cxx:837
#define GBL_PARAM_BIT(var,param_name, def, help_text)
Definition: gb_aci_impl.h:101
static GB_ERROR gbl_taxonomy(GBL_command_arguments *args)
Definition: adlang1.cxx:1865
static GB_ERROR gbl_eval(GBL_command_arguments *args)
Definition: adlang1.cxx:493
static GB_ERROR gbl_escape(GBL_command_arguments *args)
Definition: adlang1.cxx:455
const char * sai
Definition: adlang1.cxx:2327
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
const char * include
Definition: adlang1.cxx:2459
int approve_pos(int pos, int len)
Definition: adlang1.cxx:254
GB_HASH * GBS_create_dynaval_hash(long estimated_elements, GB_CASE case_sens, void(*freefun)(long))
Definition: adhash.cxx:271
void erase()
Definition: arb_strbuf.h:141
static GB_ERROR gbl_format(GBL_command_arguments *args)
Definition: adlang1.cxx:2248
char * release()
Definition: arb_strbuf.h:129
static GB_ERROR gbl_div(GBL_command_arguments *args)
Definition: adlang1.cxx:1355
static GB_ERROR gbl_findgene(GBL_command_arguments *args)
Definition: adlang1.cxx:661
#define GBL_STRUCT_PARAM_INT(strct,member, param_name, def, help_text)
Definition: gb_aci_impl.h:103
void(* GB_CB)(GBDATA *, int *clientdata, GB_CB_TYPE gbtype)
Definition: arbdb_base.h:59
static GB_ERROR gbl_minus(GBL_command_arguments *args)
Definition: adlang1.cxx:1351
CONSTEXPR_INLINE int calc_digits(NUM val)
Definition: arbtools.h:205
void GBS_free_hash(GB_HASH *hs)
Definition: adhash.cxx:538
long GBS_gcgchecksum(const char *seq)
Definition: adstring.cxx:246
const char * species
Definition: adlang1.cxx:2328
void cat(const char *from)
Definition: arb_strbuf.h:199
#define CASTSIG(sig, cb)
Definition: arbtools.h:123
#define COPY_2_OUT(args, s)
Definition: gb_aci_impl.h:20
char * ARB_strpartdup(const char *start, const char *end)
Definition: arb_string.h:51
static GB_ERROR gbl_pretab(GBL_command_arguments *args)
Definition: adlang1.cxx:939
static GB_ERROR gbl_readdb(GBL_command_arguments *args)
Definition: adlang1.cxx:1446
static GB_ERROR gbl_contains(GBL_command_arguments *args)
Definition: adlang1.cxx:777
filter_function
Definition: adlang1.cxx:2454
const char * change_to
Definition: adlang1.cxx:2464
long GB_read_bits_count(GBDATA *gbd)
Definition: arbdb.cxx:921
static T binop_div(T v1, T v2)
Definition: adlang1.cxx:1343
const char * get(const char *name) const
Definition: adlang1.cxx:523
#define ARRAY_ELEMS(array)
Definition: arb_defs.h:19
GB_ERROR GBT_link_tree(TreeNode *tree, GBDATA *gb_main, bool show_status, int *zombies, int *duplicates)
Definition: adtree.cxx:953
GBDATA * GB_get_grandfather(GBDATA *gbd)
Definition: arbdb.cxx:1728
char * GBT_get_alignment_type_string(GBDATA *gb_main, const char *aliname)
Definition: adali.cxx:863
#define ACCEPT_ANY_PARAMS(args)
Definition: gb_aci_impl.h:204
GBT_ITEM_TYPE
Definition: adlang1.cxx:1465
GBDATA * GB_get_father(GBDATA *gbd)
Definition: arbdb.cxx:1722
GB_ERROR gbl_apply_binary_operator(GBL_command_arguments *args, char *(*op)(const char *, const char *, T), T client_data)
Definition: adlang1.cxx:328
const GBL_call_env & get_callEnv() const
Definition: gb_aci.h:234
FILE * seq
Definition: rns.c:46
Tab(bool take, const char *invert)
Definition: adlang1.cxx:692
static GB_HASH * cached_taxonomies
Definition: adlang1.cxx:1580
static GB_ERROR gbl_rest(GBL_command_arguments *args)
Definition: adlang1.cxx:1357
static GB_ERROR gbl_round(GBL_command_arguments *args)
Definition: adlang1.cxx:1381
#define NOT4PERL
Definition: arbdb_base.h:23
static GB_ERROR apply_to_origin(GBL_command_arguments *args, bool organism)
Definition: adlang1.cxx:574
GB_ERROR check_no_parameter(GBL_command_arguments *args)
Definition: gb_aci_impl.h:152
int traceIndent
Definition: adlang1.cxx:45
static GB_ERROR gbl_remove(GBL_command_arguments *args)
Definition: adlang1.cxx:733
static char * apply_numeric_binop(const char *arg1, const char *arg2, int(*num_bin_op)(int, int))
Definition: adlang1.cxx:1305
gbl_param * next
Definition: gb_aci_impl.h:38
const char * get_optional_param(int idx, const char *defaultValue) const
Definition: gb_aci.h:246
int GB_string_comparator(const void *v0, const void *v1, void *)
Definition: arb_sort.cxx:47
static HelixNrInfo * start
const GBL_env & get_env() const
Definition: gb_aci.h:235
const char * GBS_hash_next_element_that(const GB_HASH *hs, const char *last_key, bool(*condition)(const char *key, long val, void *cd), void *cd)
Definition: adhash.cxx:574
static GB_ERROR gbl_change_gc(GBL_command_arguments *args)
Definition: adlang1.cxx:2559
static GB_ERROR gbl_or(GBL_command_arguments *args)
Definition: adlang1.cxx:1419
static GB_ERROR gbl_tail(GBL_command_arguments *args)
Definition: adlang1.cxx:900
GBDATA * GBT_find_SAI(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:177
static T binop_isBelow(T i1, T i2)
Definition: adlang1.cxx:1362
static GB_ERROR gbl_exec(GBL_command_arguments *args)
Definition: adlang1.cxx:2584
GB_ERROR GB_export_error(const char *error)
Definition: arb_msg.cxx:257
#define IN_2_OUT(args, i)
Definition: gb_aci_impl.h:21
GB_ERROR check_valid_stream_index(GBL_command_arguments *args, int number)
Definition: gb_aci_impl.h:185
static GB_ERROR gbl_unquote(GBL_command_arguments *args)
Definition: adlang1.cxx:438
size_t GB_read_string_count(GBDATA *gbd)
Definition: arbdb.cxx:916
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
static int gbl_strincmp(const char *s1, const char *s2, int size2)
Definition: adlang1.cxx:192
Definition: arbdb.h:67
static char * do_extract_words(const char *source, const char *chars, float minlen, bool sort_output)
Definition: adlang1.cxx:1165
fflush(stdout)
char * ARB_strduplen(const char *p, unsigned len)
Definition: arb_string.h:33
GB_TYPES GB_read_type(GBDATA *gbd)
Definition: arbdb.cxx:1643
unsigned int nat
Definition: gb_aci_impl.h:61
static GB_ERROR gbl_command(GBL_command_arguments *args)
Definition: adlang1.cxx:474
static GB_ERROR gbl_cut(GBL_command_arguments *args)
Definition: adlang1.cxx:969
static void build_taxonomy_rek(TreeNode *node, GB_HASH *tax_hash, const char *parent_group, int *group_counter)
Definition: adlang1.cxx:1528
static GB_ERROR gbl_extract_sequence(GBL_command_arguments *args)
Definition: adlang1.cxx:1228
#define PARAM_IF(cond, param)
Definition: gb_aci_impl.h:95
void GB_warningf(const char *templat,...)
Definition: arb_msg.cxx:536
static T binop_isAbove(T i1, T i2)
Definition: adlang1.cxx:1361
static GB_ERROR gbl_upper(GBL_command_arguments *args)
Definition: adlang1.cxx:891
GB_CSTR GB_read_key_pntr(GBDATA *gbd)
Definition: arbdb.cxx:1656
#define PASS_2_OUT(args, s)
Definition: gb_aci_impl.h:19
static char * gbl_read_seq_sai_or_species(GBDATA *gb_main, const char *species, const char *sai, const char *ali, size_t *seqLen)
Definition: adlang1.cxx:2252
static GB_ERROR gbl_swap(GBL_command_arguments *args)
Definition: adlang1.cxx:1025
void print_trace(const char *text)
Definition: adlang1.cxx:47
int chars
Definition: seq_search.cxx:38
static GB_ERROR gbl_checksum(GBL_command_arguments *args)
Definition: adlang1.cxx:1244
bool is_leftson() const
Definition: TreeNode.h:228
CONSTEXPR_INLINE int digits(int parts)
static const char * gbl_stristr(const char *haystack, const char *needle)
Definition: adlang1.cxx:209
#define EXPECT_ITEM_REFERENCED(args)
Definition: gb_aci_impl.h:215
static GBT_ITEM_TYPE identify_gb_item(GBDATA *gb_item)
Definition: adlang1.cxx:1471
T_PT_MAIN com
char * get_copy() const
Definition: arb_strbuf.h:125
Definition: arbdb.h:64
bool set_params_checked()
Definition: gb_aci.h:250
double(* DOUBLE)(double, double)
Definition: adlang1.cxx:1301
#define COMMAND_DROPS_INPUT_STREAMS(args)
Definition: gb_aci_impl.h:218
static GB_ERROR gbl_dropempty(GBL_command_arguments *args)
Definition: adlang1.cxx:1003
static bool is_cached_taxonomy(const char *, long val, void *cl_ct)
Definition: adlang1.cxx:1582
static GB_ERROR gbl_tab(GBL_command_arguments *args)
Definition: adlang1.cxx:938
const char * get_param(int idx) const
Definition: gb_aci.h:245
static void error(const char *msg)
Definition: mkptypes.cxx:96
#define TRACE_ACI(text)
Definition: gb_aci_impl.h:195
GBDATA * GB_get_root(GBDATA *gbd)
Definition: arbdb.cxx:1740
#define GBL_STRUCT_PARAM_STRING(strct, member, param_name, def, help_text)
Definition: gb_aci_impl.h:106
static GB_ERROR gbl_isEqual(GBL_command_arguments *args)
Definition: adlang1.cxx:1367
char * GB_read_bits(GBDATA *gbd, char c_0, char c_1)
Definition: arbdb.cxx:958
#define AWAR_TREE_REFRESH
FILE * GB_fopen_tempfile(const char *filename, const char *fmode, char **res_fullname)
Definition: adsocket.cxx:1176
static GB_ERROR gbl_not(GBL_command_arguments *args)
Definition: adlang1.cxx:1398
fputc('\n', stderr)
static T binop_mult(T v1, T v2)
Definition: adlang1.cxx:1342
#define GROUP_COUNT_CHARS
Definition: adlang1.cxx:1504
#define PARAM_2_OUT(args, i)
Definition: gb_aci_impl.h:22
static GB_ERROR backfront_stream(GBL_command_arguments *args, int toback)
Definition: adlang1.cxx:1057
#define GBL_COMMON_FILTER_PARAMS
Definition: adlang1.cxx:2333
char * str
Definition: defines.h:20
GB_ERROR trace_params(const GBL_streams &param, gbl_param *ppara, const char *com)
Definition: adlang1.cxx:68
static GB_ERROR gbl_sequence(GBL_command_arguments *args)
Definition: adlang1.cxx:1908
static GB_ERROR gbl_select(GBL_command_arguments *args)
Definition: adlang1.cxx:1430
GB_write_int const char GB_write_autoconv_string WRITE_SKELETON(write_pointer, GBDATA *,"%p", GB_write_pointer) char *AW_awa if)(!gb_var) return strdup("")
Definition: AW_awar.cxx:163
int GB_random(int range)
Definition: admath.cxx:88
GBDATA * GEN_find_gene_data(GBDATA *gb_species)
Definition: adGene.cxx:50
static void free_cached_taxonomy(cached_taxonomy *ct)
Definition: adlang1.cxx:1522
static GB_ERROR gbl_findacc(GBL_command_arguments *args)
Definition: adlang1.cxx:656
static void flush_taxonomy_cb(GBDATA *gbd, cached_taxonomy *ct)
Definition: adlang1.cxx:1600
Case
Definition: adlang1.cxx:861
void GBS_dynaval_free(long val)
Definition: adhash.cxx:278
static GB_ERROR gbl_mid(GBL_command_arguments *args)
Definition: adlang1.cxx:912
static SearchTree * tree[SEARCH_PATTERNS]
Definition: ED4_search.cxx:629
static GB_ERROR gbl_colsplit(GBL_command_arguments *args)
Definition: adlang1.cxx:1141
static GB_ERROR gbl_partof(GBL_command_arguments *args)
Definition: adlang1.cxx:779
static GB_ERROR gbl_filter(GBL_command_arguments *args)
Definition: adlang1.cxx:2538
static const char * tree_of_cached_taxonomy(cached_taxonomy *ct)
Definition: adlang1.cxx:1589
static GB_ERROR gbl_fmult(GBL_command_arguments *args)
Definition: adlang1.cxx:1354
static GB_ERROR gbl_isEmpty(GBL_command_arguments *args)
Definition: adlang1.cxx:782
static GB_ERROR gbl_mid_streams(const GBL_streams &arg_input, GBL_streams &arg_out, int start, int end)
Definition: adlang1.cxx:256
const char * exclude
Definition: adlang1.cxx:2460
GB_ERROR count_by_tab(GBL_command_arguments *args, const Tab &tab)
Definition: adlang1.cxx:700
static GB_ERROR apply_filters(GBL_command_arguments *args, common_filter_params *common, filter_fun filter_one, void *param)
Definition: adlang1.cxx:2348
binop_pair(int(*INT_)(int, int), double(*DOUBLE_)(double, double))
Definition: adlang1.cxx:1302
void nl()
Definition: test_unit.h:415
GBDATA * GBT_find_sequence(GBDATA *gb_species, const char *aliname)
Definition: adali.cxx:708
char * GBT_read_gene_sequence(GBDATA *gb_gene, bool use_revComplement, char partSeparator)
Definition: adali.cxx:1062
static char * filter_seq(const char *seq, const char *filter, size_t flen, void *paramP)
Definition: adlang1.cxx:2467
static char * apply_double_binop(const char *arg1, const char *arg2, double(*num_bin_op)(double, double))
Definition: adlang1.cxx:1313
static GB_ERROR gbl_origin_gene(GBL_command_arguments *args)
Definition: adlang1.cxx:613
static GB_ERROR gbl_trace(GBL_command_arguments *args)
Definition: adlang1.cxx:278
const char *(* gb_export_sequence_cb)(GBDATA *gb_species, size_t *seq_len, GB_ERROR *error)
Definition: arbdb.h:134
const char * align
Definition: adlang1.cxx:2326
static GB_ERROR gbl_export_sequence(GBL_command_arguments *args)
Definition: adlang1.cxx:1948
char * GB_unique_filename(const char *name_prefix, const char *suffix)
Definition: adsocket.cxx:1233
GBDATA * get_item_ref() const
Definition: gb_aci.h:233
void insert(char *copy)
Definition: gb_aci.h:35
#define EXPECT_NO_PARAM(args)
Definition: gb_aci_impl.h:202
static GB_ERROR gbl_equals(GBL_command_arguments *args)
Definition: adlang1.cxx:775
static GB_ERROR gbl_srt(GBL_command_arguments *args)
Definition: adlang1.cxx:1271
static GB_ERROR gbl_lower(GBL_command_arguments *args)
Definition: adlang1.cxx:892
static GB_ERROR convert_case(GBL_command_arguments *args, Case convTo)
Definition: adlang1.cxx:863
fputs(TRACE_PREFIX, stderr)
ASSERTING_CONSTEXPR_INLINE int bio2info(int biopos)
Definition: arb_defs.h:26
static GB_ERROR gbl_sequence_type(GBL_command_arguments *args)
Definition: adlang1.cxx:1995
GB_ERROR GB_export_errorf(const char *templat,...)
Definition: arb_msg.cxx:262
static T binop_plus(T v1, T v2)
Definition: adlang1.cxx:1340
static void copy(double **i, double **j)
Definition: trnsprob.cxx:32
static GB_ERROR gbl_fdiv(GBL_command_arguments *args)
Definition: adlang1.cxx:1356
void ncat(const char *from, size_t count)
Definition: arb_strbuf.h:189
bool is_leaf() const
Definition: TreeNode.h:211
static GB_ERROR gbl_echo(GBL_command_arguments *args)
Definition: adlang1.cxx:849
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
static DefinedCommands defined_commands
Definition: adlang1.cxx:526
#define gb_assert(cond)
Definition: arbdbt.h:11
void set(const char *name, char *cmd)
Definition: adlang1.cxx:522
#define FORMAT_2_OUT(args, fmt, value)
Definition: gb_aci_impl.h:24
GBDATA * GEN_find_origin_organism(GBDATA *gb_pseudo, const GB_HASH *organism_hash)
Definition: adGene.cxx:643
char * ARB_strndup(const char *start, int len)
Definition: arb_string.h:83
static const char * get_taxonomy(GBDATA *gb_species_or_group, const char *tree_name, bool is_current_tree, int depth, GB_ERROR *error)
Definition: adlang1.cxx:1790
NOT4PERL void GB_set_export_sequence_hook(gb_export_sequence_cb escb)
Definition: adlang1.cxx:35
int size() const
Definition: gb_aci.h:39
static GB_ERROR format(GBL_command_arguments *args, bool simple_format)
Definition: adlang1.cxx:2010
static GB_ERROR gbl_plus(GBL_command_arguments *args)
Definition: adlang1.cxx:1349
void GB_touch(GBDATA *gbd)
Definition: arbdb.cxx:2802
static char * binop_partof(const char *arg1, const char *arg2, bool case_sensitive)
Definition: adlang1.cxx:769
static int gbl_stricmp(const char *s1, const char *s2)
Definition: adlang1.cxx:175
static GB_ERROR gbl_fplus(GBL_command_arguments *args)
Definition: adlang1.cxx:1350
GB_ERROR check_valid_param_index(GBL_command_arguments *args, int number)
Definition: gb_aci_impl.h:186
#define GBL_PARAM_STRING(var, param_name, def, help_text)
Definition: gb_aci_impl.h:100
char * name
Definition: TreeNode.h:174
void ARB_realloc(TYPE *&tgt, size_t nelem)
Definition: arb_mem.h:43
static GB_ERROR gbl_count(GBL_command_arguments *args)
Definition: adlang1.cxx:724
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:909
static int binop_rest(int i1, int i2)
Definition: adlang1.cxx:1346
static GB_ERROR gbl_diff(GBL_command_arguments *args)
Definition: adlang1.cxx:2437
static char * get_taxonomy_string(GB_HASH *tax_hash, const char *group_key, int depth, GB_ERROR *error)
Definition: adlang1.cxx:1754
char * GBT_read_as_string(GBDATA *gb_container, const char *fieldpath)
Definition: adtools.cxx:290
static GB_ERROR gbl_split(GBL_command_arguments *args)
Definition: adlang1.cxx:1094
static ARB_init_perl_interface init
Definition: ARB_ext.c:101
uint32_t GBS_checksum(const char *seq, int ignore_case, const char *exclude)
Definition: adstring.cxx:352
static GB_ERROR gbl_len(GBL_command_arguments *args)
Definition: adlang1.cxx:728
static GB_ERROR gbl_isAbove(GBL_command_arguments *args)
Definition: adlang1.cxx:1365
GB_HASH * taxonomy
Definition: adlang1.cxx:1511
GB_ERROR remove_by_tab(GBL_command_arguments *args, const Tab &tab)
Definition: adlang1.cxx:710
int param_count() const
Definition: gb_aci.h:244
GBDATA * GB_find_string(GBDATA *gbd, const char *key, const char *str, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
Definition: adquery.cxx:302
static T binop_isEqual(T i1, T i2)
Definition: adlang1.cxx:1363
static GB_ERROR gbl_do(GBL_command_arguments *args)
Definition: adlang1.cxx:540
char *(* filter_fun)(const char *seq, const char *filter, size_t flen, void *param)
Definition: adlang1.cxx:2341
static char * binop_equals(const char *arg1, const char *arg2, bool case_sensitive)
Definition: adlang1.cxx:751
static GB_ERROR gbl_define(GBL_command_arguments *args)
Definition: adlang1.cxx:528
static int line
Definition: arb_a2ps.c:296
#define KEELED_INDICATOR
Definition: TreeNode.h:168
#define NULp
Definition: cxxforward.h:116
GBDATA * GBT_find_species(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:139
static GB_ERROR gbl_caps(GBL_command_arguments *args)
Definition: adlang1.cxx:890
static GB_ERROR applyToItemFoundByKey(GBL_command_arguments *args, const char *itemname, GBDATA *gb_item_data, const char *key)
Definition: adlang1.cxx:617
static char * command
Definition: arb_a2ps.c:319
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, SplitMode mode)
Definition: arb_strarray.h:223
#define MAX_GROUPS
Definition: adlang1.cxx:1506
double float_shift_factor(int digits)
Definition: adlang1.cxx:1369
char * GBT_get_default_alignment(GBDATA *gb_main)
Definition: adali.cxx:747
const char * get_data() const
Definition: arb_strbuf.h:120
const char * GBT_get_name(GBDATA *gb_item)
Definition: aditem.cxx:468
Definition: trnsprob.h:20
GBDATA * GB_nextChild(GBDATA *child)
Definition: adquery.cxx:326
GBL_streams & input
Definition: gb_aci.h:211
#define GBL_TRACE_PARAMS(args)
Definition: gb_aci_impl.h:109
TreeNode * keelTarget()
Definition: TreeNode.h:448
static GB_ERROR gbl_dd(GBL_command_arguments *args)
Definition: adlang1.cxx:856
GBDATA * GBT_find_tree(GBDATA *gb_main, const char *tree_name)
Definition: adtree.cxx:993
void destroy(TreeNode *that)
Definition: TreeNode.h:600
GBDATA * gb_node
Definition: TreeNode.h:173
GBDATA * gb_main
Definition: adname.cxx:32
GBDATA * GB_get_gb_main_during_cb()
Definition: ad_cb.cxx:142
static GB_ERROR gbl_fminus(GBL_command_arguments *args)
Definition: adlang1.cxx:1352
static GB_ERROR gbl_per_cent(GBL_command_arguments *args)
Definition: adlang1.cxx:1358
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
const char * GB_KEY(GBDATA *gbd)
Definition: gb_key.h:49
NOT4PERL bool GB_inside_callback(GBDATA *of_gbd, GB_CB_TYPE cbtype)
Definition: ad_cb.cxx:115
GB_CSTR GBT_get_name_or_description(GBDATA *gb_item)
Definition: aditem.cxx:459
bool GEN_is_genome_db(GBDATA *gb_main, int default_value)
Definition: adGene.cxx:20
const char * track_field_access(const char *fieldname) const
Definition: gb_aci.h:237
static GB_ERROR gbl_streams(GBL_command_arguments *args)
Definition: adlang1.cxx:562
#define EXPECT_LEGAL_STREAM_INDEX(args, number)
Definition: gb_aci_impl.h:210
bool GEN_is_pseudo_gene_species(GBDATA *gb_species)
Definition: adGene.cxx:558
static GB_ERROR expect_used_in_genome_db(GBL_command_arguments *args)
Definition: adlang1.cxx:569
#define STATIC_ASSERT(const_expression)
Definition: static_assert.h:37
char * tree_name
Definition: adlang1.cxx:1509
static GB_ERROR gbl_translate(GBL_command_arguments *args)
Definition: adlang1.cxx:805
static cached_taxonomy * get_cached_taxonomy(GBDATA *gb_main, const char *tree_name, GB_ERROR *error)
Definition: adlang1.cxx:1681
static GB_ERROR gbl_head(GBL_command_arguments *args)
Definition: adlang1.cxx:894
const GBL_command_lookup_table & ACI_get_standard_commands()
Definition: adlang1.cxx:2749
#define EXPECT_PARAMS(args, cnt, help)
Definition: gb_aci_impl.h:206
char * release_memfriendly()
Definition: arb_strbuf.h:133
long GBS_read_hash(const GB_HASH *hs, const char *key)
Definition: adhash.cxx:392
GB_ERROR mid(GBL_command_arguments *args, int start_index)
Definition: adlang1.cxx:907
static GB_ERROR gbl_format_sequence(GBL_command_arguments *args)
Definition: adlang1.cxx:2249
GBDATA * GB_entry(GBDATA *father, const char *key)
Definition: adquery.cxx:334
static GB_ERROR gbl_mid0(GBL_command_arguments *args)
Definition: adlang1.cxx:911
filter_function function
Definition: adlang1.cxx:2457
#define EXPECT_PARAMS_PASSED(args, syntax)
Definition: gb_aci_impl.h:203
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
static GB_ERROR gbl_findspec(GBL_command_arguments *args)
Definition: adlang1.cxx:652
static GB_ERROR gbl_tofront(GBL_command_arguments *args)
Definition: adlang1.cxx:1074
bool GB_is_privatefile(const char *path, bool read_private)
Definition: arb_file.cxx:124
static char * binop_compare(const char *arg1, const char *arg2, bool case_sensitive)
Definition: adlang1.cxx:743
GB_HASH * GBS_create_hash(long estimated_elements, GB_CASE case_sens)
Definition: adhash.cxx:253
void put(char c)
Definition: arb_strbuf.h:174
GBDATA * GEN_find_origin_gene(GBDATA *gb_pseudo, const GB_HASH *organism_hash)
Definition: adGene.cxx:666
Definition: arbdb.h:66
static GB_ERROR gbl_inRange(GBL_command_arguments *args)
Definition: adlang1.cxx:790
const char * get_treename() const
Definition: gb_aci.h:240
static char * unEscapeString(const char *escapedString)
Definition: adlang1.cxx:384
GBDATA * GBT_get_species_data(GBDATA *gb_main)
Definition: aditem.cxx:105
GB_write_int const char s
Definition: AW_awar.cxx:154