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", true);
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  gbl_param **params;
130  int k;
131  char *res;
132  GBS_strstruct *str = GBS_stropen(1000);
133  GB_ERROR err;
134 
135 
136  for (para = ppara; para; para = para->next) pcount++;
137  ARB_calloc(params, pcount);
138  for (k = 0, para = ppara; para; para = para->next) params[k++] = para;
139 
140 
141  for (pcount--; pcount>=0; pcount--) {
142  para = params[pcount];
143  if (para->param_name) {
144  GBS_strcat(str, " ");
145  GBS_strcat(str, para->param_name);
146  switch (para->type) {
147  case GB_STRING: GBS_strcat(str, "STRING"); break;
148  case GB_INT: GBS_strcat(str, "INT"); break;
149  case GB_FLOAT: GBS_strcat(str, "FLOAT"); break;
150  case GB_BYTE: GBS_strcat(str, "CHAR"); break;
151  case GB_BIT: GBS_strcat(str, " "); break;
152  default: gb_assert (0); GBS_strcat(str, "????"); break;
153  }
154  GBS_strcat(str, "\t\t;");
155  GBS_strcat(str, para->help_text);
156  GBS_strcat(str, "\n");
157  }
158  }
159  freenull(params);
160  res = GBS_strclose(str);
161  err = GB_export_errorf("Unknown Parameter '%s' in command '%s'\n PARAMETERS:\n%s", argument, com, res);
162  free(res);
163  return err;
164  }
165  }
166 
167  return error;
168  }
169 };
170 
171 
172 
173 // -------------------------
174 // String functions
175 
176 static int gbl_stricmp(const char *s1, const char *s2) {
177  // case insensitive strcmp
178  int i;
179  for (i = 0; ; ++i) {
180  char c1 = tolower(s1[i]);
181  char c2 = tolower(s2[i]);
182 
183  if (c1 == c2) {
184  if (!c1) break; // equal strings
185  }
186  else {
187  if (c1<c2) return -1;
188  return 1;
189  }
190  }
191  return 0;
192 }
193 static int gbl_strincmp(const char *s1, const char *s2, int size2) {
194  // case insensitive strcmp
195  int i;
196  for (i = 0; i<size2; ++i) {
197  char c1 = tolower(s1[i]);
198  char c2 = tolower(s2[i]);
199 
200  if (c1 == c2) {
201  if (!c1) break; // equal strings
202  }
203  else {
204  if (c1<c2) return -1;
205  return 1;
206  }
207  }
208  return 0;
209 }
210 static const char *gbl_stristr(const char *haystack, const char *needle) {
211  // case insensitive strstr
212  const char *hp = haystack;
213  char c1 = toupper(needle[0]);
214  char c2 = tolower(c1);
215  int needle_size = strlen(needle);
216 
217  if (c1 == c2) {
218  hp = strchr(hp, c1);
219  while (hp) {
220  if (gbl_strincmp(hp, needle, needle_size) == 0) return hp;
221  hp = strchr(hp+1, c1);
222  }
223  }
224  else {
225  while (hp) {
226  const char *h1 = strchr(hp, c1);
227  const char *h2 = strchr(hp, c2);
228 
229  if (h1 && h2) {
230  if (h1<h2) {
231  if (gbl_strincmp(h1, needle, needle_size) == 0) return h1;
232  hp = h1+1;
233  }
234  else {
235  gb_assert(h1>h2);
236  if (gbl_strincmp(h2, needle, needle_size) == 0) return h2;
237  hp = h2+1;
238  }
239  }
240  else {
241  if (h1) { hp = h1; }
242  else if (h2) { hp = h2; c1 = c2; }
243  else { hp = NULp; }
244 
245  while (hp) {
246  if (gbl_strincmp(hp, needle, needle_size) == 0) return hp;
247  hp = strchr(hp+1, c1);
248  }
249  }
250  }
251  }
252  return NULp;
253 }
254 
255 inline int approve_pos(int pos, int len) { return pos<0 ? (-pos<len ? len+pos : 0) : pos; }
256 
257 static GB_ERROR gbl_mid_streams(const GBL_streams& arg_input, GBL_streams& arg_out, int start, int end) {
258  // used as well to copy all streams (e.g. by 'dd')
259  for (int i=0; i<arg_input.size(); i++) {
260  const char *p = arg_input.get(i);
261  int len = strlen(p);
262 
263  int s = approve_pos(start, len);
264  int e = approve_pos(end, len);
265 
266  char *res;
267  if (s >= len || e<s) {
268  res = ARB_strdup("");
269  }
270  else {
271  gb_assert(s >= 0);
272  res = ARB_strpartdup(p+s, p+e);
273  }
274  arg_out.insert(res);
275  }
276  return NULp;
277 }
278 
280  int tmp_trace;
281 
282  EXPECT_PARAMS(args, 1, "0|1");
283 
284  tmp_trace = atoi(args->get_param(0));
285  if (tmp_trace<0 || tmp_trace>1) return GBS_global_string("Illegal value %i to trace", tmp_trace);
286 
287  if (tmp_trace != traceACI) {
288  traceACI = 1;
289  print_trace(GBS_global_string("%sctivated ACI trace\n", tmp_trace ? "A" : "De-a"));
290  traceACI = tmp_trace;
291  }
292 
293  return gbl_mid_streams(args->input, args->output, 0, -1); // copy all streams
294 }
295 
296 /* ---------------------------------------------------------------------------------------
297  * Binary operators work on pairs of values.
298  * Three different operational modes are implemented for all binary operators:
299  *
300  * 1. inputstreams|operator
301  *
302  * The number of inputstreams has to be even and the operator will be
303  * applied to pairs of them.
304  *
305  * Example : a;b;c;d;e;f | plus
306  * Result : a+b;c+d;e+f
307  *
308  * 2. inputstreams|operator(x)
309  *
310  * The number of inputstreams has to be at least 1.
311  * The operator is applied to each inputstream.
312  *
313  * Example : a;b;c | plus(d)
314  * Result : a+d;b+d;c+d
315  *
316  * 3. operator(x, y)
317  *
318  * @@@ this decription does not match behavior!
319  * @@@ check description in helpfile as well
320  *
321  * Inputstreams will be ignored and the operator is applied
322  * to the arguments
323  *
324  * Example : a;b | plus(c,d)
325  * Result : c+d
326  */
327 
328 template <typename T>
329 GB_ERROR gbl_apply_binary_operator(GBL_command_arguments *args, char *(*op)(const char *, const char *, T), T client_data) {
330  GB_ERROR error = NULp;
331  switch (args->param_count()) {
332  case 0:
333  gb_assert(args->set_params_checked());
334  if (args->input.size() == 0) error = "Expect at least two input streams if called with 0 parameters";
335  else if (args->input.size()%2) error = "Expect an even number of input streams if called with 0 parameters";
336  else {
337  int inputpairs = args->input.size()/2;
338  int i;
339  for (i = 0; i<inputpairs; ++i) {
340  PASS_2_OUT(args, op(args->input.get(i*2), args->input.get(i*2+1), client_data));
341  }
342  }
343  break;
344 
345  case 1:
346  gb_assert(args->set_params_checked());
347  if (args->input.size() == 0) error = "Expect at least one input stream if called with 1 parameter";
348  else {
349  int i;
350  const char *argument = args->get_param(0);
351  for (i = 0; i<args->input.size(); ++i) {
352  PASS_2_OUT(args, op(args->input.get(i), argument, client_data));
353  }
354  }
355  break;
356 
357  case 2:
358  gb_assert(args->set_params_checked());
359  for (int i = 0; i<args->input.size(); ++i) {
360  char *result1 = args->get_callEnv().interpret_subcommand(args->input.get(i), args->get_param(0)); // @@@ EVALUATED_PARAM (#768)
361  if (!result1) error = GB_await_error();
362  else {
363  char *result2 = args->get_callEnv().interpret_subcommand(args->input.get(i), args->get_param(1)); // @@@ EVALUATED_PARAM (#768)
364  if (!result2) error = GB_await_error();
365  else {
366  PASS_2_OUT(args, op(result1, result2, client_data));
367  free(result2);
368  }
369  free(result1);
370  }
371  }
372  break;
373 
374  default:
375  error = check_optional_parameters(args, 0, NULp, 2, "Expr1[,Expr2]", true, false);
376  break;
377  }
378 
379  return error;
380 }
381 
382 // --------------------------------
383 // escape/unescape strings
384 
385 static char *unEscapeString(const char *escapedString) {
386  // replaces all \x by x
387  char *result = nulldup(escapedString);
388  char *to = result;
389  char *from = result;
390 
391  while (1) {
392  char c = *from++;
393  if (!c) break;
394 
395  if (c=='\\') {
396  *to++ = *from++;
397  }
398  else {
399  *to++ = c;
400  }
401  }
402  *to = 0;
403  return result;
404 }
405 static char *escapeString(const char *unescapedString) {
406  // replaces all '\' and '"' by '\\' and '\"'
407  int len = strlen(unescapedString);
408  char *result = ARB_alloc<char>(2*len+1);
409  char *to = result;
410  const char *from = unescapedString;
411 
412  while (1) {
413  char c = *from++;
414  if (!c) break;
415 
416  if (c=='\\' || c == '\"') {
417  *to++ = '\\';
418  *to++ = c;
419  }
420  else {
421  *to++ = c;
422  }
423  }
424  *to = 0;
425  return result;
426 }
427 
428 // ---------------------------------
429 // the commands themselves:
430 
432  EXPECT_NO_PARAM(args);
433 
434  for (int i=0; i<args->input.size(); i++) {
435  FORMAT_2_OUT(args, "\"%s\"", args->input.get(i));
436  }
437  return NULp;
438 }
440  EXPECT_NO_PARAM(args);
441 
442  for (int i=0; i<args->input.size(); i++) {
443  const char *str = args->input.get(i);
444  int len = strlen(str);
445 
446  if (str[0] == '\"' && str[len-1] == '\"') {
447  PASS_2_OUT(args, ARB_strpartdup(str+1, str+len-2));
448  }
449  else {
450  IN_2_OUT(args, i);
451  }
452  }
453  return NULp;
454 }
455 
457  EXPECT_NO_PARAM(args);
458 
459  for (int i=0; i<args->input.size(); i++) {
460  char *escaped = escapeString(args->input.get(i));
461  PASS_2_OUT(args, escaped);
462  }
463  return NULp;
464 }
466  EXPECT_NO_PARAM(args);
467 
468  for (int i=0; i<args->input.size(); i++) {
469  char *unescaped = unEscapeString(args->input.get(i));
470  PASS_2_OUT(args, unescaped);
471  }
472  return NULp;
473 }
474 
476  EXPECT_PARAMS(args, 1, "\"ACI command\"");
477 
478  GB_ERROR error = NULp;
479  char *command = unEscapeString(args->get_param(0));
480 
481  if (traceACI) {
482  print_trace(GBS_global_string("executing command '%s'\n", command));
483  }
484 
485  for (int i=0; i<args->input.size() && !error; i++) {
486  char *result = args->get_callEnv().interpret_subcommand(args->input.get(i), command);
487  if (!result) error = GB_await_error();
488  else PASS_2_OUT(args, result);
489  }
490  free(command);
491  return error;
492 }
493 
495  EXPECT_PARAMS(args, 1, "\"expression evaluating to ACI command\"");
496 
497  GB_ERROR error = NULp;
498  char *to_eval = unEscapeString(args->get_param(0));
499  TRACE_ACI(GBS_global_string("evaluating '%s'\n", to_eval));
500 
501  char *command = args->get_callEnv().interpret_subcommand("", to_eval); // evaluate independent
502  if (!command) error = GB_await_error();
503  else {
504  TRACE_ACI(GBS_global_string("executing '%s'\n", command));
505 
506  for (int i=0; i<args->input.size() && !error; i++) {
507  char *result = args->get_callEnv().interpret_subcommand(args->input.get(i), command);
508  if (!result) error = GB_await_error();
509  else PASS_2_OUT(args, result);
510  }
511  free(command);
512  }
513  free(to_eval);
514  return error;
515 }
516 
517 class DefinedCommands : virtual Noncopyable {
518  GB_HASH *cmds;
519 public:
522 
523  void set(const char *name, char* cmd) { GBS_dynaval_free(GBS_write_hash(cmds, name, (long)cmd)); } // takes ownership of 'cmd'!
524  const char *get(const char *name) const { return (const char *)GBS_read_hash(cmds, name); }
525 };
526 
528 
531  EXPECT_PARAMS(args, 2, "name, \"ACI command\"");
532 
533  const char *name = args->get_param(0);
534  char *cmd = unEscapeString(args->get_param(1));
535 
536  defined_commands.set(name, cmd);
537  TRACE_ACI(GBS_global_string("defining command '%s'='%s'\n", name, cmd));
538  return NULp;
539 }
540 
542  EXPECT_PARAMS(args, 1, "definedCommandName");
543 
544  GB_ERROR error = NULp;
545  const char *name = args->get_param(0);
546  const char *cmd = defined_commands.get(name);
547 
548  if (!cmd) {
549  error = GBS_global_string("Can't do undefined command '%s' - use define(%s, ...) first", name, name);
550  }
551  else {
552  TRACE_ACI(GBS_global_string("executing defined command '%s'='%s' on %i streams\n", name, cmd, args->input.size()));
553 
554  for (int i=0; i<args->input.size() && !error; i++) {
555  char *result = args->get_callEnv().interpret_subcommand(args->input.get(i), cmd);
556  if (!result) error = GB_await_error();
557  else PASS_2_OUT(args, result);
558  }
559  }
560  return error;
561 }
562 
564  EXPECT_NO_PARAM(args);
565 
566  FORMAT_2_OUT(args, "%i", args->input.size());
567  return NULp;
568 }
569 
571  if (GEN_is_genome_db(args->get_gb_main(), -1)) return NULp;
572  return GBS_global_string("ACI command '%s' can only be used in genome databases.", args->get_cmdName());
573 }
574 
575 static GB_ERROR apply_to_origin(GBL_command_arguments *args, bool organism) {
576  EXPECT_PARAMS(args, 1, "\"ACI command\"");
578 
580  if (!error) {
582  error = GBS_global_string("'%s' applies to gene-species only", args->get_cmdName());
583  }
584  else {
585  GBDATA *gb_origin = NULp;
586  if (organism) {
587  gb_origin = GEN_find_origin_organism(args->get_item_ref(), NULp);
588  }
589  else {
590  gb_origin = GEN_find_origin_gene(args->get_item_ref(), NULp);
591  }
592 
593  if (!error && !gb_origin) error = GB_await_error();
594 
595  if (!error) {
596  char *command = unEscapeString(args->get_param(0));
597  GBL_call_env callEnv(gb_origin, args->get_env()); // refer to gb_origin for subcommands
598  // Note: if calling env has a FieldTracker, field access from 'command' is not tracked.
599  // That access applies to different item.
600 
601  for (int i=0; i<args->input.size() && !error; i++) {
602  char *result = callEnv.interpret_subcommand(args->input.get(i), command);
603  if (!result) error = GB_await_error();
604  else PASS_2_OUT(args, result);
605  }
606 
607  free(command);
608  }
609  }
610  }
611  return error;
612 }
613 
614 static GB_ERROR gbl_origin_gene(GBL_command_arguments *args) { return apply_to_origin(args, false); }
616 
617 
618 static GB_ERROR applyToItemFoundByKey(GBL_command_arguments *args, const char *itemname, GBDATA *gb_item_data, const char *key) {
619  GB_ERROR error = NULp;
620  char *command = unEscapeString(args->get_param(0));
621 
622  for (int i=0; i<args->input.size() && !error; i++) {
623  const char *in = args->input.get(i);
624  if (in[0]) { // silently ignore empty input streams
625  GBDATA *gb_item = NULp;
626  {
627  GBDATA *gb_field = GB_find_string(gb_item_data, key, in, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
628  if (gb_field) {
629  gb_item = GB_get_father(gb_field);
630  }
631  else {
632  error = GBS_global_string("No %s with %s '%s' found.", itemname, key, in);
633  }
634  }
635  if (gb_item) {
636  GBL_call_env callEnv(gb_item, args->get_env()); // refer to gb_item for subcommands
637  // Note: if calling env has a FieldTracker, field access from 'command' is not tracked.
638  // That access applies to different item.
639 
640  char *result = callEnv.interpret_subcommand("", command);
641  if (!result) error = GB_await_error();
642  else PASS_2_OUT(args, result);
643  }
644  else {
645  if (!error) error = GB_await_error();
646  }
647  }
648  }
649 
650  free(command);
651  return error;
652 }
654  EXPECT_PARAMS(args, 1, "\"ACI command\"");
655  return applyToItemFoundByKey(args, "species", GBT_get_species_data(args->get_gb_main()), "name");
656 }
658  EXPECT_PARAMS(args, 1, "\"ACI command\"");
659  return applyToItemFoundByKey(args, "species", GBT_get_species_data(args->get_gb_main()), "acc");
660 }
661 
663  EXPECT_PARAMS(args, 1, "\"ACI command\"");
665 
667  if (!error) {
668  GBDATA *gb_item = args->get_item_ref();
669  if (GEN_is_organism(gb_item)) {
670  error = applyToItemFoundByKey(args, "gene", GEN_find_gene_data(gb_item), "name");
671  }
672  else if (strcmp(GB_read_key_pntr(gb_item), "gene") == 0) {
673  // if applied to gene -> find "brother" of gene
674  GBDATA *gb_organism = GB_get_grandfather(gb_item);
675  if (GEN_is_organism(gb_organism)) {
676  error = applyToItemFoundByKey(args, "gene", GEN_find_gene_data(gb_organism), "name");
677  }
678  else {
679  error = "'findgene' cannot be used here (was applied to 'gene', but could not find gene-owning organism)";
680  }
681  }
682  else {
683  error = GBS_global_string("'findgene' cannot be applied to '%s' (need an organism)",
684  GBT_get_name_or_description(gb_item));
685  }
686  }
687  return error;
688 }
689 
690 class Tab {
691  bool tab[256];
692 public:
693  Tab(bool take, const char *invert) {
694  bool init = !take;
695  for (int i = 0; i<256; ++i) tab[i] = init;
696  for (int i = 0; invert[i]; ++i) tab[safeCharIndex(invert[i])] = take;
697  }
698  bool operator[](int i) const { return tab[i]; }
699 };
700 
702  for (int i=0; i<args->input.size(); ++i) {
703  long sum = 0; // count frequencies
704  const char *p = args->input.get(i);
705 
706  while (*p) sum += tab[safeCharIndex(*(p++))];
707  FORMAT_2_OUT(args, "%li", sum);
708  }
709  return NULp;
710 }
712  for (int i=0; i<args->input.size(); ++i) {
713  GBS_strstruct *strstruct = GBS_stropen(1000);
714  for (const char *p = args->input.get(i); *p; p++) {
715  if (!tab[(unsigned int)*p]) {
716  GBS_chrcat(strstruct, *p);
717  }
718  }
719  PASS_2_OUT(args, GBS_strclose(strstruct));
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  for (int i=0; i<args->input.size(); i++) {
838  GBS_strstruct *strstruct = GBS_stropen(1000);
839  for (const char *p = args->input.get(i); *p; p++) {
840  GBS_chrcat(strstruct, tab[(unsigned char)*p]);
841  }
842  PASS_2_OUT(args, GBS_strclose(strstruct));
843  }
844  return NULp;
845 }
846 
847 
849  ACCEPT_ANY_PARAMS(args);
851  for (int i=0; i<args->param_count(); i++) PARAM_2_OUT(args, i);
852  return NULp;
853 }
854 
856  EXPECT_NO_PARAM(args);
857  return gbl_mid_streams(args->input, args->output, 0, -1); // copy all streams
858 }
859 
860 enum Case { UPPER, LOWER, CAPS };
861 
863  EXPECT_NO_PARAM(args);
864 
865  for (int i=0; i<args->input.size(); i++) {
866  char *p = ARB_strdup(args->input.get(i));
867  bool last_was_alnum = false;
868 
869  for (char *pp = p; pp[0]; ++pp) {
870  switch (convTo) {
871  case LOWER: pp[0] = tolower(pp[0]); break;
872  case UPPER: pp[0] = toupper(pp[0]); break;
873  case CAPS: {
874  bool alnum = isalnum(pp[0]);
875  if (alnum) pp[0] = (last_was_alnum ? tolower : toupper)(pp[0]);
876  last_was_alnum = alnum;
877  break;
878  }
879  default: gb_assert(0); break;
880  }
881  }
882 
883  PASS_2_OUT(args, p);
884  }
885 
886  return NULp;
887 }
888 
889 static GB_ERROR gbl_caps (GBL_command_arguments *args) { return convert_case(args, CAPS); }
892 
894  EXPECT_PARAMS(args, 1, "length_of_head");
895  int start = atoi(args->get_param(0));
896  if (start <= 0) return gbl_mid_streams(args->input, args->output, 1, 0); // empty all streams
897  return gbl_mid_streams(args->input, args->output, 0, start-1);
898 }
900  EXPECT_PARAMS(args, 1, "length_of_tail");
901  int end = atoi(args->get_param(0));
902  if (end <= 0) return gbl_mid_streams(args->input, args->output, 1, 0); // empty all streams
903  return gbl_mid_streams(args->input, args->output, -end, -1);
904 }
905 
906 inline GB_ERROR mid(GBL_command_arguments *args, int start_index) {
907  EXPECT_PARAMS(args, 2, "start,end");
908  return gbl_mid_streams(args->input, args->output, atoi(args->get_param(0))-start_index, atoi(args->get_param(1))-start_index);
909 }
910 static GB_ERROR gbl_mid0(GBL_command_arguments *args) { return mid(args, 0); }
911 static GB_ERROR gbl_mid (GBL_command_arguments *args) { return mid(args, 1); }
912 
913 static GB_ERROR tab(GBL_command_arguments *args, bool pretab) {
914  EXPECT_PARAMS(args, 1, "tabstop");
915 
916  int tab = atoi(args->get_param(0));
917  for (int i=0; i<args->input.size(); i++) {
918  int len = strlen(args->input.get(i));
919  if (len >= tab) IN_2_OUT(args, i);
920  else {
921  char *p = ARB_alloc<char>(tab+1);
922  if (pretab) {
923  int spaces = tab-len;
924  for (int j = 0; j<spaces; ++j) p[j] = ' ';
925  strcpy(p+spaces, args->input.get(i));
926  }
927  else {
928  strcpy(p, args->input.get(i));
929  for (int j=len; j<tab; j++) p[j] = ' ';
930  p[tab] = 0;
931  }
932  PASS_2_OUT(args, p);
933  }
934  }
935  return NULp;
936 }
937 static GB_ERROR gbl_tab (GBL_command_arguments *args) { return tab(args, false); }
938 static GB_ERROR gbl_pretab(GBL_command_arguments *args) { return tab(args, true); }
939 
941  EXPECT_PARAMS(args, 1, "\"chars_to_crop\"");
942 
943  const char *chars_to_crop = args->get_param(0);
944  for (int i=0; i<args->input.size(); i++) {
945  const char *s = args->input.get(i);
946  while (s[0] && strchr(chars_to_crop, s[0])) s++; // crop at beg of line
947 
948  int len = strlen(s);
949  char *p = ARB_alloc<char>(len+1);
950  strcpy(p, s);
951 
952  {
953  char *pe = p+len-1;
954 
955  while (pe >= p && strchr(chars_to_crop, pe[0])) { // crop at end of line
956  --pe;
957  }
958  gb_assert(pe >= (p-1));
959  pe[1] = 0;
960  }
961  PASS_2_OUT(args, p);
962  }
963  return NULp;
964 }
965 
966 
967 
969  EXPECT_PARAMS_PASSED(args, "streamnumber[,streamnumber]+");
970 
971  for (int i=0; i<args->param_count(); i++) {
972  int stream = atoi(args->get_param(i));
973  EXPECT_LEGAL_STREAM_INDEX(args, stream);
974  IN_2_OUT(args, bio2info(stream));
975  }
976  return NULp;
977 }
979  EXPECT_PARAMS_PASSED(args, "streamnumber[,streamnumber]+");
980 
981  GB_ERROR error = NULp;
982  bool *dropped = ARB_alloc<bool>(args->input.size());
983 
984  for (int i=0; i<args->input.size(); ++i) dropped[i] = false;
985 
986  for (int i=0; i<args->param_count() && !error; ++i) {
987  int stream = atoi(args->get_param(i));
988  error = check_valid_stream_index(args, stream);
989  if (!error) dropped[bio2info(stream)] = true;
990  }
991 
992  if (!error) {
993  for (int i=0; i<args->input.size(); ++i) {
994  if (!dropped[i]) IN_2_OUT(args, i);
995  }
996  }
997  free(dropped);
998 
999  return error;
1000 }
1001 
1003  EXPECT_NO_PARAM(args);
1004 
1005  for (int i=0; i<args->input.size(); ++i) {
1006  if (args->input.get(i)[0]) { // if non-empty
1007  IN_2_OUT(args, i);
1008  }
1009  }
1010  return NULp;
1011 }
1012 
1014  EXPECT_NO_PARAM(args);
1015 
1016  for (int i=0; i<args->input.size(); ++i) {
1017  if (atoi(args->input.get(i))) { // if non-zero
1018  IN_2_OUT(args, i);
1019  }
1020  }
1021  return NULp;
1022 }
1023 
1025  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 2, "streamnumber,streamnumber");
1026 
1027  if (args->input.size()<2) return "need at least two input streams";
1028 
1029  int swap1;
1030  int swap2;
1031  if (args->param_count() == 0) {
1032  swap1 = args->input.size()-1;
1033  swap2 = args->input.size()-2;
1034  }
1035  else {
1036  gb_assert(args->param_count() == 2);
1037 
1038  swap1 = atoi(args->get_param(0));
1039  swap2 = atoi(args->get_param(1));
1040 
1041  EXPECT_LEGAL_STREAM_INDEX(args, swap1);
1042  EXPECT_LEGAL_STREAM_INDEX(args, swap2);
1043 
1044  swap1 = bio2info(swap1);
1045  swap2 = bio2info(swap2);
1046  }
1047 
1048  for (int i = 0; i<args->input.size(); ++i) {
1049  int j = i == swap1 ? swap2 : (i == swap2 ? swap1 : i);
1050  IN_2_OUT(args, j);
1051  }
1052 
1053  return NULp;
1054 }
1055 
1057  EXPECT_PARAMS(args, 1, "streamnumber");
1058  if (args->input.size()<1) return "need at least one input stream";
1059 
1060  int stream_to_move = atoi(args->get_param(0));
1061  EXPECT_LEGAL_STREAM_INDEX(args, stream_to_move);
1062  stream_to_move = bio2info(stream_to_move);
1063 
1064  if (!toback) IN_2_OUT(args, stream_to_move);
1065  for (int i = 0; i<args->input.size(); ++i) {
1066  if (i != stream_to_move) IN_2_OUT(args, i);
1067  }
1068  if (toback) IN_2_OUT(args, stream_to_move);
1069 
1070  return NULp;
1071 }
1072 static GB_ERROR gbl_toback (GBL_command_arguments *args) { return backfront_stream(args, 1); }
1074 
1076  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 1, "\"separator\"");
1077  const char *separator = args->get_optional_param(0, NULp);
1078 
1079  if (args->input.size()) {
1080  GBS_strstruct *str = GBS_stropen(1000);
1081  GBS_strcat(str, args->input.get(0));
1082 
1083  for (int i = 1; i<args->input.size(); ++i) {
1084  if (separator) GBS_strcat(str, separator);
1085  GBS_strcat(str, args->input.get(i));
1086  }
1087 
1088  PASS_2_OUT(args, GBS_strclose(str));
1089  }
1090  return NULp;
1091 }
1092 
1094  EXPECT_OPTIONAL_PARAMS_CUSTOM(args, 0, NULp, 2, "\"separator\"[,mode]", true, false);
1095 
1096  const char *separator = args->get_optional_param(0, "\n");
1097  int split_mode = atoi(args->get_optional_param(1, "0")); // 0: remove separator, 1: split before separator, 2: split behind separator
1098 
1099  if (!separator[0]) {
1100  // e.g. happens if trying to specify character ';' or ','
1101  return "Invalid separator (cannot be empty; please try to quote the parameter)";
1102  }
1103 
1104  if (split_mode<0 || split_mode>2) return GBS_global_string("Illegal split mode '%i' (valid: 0..2)", split_mode);
1105 
1106  {
1107  size_t sepLen = strlen(separator);
1108 
1109  for (int i = 0; i<args->input.size(); ++i) {
1110  const char *in = args->input.get(i);
1111  const char *from = in; // search from here
1112 
1113  while (in) {
1114  const char *splitAt = strstr(from, separator);
1115  if (splitAt) {
1116  size_t len;
1117  char *copy;
1118 
1119  if (split_mode == 2) splitAt += sepLen; // split behind separator
1120 
1121  len = splitAt-in;
1122  copy = ARB_strndup(in, len);
1123 
1124  PASS_2_OUT(args, copy);
1125 
1126  in = splitAt + (split_mode == 0 ? sepLen : 0);
1127  from = in+(split_mode == 1 ? sepLen : 0);
1128  }
1129  else {
1130  COPY_2_OUT(args, in); // last part
1131  in = NULp;
1132  }
1133  }
1134  }
1135  }
1136 
1137  return NULp;
1138 }
1139 
1141  EXPECT_OPTIONAL_PARAMS(args, 0, NULp, 1, "width");
1142 
1143  int width = atoi(args->get_optional_param(0, "1"));
1144  if (width<1) return "Invalid width";
1145 
1146  for (int i = 0; i<args->input.size(); ++i) {
1147  const char *in = args->input.get(i);
1148  int len = strlen(in);
1149 
1150  while (len>0) {
1151  char *part = ARB_strpartdup(in, in+width-1);
1152  PASS_2_OUT(args, part);
1153 
1154  in += width;
1155  len -= width;
1156  }
1157  }
1158 
1159  return NULp;
1160 }
1161 // ----------------------------------
1162 // Extended string functions
1163 
1164 static char *do_extract_words(const char *source, const char *chars, float minlen, bool sort_output) {
1165  /* extract all words in a text that:
1166  * if minlen < 1.0 -> contain more than minlen*len_of_text characters that also exists in chars
1167  * if minlen > 1.0 -> contain more than minlen characters that also exists in chars
1168  */
1169 
1170  char *s = ARB_strdup(source);
1171  char **ps = ARB_calloc<char*>((strlen(source)>>1) + 1);
1172  GBS_strstruct *strstruct = GBS_stropen(1000);
1173  char *f = s;
1174  int count = 0;
1175  char *p; // @@@ fix locals
1176  char *h;
1177  int cnt;
1178  int len;
1179  int iminlen = (int) (minlen+.5);
1180 
1181  while ((p = strtok(f, " \t,;:|"))) {
1182  f = NULp;
1183  cnt = 0;
1184  len = strlen(p);
1185  for (h=p; *h; h++) {
1186  if (strchr(chars, *h)) cnt++;
1187  }
1188 
1189  if (minlen == 1.0) {
1190  if (cnt != len) continue;
1191  }
1192  else if (minlen > 1.0) {
1193  if (cnt < iminlen) continue;
1194  }
1195  else {
1196  if (len < 3 || cnt < minlen*len) continue;
1197  }
1198  ps[count] = p;
1199  count ++;
1200  }
1201  if (sort_output) {
1202  GB_sort((void **)ps, 0, count, GB_string_comparator, NULp);
1203  }
1204  for (cnt = 0; cnt<count; cnt++) {
1205  if (cnt) {
1206  GBS_chrcat(strstruct, ' ');
1207  }
1208  GBS_strcat(strstruct, ps[cnt]);
1209  }
1210 
1211  free(ps);
1212  free(s);
1213  return GBS_strclose(strstruct);
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 *strstr = GBS_stropen(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  GBS_strcat(strstr, val);
1457  free(val);
1458  }
1459  }
1460  PASS_2_OUT(args, GBS_strclose(strstr));
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 
1546  hash_entry = GBS_global_string_copy(">%0*x%s%s",
1547  GROUP_COUNT_CHARS, *group_counter,
1548  keelTarget ? "!" : "",
1549  node->name);
1550  GBS_write_hash(tax_hash, hash_entry, (long)ARB_strdup(parent_group));
1551 
1552  hash_binary_entry = GBS_global_string(">>%p", node->gb_node);
1553  GBS_write_hash(tax_hash, hash_binary_entry, (long)ARB_strdup(hash_entry));
1554 
1555  if (keelTarget) { // keeled group (projected to son)
1556  if (keelTarget->is_leftson()) {
1557  build_taxonomy_rek(node->get_leftson(), tax_hash, hash_entry, group_counter); // pass down hash_entry only to keelTarget
1558  build_taxonomy_rek(node->get_rightson(), tax_hash, parent_group, group_counter);
1559  }
1560  else {
1561  build_taxonomy_rek(node->get_leftson(), tax_hash, parent_group, group_counter);
1562  build_taxonomy_rek(node->get_rightson(), tax_hash, hash_entry, group_counter);
1563  }
1564  }
1565  else { // normal group
1566  build_taxonomy_rek(node->get_leftson(), tax_hash, hash_entry, group_counter); // pass down hash_entry to both sons
1567  build_taxonomy_rek(node->get_rightson(), tax_hash, hash_entry, group_counter);
1568  }
1569 
1570  free(hash_entry);
1571  }
1572  else {
1573  build_taxonomy_rek(node->get_leftson(), tax_hash, parent_group, group_counter);
1574  build_taxonomy_rek(node->get_rightson(), tax_hash, parent_group, group_counter);
1575  }
1576  }
1577 }
1578 
1580 
1581 static bool is_cached_taxonomy(const char */*key*/, long val, void *cl_ct) {
1582  cached_taxonomy *ct1 = (cached_taxonomy *)val;
1583  cached_taxonomy *ct2 = (cached_taxonomy *)cl_ct;
1584 
1585  return ct1 == ct2;
1586 }
1587 
1588 static const char *tree_of_cached_taxonomy(cached_taxonomy *ct) {
1589  /* search the hash to find the correct cached taxonomy.
1590  * searching for tree name does not work, because the tree possibly already was deleted
1591  */
1592  const char *tree = GBS_hash_next_element_that(cached_taxonomies, NULp, is_cached_taxonomy, ct);
1593 #ifdef DUMP_TAXONOMY_CACHING
1594  if (tree) printf("tree_of_cached_taxonomy: tree='%s' ct->tree_name='%s'\n", tree, ct->tree_name);
1595 #endif // DUMP_TAXONOMY_CACHING
1596  return tree;
1597 }
1598 
1599 static void flush_taxonomy_cb(GBDATA *gbd, cached_taxonomy *ct) {
1600  /* this cb is bound all tree db members below "/tree_data/tree_xxx" which
1601  * may have an effect on the displayed taxonomy
1602  * it invalidates cached taxonomies for that tree (when changed or deleted)
1603  */
1604 
1605  GB_ERROR error = NULp;
1606  const char *found = tree_of_cached_taxonomy(ct);
1607 
1608  if (found) {
1609 #ifdef DUMP_TAXONOMY_CACHING
1610  fprintf(stderr, "Deleting cached taxonomy ct=%p (tree='%s')\n", ct, found);
1611 #endif // DUMP_TAXONOMY_CACHING
1612  GBS_write_hash(cached_taxonomies, found, 0); // delete cached taxonomy from hash
1614  }
1615 #ifdef DUMP_TAXONOMY_CACHING
1616  else {
1617  fprintf(stderr, "No tree found for cached_taxonomies ct=%p (already deleted?)\n", ct);
1618  }
1619 #endif // DUMP_TAXONOMY_CACHING
1620 
1621  if (!GB_inside_callback(gbd, GB_CB_DELETE)) {
1623  }
1624 
1625  if (found && !error) {
1627  if (gb_main) {
1628  GBDATA *gb_tree_refresh = GB_search(gb_main, AWAR_TREE_REFRESH, GB_INT);
1629  if (!gb_tree_refresh) {
1630  error = GBS_global_string("%s (while trying to force refresh)", GB_await_error());
1631  }
1632  else {
1633  GB_touch(gb_tree_refresh); // Note : force tree update
1634  }
1635  }
1636  }
1637 
1638  if (error) {
1639  fprintf(stderr, "Error in flush_taxonomy_cb: %s\n", error);
1640  }
1641 }
1642 
1644  // detects the creation of new groups and call flush_taxonomy_cb() manually
1645 #ifdef DUMP_TAXONOMY_CACHING
1646  fputs("flush_taxonomy_if_new_group_cb() has been called\n", stderr);
1647 #endif // DUMP_TAXONOMY_CACHING
1648 
1649  const char *tree_name = tree_of_cached_taxonomy(ct);
1650  if (tree_name) {
1651  int groups = 0;
1652  GBDATA *gb_group_node;
1653 
1654  for (gb_group_node = GB_entry(gb_tree, "node");
1655  gb_group_node;
1656  gb_group_node = GB_nextEntry(gb_group_node))
1657  {
1658  if (GB_entry(gb_group_node, "group_name")) {
1659  groups++; // count named groups only
1660  }
1661  }
1662 
1663 #ifdef DUMP_TAXONOMY_CACHING
1664  fprintf(stderr, "cached_groups=%i counted_groups=%i\n", ct->groups, groups);
1665 #endif // DUMP_TAXONOMY_CACHING
1666  if (groups != ct->groups) {
1667 #ifdef DUMP_TAXONOMY_CACHING
1668  fprintf(stderr, "Number of groups changed -> invoking flush_taxonomy_cb() manually\n");
1669 #endif // DUMP_TAXONOMY_CACHING
1670  flush_taxonomy_cb(gb_tree, ct);
1671  }
1672  }
1673 #ifdef DUMP_TAXONOMY_CACHING
1674  else {
1675  fprintf(stderr, "cached taxonomy no longer valid.\n");
1676  }
1677 #endif // DUMP_TAXONOMY_CACHING
1678 }
1679 
1680 static cached_taxonomy *get_cached_taxonomy(GBDATA *gb_main, const char *tree_name, GB_ERROR *error) {
1681  long cached;
1682  *error = NULp;
1683  if (!cached_taxonomies) {
1684  cached_taxonomies = GBS_create_hash(20, GB_IGNORE_CASE);
1685  }
1686  cached = GBS_read_hash(cached_taxonomies, tree_name);
1687  if (!cached) {
1688  TreeNode *tree = GBT_read_tree(gb_main, tree_name, new SimpleRoot);
1689  if (!tree) *error = GB_await_error();
1690  else *error = GBT_link_tree(tree, gb_main, false, NULp, NULp);
1691 
1692  if (!*error) {
1693  GBDATA *gb_tree = GBT_find_tree(gb_main, tree_name);
1694  if (!gb_tree) {
1695  *error = GBS_global_string("Can't find tree '%s'", tree_name);
1696  }
1697  else {
1698  cached_taxonomy *ct = ARB_alloc<cached_taxonomy>(1);
1699  long nodes = GBT_count_leafs(tree);
1700  int group_counter = 0;
1701 
1702  ct->tree_name = ARB_strdup(tree_name);
1704  ct->groups = 0; // counted below
1705 
1706  build_taxonomy_rek(tree, ct->taxonomy, "<root>", &group_counter);
1707  cached = (long)ct;
1708  GBS_write_hash(cached_taxonomies, tree_name, (long)ct);
1709 
1711  GB_add_callback(gb_tree, GB_CB_SON_CREATED, makeDatabaseCallback(flush_taxonomy_if_new_group_cb, ct));
1712 
1713  {
1714  GBDATA *gb_tree_entry = GB_entry(gb_tree, "tree");
1715  GBDATA *gb_group_node;
1716 
1717  if (gb_tree_entry) {
1719  GB_add_callback(gb_tree_entry, GB_CB_CHANGED_OR_DELETED, makeDatabaseCallback(flush_taxonomy_cb, ct));
1720  }
1721 
1722  // add callbacks for all node/group_name subentries
1723  for (gb_group_node = GB_entry(gb_tree, "node");
1724  gb_group_node;
1725  gb_group_node = GB_nextEntry(gb_group_node))
1726  {
1727  GBDATA *gb_group_name = GB_entry(gb_group_node, "group_name");
1728  if (gb_group_name) { // group with id = 0 has no name
1730  GB_add_callback(gb_group_name, GB_CB_CHANGED_OR_DELETED, makeDatabaseCallback(flush_taxonomy_cb, ct));
1731  ct->groups++;
1732  }
1733  }
1734  }
1735 #ifdef DUMP_TAXONOMY_CACHING
1736  fprintf(stderr, "Created taxonomy hash for '%s' (ct=%p)\n", tree_name, ct);
1737 #endif // DUMP_TAXONOMY_CACHING
1738  }
1739  }
1740 
1741  destroy(tree);
1742  }
1743 
1744  if (!*error) {
1745  cached_taxonomy *ct = (cached_taxonomy*)cached;
1746  gb_assert(ct);
1747  return ct;
1748  }
1749 
1750  return NULp;
1751 }
1752 
1753 static char *get_taxonomy_string(GB_HASH *tax_hash, const char *group_key, int depth, GB_ERROR *error) {
1754  long found;
1755  char *result = NULp;
1756 
1757  gb_assert(depth>0);
1758  gb_assert(!(group_key[0] == '>' && group_key[1] == '>')); // internal group-pointers not allowed here!
1759 
1760  found = GBS_read_hash(tax_hash, group_key);
1761  if (found) {
1762  const char *parent_group_key = (const char *)found;
1763  if (strcmp(parent_group_key, "<root>") == 0) { // root reached
1764  result = ARB_strdup(group_key+(GROUP_COUNT_CHARS+1)); // return own group name
1765  }
1766  else {
1767  if (depth>1) {
1768  char *parent_name = get_taxonomy_string(tax_hash, parent_group_key, depth-1, error);
1769  if (parent_name) {
1770  result = GBS_global_string_copy("%s/%s", parent_name, group_key+(GROUP_COUNT_CHARS+1));
1771  free(parent_name);
1772  }
1773  else {
1774  *error = GBS_global_string("In get_taxonomy_string(%s): %s", group_key, *error);
1775  result = NULp;
1776  }
1777  }
1778  else {
1779  result = ARB_strdup(group_key+(GROUP_COUNT_CHARS+1)); // return own group name
1780  }
1781  }
1782  }
1783  else {
1784  *error = GBS_global_string("Not in tax_hash: '%s'", group_key);
1785  }
1786  return result;
1787 }
1788 
1789 static const char *get_taxonomy(GBDATA *gb_species_or_group, const char *tree_name, bool is_current_tree, int depth, GB_ERROR *error) {
1790  GBDATA *gb_main = GB_get_root(gb_species_or_group);
1791  cached_taxonomy *tax = get_cached_taxonomy(gb_main, tree_name, error);
1792  const char *result = NULp;
1793 
1794  if (tax) {
1795  GBDATA *gb_name = GB_entry(gb_species_or_group, "name");
1796  GBDATA *gb_group_name = GB_entry(gb_species_or_group, "group_name");
1797 
1798  if (gb_name && !gb_group_name) { // it's a species
1799  char *name = GB_read_string(gb_name);
1800  if (name) {
1801  GB_HASH *tax_hash = tax->taxonomy;
1802  long found = GBS_read_hash(tax_hash, GBS_global_string("!%s", name));
1803 
1804  if (found) {
1805  const char *parent_group = (const char *)found;
1806 
1807  if (strcmp(parent_group, "<root>") == 0) {
1808  result = ""; // not member of any group
1809  }
1810  else {
1811  static char *parent = NULp;
1812 
1813  freeset(parent, get_taxonomy_string(tax_hash, parent_group, depth, error));
1814  result = parent;
1815  }
1816  }
1817  else {
1818  result = GBS_global_string("Species '%s' not in '%s'", name, tree_name);
1819  }
1820  free(name);
1821  }
1822  else {
1823  *error = GBS_global_string("Species without 'name' entry!");
1824  }
1825  }
1826  else if (gb_group_name && !gb_name) { // it's a group
1827  char *group_name = GB_read_string(gb_group_name);
1828  if (group_name) {
1829  if (is_current_tree) {
1830  GB_HASH *tax_hash = tax->taxonomy;
1831  long found = GBS_read_hash(tax_hash, GBS_global_string(">>%p", gb_species_or_group));
1832 
1833  if (found) {
1834  static char *full_group = NULp;
1835  const char *group_id = (const char *)found;
1836 
1837  freeset(full_group, get_taxonomy_string(tax_hash, group_id, depth, error));
1838  result = full_group;
1839  }
1840  else {
1841  result = GBS_global_string("Group '%s' not in '%s'", group_name, tree_name);
1842  }
1843  }
1844  else {
1845  *error = "It's not possible to specify the tree name in taxonomy() for groups";
1846  }
1847  free(group_name);
1848  }
1849  else {
1850  *error = "Group without 'group_name' entry";
1851  }
1852  }
1853  else if (gb_group_name) {
1854  *error = "Container has 'name' and 'group_name' entry - can't detect container type";
1855  }
1856  else {
1857  *error = "Container has neither 'name' nor 'group_name' entry - can't detect container type";
1858  }
1859  }
1860 
1861  return result;
1862 }
1863 
1865  GB_ERROR error = check_optional_parameters(args, 1, "count", 1, "tree_name", false, true);
1866  if (!error) {
1867  EXPECT_ITEM_REFERENCED(args);
1869 
1870  char *tree_name = NULp;
1871  bool is_current_tree = false;
1872  int depth = -1;
1873  char *result = NULp;
1874 
1875  if (args->param_count() == 1) { // only 'depth'
1876  if (!args->get_treename()) {
1877  result = ARB_strdup("No default tree");
1878  }
1879  else {
1880  tree_name = ARB_strdup(args->get_treename());
1881  depth = atoi(args->get_param(0));
1882  is_current_tree = true;
1883  }
1884  }
1885  else { // 'tree_name', 'depth'
1886  tree_name = ARB_strdup(args->get_param(0));
1887  depth = atoi(args->get_param(1));
1888  }
1889 
1890  if (!result) {
1891  if (depth<1) {
1892  error = GBS_global_string("Illegal depth '%i' (allowed 1..n)", depth);
1893  }
1894  if (!error) {
1895  const char *taxonomy_string = get_taxonomy(args->get_item_ref(), tree_name, is_current_tree, depth, &error);
1896  if (taxonomy_string) result = ARB_strdup(taxonomy_string);
1897  }
1898  }
1899 
1900  gb_assert(contradicted(result, error));
1901  if (result) PASS_2_OUT(args, result);
1902  free(tree_name);
1903  }
1904  return error;
1905 }
1906 
1908  EXPECT_ITEM_REFERENCED(args);
1910 
1912  if (!error) {
1913  switch (identify_gb_item(args->get_item_ref())) {
1914  case GBT_ITEM_UNKNOWN: {
1915  error = "'sequence' used for unknown item";
1916  break;
1917  }
1918  case GBT_ITEM_SPECIES: {
1919  char *use = GBT_get_default_alignment(args->get_gb_main());
1920 
1921  if (!use) {
1922  error = GB_have_error() ? GB_await_error() : "no default alignment defined";
1923  }
1924  else {
1925  GBDATA *gb_seq = GBT_find_sequence(args->get_item_ref(), use);
1926 
1927  if (gb_seq) PASS_2_OUT(args, GB_read_string(gb_seq));
1928  else COPY_2_OUT(args, ""); // if current alignment does not exist -> return empty string
1929 
1930  free(use);
1931  }
1932  break;
1933  }
1934  case GBT_ITEM_GENE: {
1935  char *seq = GBT_read_gene_sequence(args->get_item_ref(), true, 0);
1936 
1937  if (!seq) error = GB_await_error();
1938  else PASS_2_OUT(args, seq);
1939 
1940  break;
1941  }
1942  }
1943  }
1944  return error;
1945 }
1946 
1948  EXPECT_ITEM_REFERENCED(args);
1950 
1952  if (!error) {
1953  switch (identify_gb_item(args->get_item_ref())) {
1954  case GBT_ITEM_UNKNOWN: {
1955  error = "'export_sequence' used for unknown item";
1956  break;
1957  }
1958  case GBT_ITEM_SPECIES: {
1959  if (!get_export_sequence) {
1960  error = "No export-sequence-hook defined (can't use 'export_sequence' here)";
1961  }
1962  else {
1963  size_t len;
1964  const char *seq = get_export_sequence(args->get_item_ref(), &len, &error);
1965 
1966  gb_assert(error || seq);
1967 
1968  if (seq) PASS_2_OUT(args, ARB_strduplen(seq, len));
1969  }
1970  break;
1971  }
1972  case GBT_ITEM_GENE: {
1973  error = "'export_sequence' cannot be used for gene";
1974  break;
1975  }
1976  }
1977  }
1978  return error;
1979 }
1980 
1983 
1985  if (!error) {
1986  GBDATA *gb_main = args->get_gb_main();
1987  char *use = GBT_get_default_alignment(gb_main);
1988  PASS_2_OUT(args, use);
1989  }
1990  return error;
1991 }
1992 
1995 
1997  if (!error) {
1998  GBDATA *gb_main = args->get_gb_main();
1999  char *use = GBT_get_default_alignment(gb_main);
2000  PASS_2_OUT(args, GBT_get_alignment_type_string(gb_main, use));
2001  free(use);
2002  }
2003 
2004  return error;
2005 }
2006 
2007 static GB_ERROR format(GBL_command_arguments *args, bool simple_format) {
2008  // simple_format: true = "format", false="format_sequence"
2009 
2010  GB_ERROR error = NULp;
2011  int ic;
2012 
2014  GBL_PARAM_INT(firsttab, "firsttab=", 10, "Indent first line");
2015  GBL_PARAM_INT(tab, "tab=", 10, "Indent not first line");
2016  GBL_PARAM_INT(width, "width=", 50, "Sequence width (bases only)");
2017 
2018  // "format_sequence"-only
2019  GBL_PARAM_BIT (numleft, PARAM_IF(!simple_format, "numleft"), 0, "Numbers left of sequence");
2020  GBL_PARAM_INT (numright, PARAM_IF(!simple_format, "numright="), 0, "Numbers right of sequence (specifies width; -1 -> auto-width)");
2021  GBL_PARAM_UINT(gap, PARAM_IF(!simple_format, "gap="), 10, "Insert ' ' every n sequence characters");
2022 
2023  // "format"-only
2024  GBL_PARAM_STRING(nl, PARAM_IF(simple_format, "nl="), " ", "Break line at characters 'str' if wrapping needed");
2025  GBL_PARAM_STRING(forcenl, PARAM_IF(simple_format, "forcenl="), "\n", "Always break line at characters 'str'");
2026 
2027  GBL_TRACE_PARAMS(args);
2029 
2030  if (tab < 0) tab = 0;
2031  if (firsttab < 0) firsttab = 0;
2032 
2033  if (width == 0) return "Illegal zero width";
2034  if (numleft && numright != 0) return "You may only specify 'numleft' OR 'numright', not both.";
2035 
2036  if (gap<1) gap = UINT_MAX;
2037 
2038  for (ic = 0; ic<args->input.size(); ++ic) {
2039  const char *src = args->input.get(ic);
2040  size_t data_size = strlen(src);
2041  size_t needed_size;
2042  size_t line_size;
2043  int numright_used = numright;
2044 
2045  if (numright_used<0) {
2046  numright_used = calc_digits(data_size);
2047  }
2048 
2049  {
2050  size_t lines;
2051 
2052  if (simple_format) {
2053  lines = data_size/2 + 1; // worst case
2054  line_size = tab + (width>0 ? width : data_size) + 1;
2055  }
2056  else {
2057  size_t gapsPerLine = (width-1)/gap;
2058  lines = data_size/width+1;
2059  line_size = tab + width + gapsPerLine + 1;
2060 
2061  if (numright_used) {
2062  // add space for numright
2063  line_size += numright_used+1; // plus space
2064  }
2065  }
2066 
2067  needed_size = lines*line_size + firsttab + 1 + 10;
2068  }
2069 
2070  char *result = ARB_alloc<char>(needed_size);
2071  if (!result) {
2072  error = GBS_global_string("Out of memory (tried to alloc %zu bytes)", needed_size);
2073  }
2074  else {
2075  char *dst = result;
2076  size_t rest_data = data_size;
2077 
2078  if (simple_format) {
2079  /* format string w/o gaps or numleft
2080  * does word-wrapping at chars in nl
2081  */
2082 
2083  // build wrap table
2084  unsigned char isWrapChar[256];
2085  memset(isWrapChar, 0, sizeof(isWrapChar));
2086  for (int i = 0; nl[i]; ++i) isWrapChar[(unsigned char)nl[i]] = 1;
2087  for (int i = 0; forcenl[i]; ++i) isWrapChar[(unsigned char)forcenl[i]] = 2;
2088 
2089  if (firsttab>0) {
2090  memset(dst, ' ', firsttab);
2091  dst += firsttab;
2092  }
2093 
2094  while (width>0 && rest_data>unsigned(width)) {
2095  int take;
2096  int move;
2097  int took;
2098 
2099  for (take = width; take > 0; --take) {
2100  if (isWrapChar[(unsigned char)src[take]]) break;
2101  }
2102  if (take <= 0) { // no wrap character found -> hard wrap at width
2103  take = move = width;
2104  }
2105  else { // soft wrap at last found wrap character
2106  move = take+1;
2107  }
2108 
2109  for (took = 0; took<take; took++) {
2110  char c = src[took];
2111  if (isWrapChar[(unsigned char)c] == 2) { // forced newline
2112  take = took;
2113  move = take+1;
2114  break;
2115  }
2116  dst[took] = c;
2117  }
2118 
2119  dst += take;
2120  src += move;
2121  rest_data -= move;
2122 
2123  if (rest_data>0) {
2124  *dst++ = '\n';
2125  if (tab>0) {
2126  memset(dst, ' ', tab);
2127  dst += tab;
2128  }
2129  }
2130  }
2131 
2132  if (rest_data>0) {
2133  size_t j, k;
2134  for (j = 0, k = 0; j<rest_data; ++j) {
2135  char c = src[j];
2136 
2137  if (isWrapChar[(unsigned char)c] == 2) {
2138  dst[k++] = '\n';
2139  if (tab>0) {
2140  memset(dst+k, ' ', tab);
2141  k += tab;
2142  }
2143  }
2144  else {
2145  dst[k++] = c;
2146  }
2147  }
2148  src += j;
2149  dst += k;
2150  rest_data = 0;
2151  }
2152  }
2153  else {
2154  // "format_sequence" with gaps and numleft
2155  char *format = NULp;
2156  const char *src_start = src;
2157  const char *dst_linestart = dst;
2158 
2159  if (numleft) {
2160  /* Warning: Be very careful, when you change format strings here!
2161  * currently all format strings result in '%u' or '%-##u' (where # are digits)
2162  */
2163  if (firsttab>0) {
2164  char *firstFormat = GBS_global_string_copy("%%-%iu ", firsttab-1);
2165  dst += sprintf(dst, firstFormat, (unsigned)1);
2166  free(firstFormat);
2167  }
2168  else {
2169  dst += sprintf(dst, "%u ", (unsigned)1);
2170  }
2171  format = tab>0 ? GBS_global_string_copy("%%-%iu ", tab-1) : ARB_strdup("%u ");
2172  }
2173  else if (firsttab>0) {
2174  memset(dst, ' ', firsttab);
2175  dst += firsttab;
2176  }
2177 
2178  while (rest_data>0) {
2179  size_t take = (width>0 && rest_data>unsigned(width)) ? width : rest_data;
2180 
2181  rest_data -= take;
2182 
2183  while (take>gap) {
2184  memcpy(dst, src, gap);
2185  dst += gap;
2186  src += gap;
2187  *dst++ = ' ';
2188  take -= gap;
2189  }
2190 
2191  memcpy(dst, src, take);
2192  dst += take;
2193  src += take;
2194 
2195  if (numright_used) {
2196  if (rest_data) *dst++ = ' ';
2197  else {
2198  // fill in missing spaces for proper alignment of numright
2199  size_t currSize = dst-dst_linestart;
2200  size_t wantSize = line_size-numright_used-1;
2201  if (currSize<wantSize) {
2202  size_t spaces = wantSize-currSize;
2203  memset(dst, ' ', spaces);
2204  dst += spaces;
2205  }
2206  }
2207  unsigned int num = (src-src_start);
2208  dst += sprintf(dst, "%*u", numright_used, num);
2209  }
2210 
2211  if (rest_data>0) {
2212  *dst++ = '\n';
2213  dst_linestart = dst;
2214  if (numleft) {
2215  unsigned int num = (src-src_start)+1; // this goes to the '%u' (see comment above)
2216  dst += sprintf(dst, format, num);
2217  }
2218  else if (tab>0) {
2219  memset(dst, ' ', tab);
2220  dst += tab;
2221  }
2222  }
2223  }
2224 
2225  free(format);
2226  }
2227 
2228  *dst++ = 0; // close str
2229 
2230 #if defined(DEBUG)
2231  { // check for array overflow
2232  size_t used_size = dst-result;
2233  gb_assert(used_size <= needed_size);
2234  ARB_realloc(result, used_size);
2235  }
2236 #endif // DEBUG
2237  }
2238 
2239  if (!error) PASS_2_OUT(args, result);
2240  else free(result);
2241  }
2242  return error;
2243 }
2244 
2245 static GB_ERROR gbl_format (GBL_command_arguments *args) { return format(args, true); }
2246 static GB_ERROR gbl_format_sequence(GBL_command_arguments *args) { return format(args, false); }
2247 
2248 
2249 static char *gbl_read_seq_sai_or_species(GBDATA *gb_main, const char *species, const char *sai, const char *ali, size_t *seqLen) {
2250  /* Reads the alignment 'ali' of 'species' or 'sai'.
2251  * If 'ali' is NULp, use default alignment.
2252  * Returns NULp in case of error (which is exported then)
2253  */
2254 
2255  char *seq = NULp;
2256  GB_ERROR error = NULp;
2257 
2258  int sources = !!species + !!sai;
2259  if (sources != 1) {
2260  error = "Either parameters 'species' or 'SAI' must be specified";
2261  }
2262  else {
2263  GBDATA *gb_item = NULp;
2264  const char *what = NULp;
2265  const char *name = NULp;
2266 
2267  if (species) {
2268  gb_item = GBT_find_species(gb_main, species);
2269  what = "species";
2270  name = species;
2271  }
2272  else {
2273  gb_item = GBT_find_SAI(gb_main, sai);
2274  what = "SAI";
2275  name = sai;
2276  }
2277 
2278  if (!gb_item) error = GBS_global_string("Can't find %s '%s'", what, name);
2279  else {
2280  char *freeMe = NULp;
2281 
2282  if (!ali) {
2283  ali = freeMe = GBT_get_default_alignment(gb_main);
2284  if (!ali) error = "can't detect default alignment";
2285  }
2286 
2287  if (ali) {
2288  GBDATA *gb_ali = GB_entry(gb_item, ali);
2289 
2290  if (gb_ali) {
2291  GBDATA *gb_seq;
2292 
2293  for (gb_seq = GB_child(gb_ali); gb_seq; gb_seq = GB_nextChild(gb_seq)) {
2294  long type = GB_read_type(gb_seq);
2295  if (type == GB_BITS) {
2296  seq = GB_read_bits(gb_seq, '-', '+');
2297  if (seqLen) *seqLen = GB_read_bits_count(gb_seq);
2298  break;
2299  }
2300  if (type == GB_STRING) {
2301  seq = GB_read_string(gb_seq);
2302  if (seqLen) *seqLen = GB_read_string_count(gb_seq);
2303  break;
2304  }
2305  }
2306  }
2307 
2308  if (!seq) error = GBS_global_string("%s '%s' has no (usable) data in alignment '%s'", what, name, ali);
2309  }
2310  free(freeMe);
2311  }
2312  }
2313 
2314  if (error) {
2315  gb_assert(!seq);
2316  GB_export_error(error);
2317  }
2318 
2319  return seq;
2320 }
2321 
2323  const char *align;
2324  const char *sai;
2325  const char *species;
2326  int first;
2328 };
2329 
2330 #define GBL_COMMON_FILTER_PARAMS \
2331  common_filter_params common_param; \
2332  GBL_STRUCT_PARAM_STRING(common_param, align, "align=", NULp, "alignment to use (defaults to default alignment)"); \
2333  GBL_STRUCT_PARAM_STRING(common_param, sai, "SAI=", NULp, "Use default sequence of given SAI as a filter"); \
2334  GBL_STRUCT_PARAM_STRING(common_param, species, "species=", NULp, "Use default sequence of given species as a filter"); \
2335  GBL_STRUCT_PARAM_BIT (common_param, first, "first=", 0, "Use 1st stream as filter for other streams"); \
2336  GBL_STRUCT_PARAM_BIT (common_param, pairwise, "pairwise=", 0, "Use 1st stream as filter for 2nd, 3rd for 4th, ...")
2337 
2338 typedef char* (*filter_fun)(const char *seq, const char *filter, size_t flen, void *param);
2339 /* Note:
2340  * filter_fun has to return a heap copy of the filter-result.
2341  * if 'flen' != 0, it contains the length of 'filter'
2342  * 'param' may be any client data
2343  */
2344 
2345 static GB_ERROR apply_filters(GBL_command_arguments *args, common_filter_params *common, filter_fun filter_one, void *param) {
2346  GB_ERROR error = NULp;
2347 
2348  if (args->input.size()==0) error = "No input stream";
2349  else {
2350  int methodCount = !!common->sai + !!common->species + !!common->pairwise + !!common->first;
2351 
2352  if (methodCount != 1) error = "Need exactly one of the parameters 'SAI', 'species', 'pairwise' or 'first'";
2353  else {
2354  if (common->pairwise) {
2355  if (args->input.size() % 2) error = "Using 'pairwise' requires an even number of input streams";
2356  else {
2357  int i;
2358  for (i = 1; i<args->input.size(); i += 2) {
2359  PASS_2_OUT(args, filter_one(args->input.get(i), args->input.get(i-1), 0, param));
2360  }
2361  }
2362  }
2363  else {
2364  int i = 0;
2365  char *filter = NULp;
2366  size_t flen = 0;
2367 
2368  if (common->first) {
2369  if (args->input.size()<2) error = "Using 'first' needs at least 2 input streams";
2370  else {
2371  const char *in = args->input.get(i++);
2372  gb_assert(in);
2373 
2374  flen = strlen(in);
2375  filter = ARB_strduplen(in, flen);
2376  }
2377  }
2378  else {
2379  filter = gbl_read_seq_sai_or_species(args->get_gb_main(), common->species, common->sai, common->align, &flen);
2380  if (!filter) error = GB_await_error();
2381  }
2382 
2383  gb_assert(filter || error);
2384  if (filter) {
2385  for (; i<args->input.size(); ++i) {
2386  PASS_2_OUT(args, filter_one(args->input.get(i), filter, flen, param));
2387  }
2388  }
2389  free(filter);
2390  }
2391  }
2392  }
2393  return error;
2394 }
2395 
2396 // -------------------------
2397 // calculate diff
2398 
2399 struct diff_params {
2400  char equalC;
2401  char diffC;
2402 };
2403 static char *calc_diff(const char *seq, const char *filter, size_t /*flen*/, void *paramP) {
2404  // filters 'seq' through 'filter'
2405  // - replace all equal positions by 'equal_char' (if != 0)
2406  // - replace all differing positions by 'diff_char' (if != 0)
2407 
2408  diff_params *param = (diff_params*)paramP;
2409  char equal_char = param->equalC;
2410  char diff_char = param->diffC;
2411 
2412  char *result = ARB_strdup(seq);
2413  int p;
2414 
2415  for (p = 0; result[p] && filter[p]; ++p) {
2416  if (result[p] == filter[p]) {
2417  if (equal_char) result[p] = equal_char;
2418  }
2419  else {
2420  if (diff_char) result[p] = diff_char;
2421  }
2422  }
2423 
2424  // if 'seq' is longer than 'filter' and diff_char is given
2425  // -> fill rest of 'result' with 'diff_char'
2426  if (diff_char) {
2427  for (; result[p]; ++p) {
2428  result[p] = diff_char;
2429  }
2430  }
2431 
2432  return result;
2433 }
2437 
2438  diff_params param;
2439  GBL_STRUCT_PARAM_CHAR(param, equalC, "equal=", '.', "symbol for equal characters");
2440  GBL_STRUCT_PARAM_CHAR(param, diffC, "differ=", 0, "symbol for diff characters (default: use char from input stream)");
2441 
2442  GBL_TRACE_PARAMS(args);
2444 
2445  return apply_filters(args, &common_param, calc_diff, &param);
2446 }
2447 
2448 // -------------------------
2449 // standard filter
2450 
2452 
2453 struct filter_params { // used by gbl_filter and gbl_change_gc
2455 
2456  const char *include;
2457  const char *exclude;
2458 
2459  // FP_MODIFY only:
2461  const char *change_to;
2462 };
2463 
2464 static char *filter_seq(const char *seq, const char *filter, size_t flen, void *paramP) {
2465  filter_params *param = (filter_params*)paramP;
2466 
2467  size_t slen = strlen(seq);
2468  if (!flen) flen = strlen(filter);
2469  size_t mlen = slen<flen ? slen : flen;
2470 
2471  GBS_strstruct *out = GBS_stropen(mlen+1); // +1 to avoid invalid, zero-length buffer
2472 
2473  const char *charset;
2474  int include;
2475 
2476  if (param->include) {
2477  charset = param->include;
2478  include = 1;
2479  }
2480  else {
2481  gb_assert(param->exclude);
2482  charset = param->exclude;
2483  include = 0;
2484  }
2485 
2486  size_t pos = 0;
2487  size_t rest = slen;
2488  size_t ctl = 0;
2489  if (param->function == FP_MODIFY) ctl = strlen(param->change_to);
2490 
2491  int inset = 1; // 1 -> check chars in charset, 0 -> check chars NOT in charset
2492  while (rest) {
2493  size_t count;
2494  if (pos >= flen) { // behind filter
2495  // trigger last loop
2496  count = rest;
2497  inset = 0; // if 'include' -> 'applies' will get false, otherwise true
2498  // (meaning is: behind filter nothing can match 'include' or 'exclude')
2499  }
2500  else {
2501  count = (inset ? strspn : strcspn)(filter+pos, charset); // count how many chars are 'inset'
2502  }
2503  if (count) {
2504  int applies = !!include == !!inset; // true -> 'filter' matches 'include' or doesn't match 'exclude'
2505  if (count>rest) count = rest;
2506 
2507  switch (param->function) {
2508  case FP_FILTER:
2509  if (applies) GBS_strncat(out, seq+pos, count);
2510  break;
2511 
2512  case FP_MODIFY:
2513  if (applies) { // then modify
2514  size_t i;
2515  for (i = 0; i<count; i++) {
2516  char c = seq[pos+i];
2517  if (isalpha(c) && GB_random(100)<param->change_pc) c = param->change_to[GB_random(ctl)];
2518  GBS_chrcat(out, c);
2519  }
2520  }
2521  else { // otherwise simply copy
2522  GBS_strncat(out, seq+pos, count);
2523  }
2524  break;
2525  }
2526 
2527  pos += count;
2528  rest -= count;
2529  }
2530  inset = 1-inset; // toggle
2531  }
2532  return GBS_strclose(out);
2533 }
2534 
2538 
2539  filter_params param;
2540  GBL_STRUCT_PARAM_STRING(param, exclude, "exclude=", NULp, "Exclude colums");
2541  GBL_STRUCT_PARAM_STRING(param, include, "include=", NULp, "Include colums");
2542  param.function = FP_FILTER;
2543 
2544  GBL_TRACE_PARAMS(args);
2546 
2547  GB_ERROR error = NULp;
2548  int inOrEx = !!param.include + !!param.exclude;
2549 
2550  if (inOrEx != 1) error = "Need exactly one parameter of: 'include', 'exclude'";
2551  else error = apply_filters(args, &common_param, filter_seq, &param);
2552 
2553  return error;
2554 }
2555 
2559 
2560  filter_params param;
2561  GBL_STRUCT_PARAM_STRING(param, exclude, "exclude=", NULp, "Exclude colums");
2562  GBL_STRUCT_PARAM_STRING(param, include, "include=", NULp, "Include colums");
2563  GBL_STRUCT_PARAM_INT (param, change_pc, "change=", 0, "percentage of changed columns (default: silently change nothing)");
2564  GBL_STRUCT_PARAM_STRING(param, change_to, "to=", "GC", "change to one of this");
2565  param.function = FP_MODIFY;
2566 
2567  GBL_TRACE_PARAMS(args);
2569 
2570  GB_ERROR error = NULp;
2571  int inOrEx = !!param.include + !!param.exclude;
2572 
2573  if (inOrEx != 1) error = "Need exactly one parameter of: 'include', 'exclude'";
2574  else {
2575  error = apply_filters(args, &common_param, filter_seq, &param);
2576  }
2577 
2578  return error;
2579 }
2580 
2582  EXPECT_PARAMS_PASSED(args, "command[,arguments]+");
2583 
2584  // write inputstreams to temp file:
2585  GB_ERROR error = NULp;
2586  char *inputname;
2587  int i;
2588  {
2589  char *filename = GB_unique_filename("arb_exec_input", "tmp");
2590  FILE *out = GB_fopen_tempfile(filename, "wt", &inputname);
2591 
2592  if (!out) error = GB_await_error();
2593  else {
2594  for (i=0; i<args->input.size(); i++) {
2595  fprintf(out, "%s\n", args->input.get(i));
2596  }
2597  fclose(out);
2598  }
2599  free(filename);
2600  }
2601 
2602  if (!error) {
2603  // build shell command to execute
2604  char *sys;
2605  {
2606  GBS_strstruct *str = GBS_stropen(1000);
2607 
2608  GBS_strcat(str, args->get_param(0));
2609  for (i=1; i<args->param_count(); i++) {
2610  GBS_strcat(str, " \'");
2611  GBS_strcat(str, args->get_param(i)); // @@@ use GBK_singlequote here?
2612  GBS_chrcat(str, '\'');
2613  }
2614  GBS_strcat(str, " <");
2615  GBS_strcat(str, inputname);
2616 
2617  sys = GBS_strclose(str);
2618  }
2619 
2620  char *result = NULp;
2621  {
2622  FILE *in = popen(sys, "r");
2623  if (in) {
2624  GBS_strstruct *str = GBS_stropen(4096);
2625 
2626  while ((i=getc(in)) != EOF) { GBS_chrcat(str, i); }
2627  result = GBS_strclose(str);
2628  pclose(in);
2629  }
2630  else {
2631  error = GBS_global_string("Cannot execute shell command '%s'", sys);
2632  }
2633  }
2634 
2635  if (!error) {
2636  gb_assert(result);
2637  PASS_2_OUT(args, result);
2638  }
2639 
2640  free(sys);
2641  }
2642 
2643  gb_assert(GB_is_privatefile(inputname, false));
2644  GB_unlink_or_warn(inputname, &error);
2645  free(inputname);
2646 
2647  return error;
2648 }
2649 
2650 
2652  { "ali_name", gbl_ali_name },
2653  { "caps", gbl_caps },
2654  { "change", gbl_change_gc },
2655  { "checksum", gbl_checksum },
2656  { "command", gbl_command },
2657  { "compare", gbl_compare },
2658  { "colsplit", gbl_colsplit },
2659  { "icompare", gbl_icompare },
2660  { "contains", gbl_contains },
2661  { "icontains", gbl_icontains },
2662  { "count", gbl_count },
2663  { "crop", gbl_crop },
2664  { "cut", gbl_cut },
2665  { "dd", gbl_dd },
2666  { "define", gbl_define },
2667  { "diff", gbl_diff },
2668  { "div", gbl_div },
2669  { "fdiv", gbl_fdiv },
2670  { "do", gbl_do },
2671  { "drop", gbl_drop },
2672  { "dropempty", gbl_dropempty },
2673  { "dropzero", gbl_dropzero },
2674  { "echo", gbl_echo },
2675  { "equals", gbl_equals },
2676  { "iequals", gbl_iequals },
2677  { "escape", gbl_escape },
2678  { "unescape", gbl_unescape },
2679  { "eval", gbl_eval },
2680  { "exec", gbl_exec },
2681  { "export_sequence", gbl_export_sequence },
2682  { "extract_sequence", gbl_extract_sequence },
2683  { "extract_words", gbl_extract_words },
2684  { "filter", gbl_filter },
2685  { "findspec", gbl_findspec },
2686  { "findacc", gbl_findacc },
2687  { "findgene", gbl_findgene },
2688  { "format", gbl_format },
2689  { "format_sequence", gbl_format_sequence },
2690  { "gcgchecksum", gbl_gcgchecksum },
2691  { "head", gbl_head },
2692  { "inRange", gbl_inRange },
2693  { "isAbove", gbl_isAbove },
2694  { "isBelow", gbl_isBelow },
2695  { "isEqual", gbl_isEqual },
2696  { "isEmpty", gbl_isEmpty },
2697  { "keep", gbl_keep },
2698  { "left", gbl_head },
2699  { "len", gbl_len },
2700  { "lower", gbl_lower },
2701  { "merge", gbl_merge },
2702  { "mid", gbl_mid },
2703  { "mid0", gbl_mid0 },
2704  { "minus", gbl_minus },
2705  { "fminus", gbl_fminus },
2706  { "mult", gbl_mult },
2707  { "fmult", gbl_fmult },
2708  { "and", gbl_and },
2709  { "or", gbl_or },
2710  { "not", gbl_not },
2711  { "origin_gene", gbl_origin_gene },
2712  { "origin_organism", gbl_origin_organism },
2713  { "partof", gbl_partof },
2714  { "ipartof", gbl_ipartof },
2715  { "per_cent", gbl_per_cent },
2716  { "fper_cent", gbl_fper_cent },
2717  { "plus", gbl_plus },
2718  { "fplus", gbl_fplus },
2719  { "pretab", gbl_pretab },
2720  { "quote", gbl_quote },
2721  { "unquote", gbl_unquote },
2722  { "readdb", gbl_readdb },
2723  { "remove", gbl_remove },
2724  { "rest", gbl_rest },
2725  { "right", gbl_tail },
2726  { "round", gbl_round },
2727  { "select", gbl_select },
2728  { "sequence", gbl_sequence },
2729  { "sequence_type", gbl_sequence_type },
2730  { "split", gbl_split },
2731  { "srt", gbl_srt },
2732  { "streams", gbl_streams },
2733  { "swap", gbl_swap },
2734  { "tab", gbl_tab },
2735  { "tail", gbl_tail },
2736  { "taxonomy", gbl_taxonomy },
2737  { "toback", gbl_toback },
2738  { "tofront", gbl_tofront },
2739  { "trace", gbl_trace },
2740  { "translate", gbl_translate },
2741  { "upper", gbl_upper },
2742 
2743  { NULp, NULp }
2744 };
2745 
2747  static GBL_command_lookup_table clt(gbl_command_table, ARRAY_ELEMS(gbl_command_table)-1);
2748  return clt;
2749 }
2750 
static GB_ERROR gbl_drop(GBL_command_arguments *args)
Definition: adlang1.cxx:978
static GB_ERROR gbl_toback(GBL_command_arguments *args)
Definition: adlang1.cxx:1072
int traceACI
Definition: adlang1.cxx:44
static GBL_command_definition gbl_command_table[]
Definition: adlang1.cxx:2651
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:796
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:1643
static char * calc_diff(const char *seq, const char *filter, size_t, void *paramP)
Definition: adlang1.cxx:2403
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:169
static GB_ERROR tab(GBL_command_arguments *args, bool pretab)
Definition: adlang1.cxx:913
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:731
bool operator[](int i) const
Definition: adlang1.cxx:698
#define EXPECT_OPTIONAL_PARAMS(args, fixCnt, fixhelp, optCnt, opthelp)
Definition: gb_aci_impl.h:209
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:457
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:465
static GB_ERROR gbl_merge(GBL_command_arguments *args)
Definition: adlang1.cxx:1075
static GB_ERROR gbl_origin_organism(GBL_command_arguments *args)
Definition: adlang1.cxx:615
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:690
#define GBL_PARAM_UINT(var,param_name, def, help_text)
Definition: gb_aci_impl.h:99
bool has_group_info() const
Definition: TreeNode.h:403
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:1013
#define EXPECT_OPTIONAL_PARAMS_CUSTOM(args, fixCnt, fixhelp, optCnt, opthelp, trail, all)
Definition: gb_aci_impl.h:210
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:431
GBDATA * GB_nextEntry(GBDATA *entry)
Definition: adquery.cxx:339
long
Definition: AW_awar.cxx:154
static GB_ERROR gbl_ali_name(GBL_command_arguments *args)
Definition: adlang1.cxx:1981
static GB_ERROR gbl_crop(GBL_command_arguments *args)
Definition: adlang1.cxx:940
#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:405
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:791
#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:1864
static GB_ERROR gbl_eval(GBL_command_arguments *args)
Definition: adlang1.cxx:494
static GB_ERROR gbl_escape(GBL_command_arguments *args)
Definition: adlang1.cxx:456
const char * sai
Definition: adlang1.cxx:2324
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
const char * include
Definition: adlang1.cxx:2456
int approve_pos(int pos, int len)
Definition: adlang1.cxx:255
GB_HASH * GBS_create_dynaval_hash(long estimated_elements, GB_CASE case_sens, void(*freefun)(long))
Definition: adhash.cxx:271
bool GB_have_error()
Definition: arb_msg.cxx:349
static GB_ERROR gbl_format(GBL_command_arguments *args)
Definition: adlang1.cxx:2245
void GBS_strncat(GBS_strstruct *strstr, const char *ptr, size_t len)
Definition: arb_strbuf.cxx:101
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:662
#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:541
long GBS_gcgchecksum(const char *seq)
Definition: adstring.cxx:247
const char * species
Definition: adlang1.cxx:2325
#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:938
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:2451
const char * change_to
Definition: adlang1.cxx:2461
long GB_read_bits_count(GBDATA *gbd)
Definition: arbdb.cxx:915
static T binop_div(T v1, T v2)
Definition: adlang1.cxx:1343
const char * get(const char *name) const
Definition: adlang1.cxx:524
#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:907
GBDATA * GB_get_grandfather(GBDATA *gbd)
Definition: arbdb.cxx:1726
char * GBT_get_alignment_type_string(GBDATA *gb_main, const char *aliname)
Definition: adali.cxx:739
#define ACCEPT_ANY_PARAMS(args)
Definition: gb_aci_impl.h:206
GBT_ITEM_TYPE
Definition: adlang1.cxx:1465
GBDATA * GB_get_father(GBDATA *gbd)
Definition: arbdb.cxx:1720
GB_ERROR gbl_apply_binary_operator(GBL_command_arguments *args, char *(*op)(const char *, const char *, T), T client_data)
Definition: adlang1.cxx:329
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:693
static GB_HASH * cached_taxonomies
Definition: adlang1.cxx:1579
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:575
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, bool dropEmptyTokens)
Definition: arb_strarray.h:232
GB_ERROR check_no_parameter(GBL_command_arguments *args)
Definition: gb_aci_impl.h:154
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:577
static GB_ERROR gbl_change_gc(GBL_command_arguments *args)
Definition: adlang1.cxx:2556
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:899
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:2581
GB_ERROR GB_export_error(const char *error)
Definition: arb_msg.cxx:259
#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:187
GBS_strstruct * GBS_stropen(long init_size)
Definition: arb_strbuf.cxx:39
static GB_ERROR gbl_unquote(GBL_command_arguments *args)
Definition: adlang1.cxx:439
size_t GB_read_string_count(GBDATA *gbd)
Definition: arbdb.cxx:910
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:353
static int gbl_strincmp(const char *s1, const char *s2, int size2)
Definition: adlang1.cxx:193
Definition: arbdb.h:67
static char * do_extract_words(const char *source, const char *chars, float minlen, bool sort_output)
Definition: adlang1.cxx:1164
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:1641
unsigned int nat
Definition: gb_aci_impl.h:61
static GB_ERROR gbl_command(GBL_command_arguments *args)
Definition: adlang1.cxx:475
static GB_ERROR gbl_cut(GBL_command_arguments *args)
Definition: adlang1.cxx:968
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:490
static T binop_isAbove(T i1, T i2)
Definition: adlang1.cxx:1361
static GB_ERROR gbl_upper(GBL_command_arguments *args)
Definition: adlang1.cxx:890
GB_CSTR GB_read_key_pntr(GBDATA *gbd)
Definition: arbdb.cxx:1654
#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:2249
static GB_ERROR gbl_swap(GBL_command_arguments *args)
Definition: adlang1.cxx:1024
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:188
static const char * gbl_stristr(const char *haystack, const char *needle)
Definition: adlang1.cxx:210
#define EXPECT_ITEM_REFERENCED(args)
Definition: gb_aci_impl.h:217
static GBT_ITEM_TYPE identify_gb_item(GBDATA *gb_item)
Definition: adlang1.cxx:1471
T_PT_MAIN com
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:220
static GB_ERROR gbl_dropempty(GBL_command_arguments *args)
Definition: adlang1.cxx:1002
static bool is_cached_taxonomy(const char *, long val, void *cl_ct)
Definition: adlang1.cxx:1581
static GB_ERROR gbl_tab(GBL_command_arguments *args)
Definition: adlang1.cxx:937
const char * get_param(int idx) const
Definition: gb_aci.h:245
void GBS_strcat(GBS_strstruct *strstr, const char *ptr)
Definition: arb_strbuf.cxx:108
static void error(const char *msg)
Definition: mkptypes.cxx:96
#define TRACE_ACI(text)
Definition: gb_aci_impl.h:197
GBDATA * GB_get_root(GBDATA *gbd)
Definition: arbdb.cxx:1738
#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:952
#define AWAR_TREE_REFRESH
FILE * GB_fopen_tempfile(const char *filename, const char *fmode, char **res_fullname)
Definition: adsocket.cxx:1142
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:1056
#define GBL_COMMON_FILTER_PARAMS
Definition: adlang1.cxx:2330
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:1907
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:166
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:657
static void flush_taxonomy_cb(GBDATA *gbd, cached_taxonomy *ct)
Definition: adlang1.cxx:1599
Case
Definition: adlang1.cxx:860
void GBS_dynaval_free(long val)
Definition: adhash.cxx:278
static GB_ERROR gbl_mid(GBL_command_arguments *args)
Definition: adlang1.cxx:911
static SearchTree * tree[SEARCH_PATTERNS]
Definition: ED4_search.cxx:629
static GB_ERROR gbl_colsplit(GBL_command_arguments *args)
Definition: adlang1.cxx:1140
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:2535
static const char * tree_of_cached_taxonomy(cached_taxonomy *ct)
Definition: adlang1.cxx:1588
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:257
const char * exclude
Definition: adlang1.cxx:2457
GB_ERROR count_by_tab(GBL_command_arguments *args, const Tab &tab)
Definition: adlang1.cxx:701
static GB_ERROR apply_filters(GBL_command_arguments *args, common_filter_params *common, filter_fun filter_one, void *param)
Definition: adlang1.cxx:2345
binop_pair(int(*INT_)(int, int), double(*DOUBLE_)(double, double))
Definition: adlang1.cxx:1302
void nl()
Definition: test_unit.h:404
GBDATA * GBT_find_sequence(GBDATA *gb_species, const char *aliname)
Definition: adali.cxx:682
char * GBT_read_gene_sequence(GBDATA *gb_gene, bool use_revComplement, char partSeparator)
Definition: adali.cxx:931
static char * filter_seq(const char *seq, const char *filter, size_t flen, void *paramP)
Definition: adlang1.cxx:2464
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:614
static GB_ERROR gbl_trace(GBL_command_arguments *args)
Definition: adlang1.cxx:279
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:2323
static GB_ERROR gbl_export_sequence(GBL_command_arguments *args)
Definition: adlang1.cxx:1947
char * GB_unique_filename(const char *name_prefix, const char *suffix)
Definition: adsocket.cxx:1199
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:204
void GBS_chrcat(GBS_strstruct *strstr, char ch)
Definition: arb_strbuf.cxx:119
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:891
static GB_ERROR convert_case(GBL_command_arguments *args, Case convTo)
Definition: adlang1.cxx:862
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:1993
GB_ERROR GB_export_errorf(const char *templat,...)
Definition: arb_msg.cxx:264
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
bool is_leaf() const
Definition: TreeNode.h:171
static GB_ERROR gbl_echo(GBL_command_arguments *args)
Definition: adlang1.cxx:848
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
static DefinedCommands defined_commands
Definition: adlang1.cxx:527
#define gb_assert(cond)
Definition: arbdbt.h:11
void set(const char *name, char *cmd)
Definition: adlang1.cxx:523
#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:653
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:1789
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:2007
static GB_ERROR gbl_plus(GBL_command_arguments *args)
Definition: adlang1.cxx:1349
void GB_touch(GBDATA *gbd)
Definition: arbdb.cxx:2790
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:176
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:188
#define GBL_PARAM_STRING(var, param_name, def, help_text)
Definition: gb_aci_impl.h:100
char * name
Definition: TreeNode.h:134
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:903
static int binop_rest(int i1, int i2)
Definition: adlang1.cxx:1346
static GB_ERROR gbl_diff(GBL_command_arguments *args)
Definition: adlang1.cxx:2434
char * GBS_strclose(GBS_strstruct *strstr)
Definition: arb_strbuf.cxx:69
static char * get_taxonomy_string(GB_HASH *tax_hash, const char *group_key, int depth, GB_ERROR *error)
Definition: adlang1.cxx:1753
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:1093
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:353
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:711
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:541
char *(* filter_fun)(const char *seq, const char *filter, size_t flen, void *param)
Definition: adlang1.cxx:2338
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:529
static int line
Definition: arb_a2ps.c:296
#define NULp
Definition: cxxforward.h:97
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:889
static GB_ERROR applyToItemFoundByKey(GBL_command_arguments *args, const char *itemname, GBDATA *gb_item_data, const char *key)
Definition: adlang1.cxx:618
static char * command
Definition: arb_a2ps.c:319
#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:687
const char * GBT_get_name(GBDATA *gb_item)
Definition: aditem.cxx:450
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:407
static GB_ERROR gbl_dd(GBL_command_arguments *args)
Definition: adlang1.cxx:855
GBDATA * GBT_find_tree(GBDATA *gb_main, const char *tree_name)
Definition: adtree.cxx:947
void destroy(TreeNode *that)
Definition: TreeNode.h:559
GBDATA * gb_node
Definition: TreeNode.h:133
GBDATA * gb_main
Definition: adname.cxx:33
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:441
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:563
#define EXPECT_LEGAL_STREAM_INDEX(args, number)
Definition: gb_aci_impl.h:212
bool GEN_is_pseudo_gene_species(GBDATA *gb_species)
Definition: adGene.cxx:568
static GB_ERROR expect_used_in_genome_db(GBL_command_arguments *args)
Definition: adlang1.cxx:570
#define STATIC_ASSERT(const_expression)
Definition: static_assert.h:36
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:1680
static GB_ERROR gbl_head(GBL_command_arguments *args)
Definition: adlang1.cxx:893
const GBL_command_lookup_table & ACI_get_standard_commands()
Definition: adlang1.cxx:2746
#define EXPECT_PARAMS(args, cnt, help)
Definition: gb_aci_impl.h:208
long GBS_read_hash(const GB_HASH *hs, const char *key)
Definition: adhash.cxx:395
GB_ERROR mid(GBL_command_arguments *args, int start_index)
Definition: adlang1.cxx:906
static GB_ERROR gbl_format_sequence(GBL_command_arguments *args)
Definition: adlang1.cxx:2246
GBDATA * GB_entry(GBDATA *father, const char *key)
Definition: adquery.cxx:334
static GB_ERROR gbl_mid0(GBL_command_arguments *args)
Definition: adlang1.cxx:910
filter_function function
Definition: adlang1.cxx:2454
#define EXPECT_PARAMS_PASSED(args, syntax)
Definition: gb_aci_impl.h:205
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:195
static GB_ERROR gbl_findspec(GBL_command_arguments *args)
Definition: adlang1.cxx:653
static GB_ERROR gbl_tofront(GBL_command_arguments *args)
Definition: adlang1.cxx:1073
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
GBDATA * GEN_find_origin_gene(GBDATA *gb_pseudo, const GB_HASH *organism_hash)
Definition: adGene.cxx:676
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:385
GBDATA * GBT_get_species_data(GBDATA *gb_main)
Definition: aditem.cxx:105
GB_write_int const char s
Definition: AW_awar.cxx:156