1 /* @source ajacd **************************************************************
2 **
3 ** These functions control all aspects of AJAX command definition
4 ** syntax, command line handling and prompting of the user.
5 **
6 ** The only major functions visible to callers are the initialisation
7 ** function ajAcdInit and a series of retrieval functions ajGetAcdObject
8 ** for each defined object type (integer, sequence, and so on).
9 **
10 ** Future extensions are planned, including the ability to write out
11 ** the ACD internal structures in a number of other interface formats.
12 **
13 ** @author Copyright (C) 1998 Peter Rice
14 ** @version $Revision: 1.91 $
15 ** @modified Jun 25 pmr First version
16 ** @modified May 06 2004 Jon Ison Minor mods.
17 ** @modified $Date: 2012/12/07 10:22:55 $ by $Author: rice $
18 ** @@
19 **
20 ** This library is free software; you can redistribute it and/or
21 ** modify it under the terms of the GNU Lesser General Public
22 ** License as published by the Free Software Foundation; either
23 ** version 2.1 of the License, or (at your option) any later version.
24 **
25 ** This library is distributed in the hope that it will be useful,
26 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
27 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28 ** Lesser General Public License for more details.
29 **
30 ** You should have received a copy of the GNU Lesser General Public
31 ** License along with this library; if not, write to the Free Software
32 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
33 ** MA  02110-1301,  USA.
34 **
35 ******************************************************************************/
36 
37 
38 #include "ajlib.h"
39 
40 #include "ajacd.h"
41 
42 #include "ajnam.h"
43 #include "ajfiledata.h"
44 #include "ajutil.h"
45 #include "ajfileio.h"
46 #include "ajsys.h"
47 
48 #include "ajassem.h"
49 #include "ajassemread.h"
50 #include "ajassemwrite.h"
51 #include "ajfeat.h"
52 #include "ajfeatread.h"
53 #include "ajfeatwrite.h"
54 #include "ajobo.h"
55 #include "ajoboread.h"
56 #include "ajobowrite.h"
57 #include "ajrefseqread.h"
58 #include "ajrefseqwrite.h"
59 #include "ajresourceread.h"
60 #include "ajresourcewrite.h"
61 #include "ajseq.h"
62 #include "ajseqtype.h"
63 #include "ajseqread.h"
64 #include "ajseqread.h"
65 #include "ajseqwrite.h"
66 #include "ajtaxread.h"
67 #include "ajtaxwrite.h"
68 #include "ajtextread.h"
69 #include "ajtextwrite.h"
70 #include "ajurlread.h"
71 #include "ajurlwrite.h"
72 #include "ajvarread.h"
73 #include "ajvarwrite.h"
74 #include "ajxmlread.h"
75 #include "ajxmlwrite.h"
76 
77 #include <stddef.h>
78 #include <stdarg.h>
79 #include <float.h>
80 #include <limits.h>
81 #include <math.h>
82 
83 
84 #ifdef WIN32
85 #include "win32.h"
86 #endif
87 
88 
89 
90 #define DEFDLIST  "."
91 #define DEFBLOSUM "EBLOSUM62"
92 #define DEFDNA    "EDNAFULL"
93 
94 #define ACD_SEQ_BEGIN 0
95 #define	ACD_SEQ_END 1
96 #define	ACD_SEQ_LENGTH 2
97 #define	ACD_SEQ_PROTEIN 3
98 #define	ACD_SEQ_NUCLEIC 4
99 #define	ACD_SEQ_NAME 5
100 #define	ACD_SEQ_USA 6
101 #define	ACD_SEQ_WEIGHT 7
102 #define	ACD_SEQ_COUNT 8
103 #define	ACD_SEQ_MULTICOUNT 9
104 
105 #define USED_GET 1
106 #define USED_ACD 2
107 
108 /*static AjBool acdDebug = 0;*/
109 /*static AjBool acdDebugSet = 0;*/
110 static AjBool acdDoHelp = AJFALSE;
111 static AjBool acdDoLog = AJFALSE;
112 static AjBool acdDoWarnRange =AJTRUE;
113 static AjBool acdDoPretty = AJFALSE;
114 static AjBool acdDoTable = AJFALSE;
115 static AjBool acdDoTrace = AJFALSE;
116 static AjBool acdDoValid = AJFALSE;
117 static AjBool acdDoGalaxy = AJFALSE;
118 static AjBool acdDoGalaxyNuc = AJFALSE;
119 static AjBool acdDoGalaxyProt = AJFALSE;
120 static AjBool acdDoXsd = AJFALSE;
121 static AjBool acdDoVersion = AJFALSE;
122 static AjBool acdVerbose = AJFALSE;
123 static AjBool acdCommandLine = AJTRUE;
124 static AjBool acdAuto = AJFALSE;
125 static AjBool acdFilter = AJFALSE;
126 static AjBool acdOptions = AJFALSE;
127 static AjBool acdStdout = AJFALSE;
128 static AjBool acdCodeSet = AJFALSE;
129 static AjBool acdWrapper = AJFALSE;
130 static AjPTable acdCodeTable = NULL;
131 static AjBool acdKnowntypeSet = AJFALSE;
132 static AjPTable acdKnowntypeTypeTable = NULL;
133 static AjPTable acdKnowntypeDescTable = NULL;
134 
135 /* static AjBool acdQualTestSkip = AJFALSE; */
136 
137 static ajint acdInFile = 0;
138 static ajint acdInFileSet = AJFALSE;
139 static ajint acdOutFile = 0;
140 static ajint acdPromptTry = 2;
141 
142 static AjPStr acdTmpStr = NULL;
143 static AjPStr acdTmpStr2 = NULL;
144 
145 static AjPStr acdPrefName = NULL;
146 static AjPStr acdPrefToken = NULL;
147 
148 static AjPStr acdPackName = NULL;
149 static AjPStr acdPackVersion = NULL;
150 
151 static AjPStr acdInputName = NULL;
152 static ajint acdInputLen = 0;
153 static AjPStr acdInFName = NULL;
154 static AjPStr acdInTypeFeatName = NULL;
155 static AjPStr acdInTypeSeqName = NULL;
156 static AjPStr acdOutFName = NULL;
157 static AjPStr acdOutFExt = NULL;
158 static AjPStr acdTmpOutFName = NULL;
159 
160 static AjPList acdListComments = NULL;
161 static AjPList acdListCommentsCount = NULL;
162 static AjPList acdListCommentsColumn = NULL;
163 static AjPStr acdLogFName = NULL;
164 static AjPFile acdLogFile = NULL;
165 static AjPList acdSecList = NULL;
166 static AjPTable acdSecTable = NULL;
167 static AjPTable acdExternalTable = NULL;
168 
169 static AjPStr acdOutFullFName = NULL;
170 static AjPStr acdPrettyFName = NULL;
171 static AjPFile acdPrettyFile = NULL;
172 static ajint acdPrettyMargin = 0;
173 static ajint acdPrettyIndent = 2;
174 
175 static AjPStr acdFName = NULL;
176 static ajint acdLineNum = 0;
177 static ajint acdCmtWord  = 0;
178 static ajint acdWordNum = 0;
179 static ajint acdWordSave = 0;
180 static ajint acdErrorCount = 0;
181 
182 static AjPStr acdStrName = NULL;
183 
184 static AjPStr acdVarAcdProtein = NULL;
185 
186 static ajint acdUseData = 0;
187 static ajint acdUseFeatures = 0;
188 static ajint acdUseInfile = 0;
189 static ajint acdUseIn = 0;
190 static ajint acdUseSeq = 0;
191 
192 static ajint acdUseAlign = 0;
193 static ajint acdUseFeatout = 0;
194 static ajint acdUseOut = 0;
195 static ajint acdUseOutfile = 0;
196 static ajint acdUseReport = 0;
197 static ajint acdUseSeqout = 0;
198 static ajint acdUseGraph = 0;
199 
200 static ajint acdUseMisc = 0;
201 
202 static AjPRegexp acdRegQualParse  = NULL;
203 static AjPRegexp acdRegResolveVar = NULL;
204 static AjPRegexp acdRegResolveFun = NULL;
205 
206 static AjPRegexp acdRegExpPlusI = NULL;
207 static AjPRegexp acdRegExpPlusD = NULL;
208 static AjPRegexp acdRegExpMinusI = NULL;
209 static AjPRegexp acdRegExpMinusD = NULL;
210 static AjPRegexp acdRegExpStarI = NULL;
211 static AjPRegexp acdRegExpStarD = NULL;
212 static AjPRegexp acdRegExpDivI = NULL;
213 static AjPRegexp acdRegExpDivD = NULL;
214 static AjPRegexp acdRegExpEqualI = NULL;
215 static AjPRegexp acdRegExpEqualD = NULL;
216 static AjPRegexp acdRegExpEqualT = NULL;
217 static AjPRegexp acdRegExpNeI = NULL;
218 static AjPRegexp acdRegExpNeD = NULL;
219 static AjPRegexp acdRegExpNeT = NULL;
220 static AjPRegexp acdRegExpGtI = NULL;
221 static AjPRegexp acdRegExpGtD = NULL;
222 static AjPRegexp acdRegExpGtT = NULL;
223 static AjPRegexp acdRegExpLtI = NULL;
224 static AjPRegexp acdRegExpLtD = NULL;
225 static AjPRegexp acdRegExpLtT = NULL;
226 static AjPRegexp acdRegExpOrI = NULL;
227 static AjPRegexp acdRegExpOrD = NULL;
228 static AjPRegexp acdRegExpOrT = NULL;
229 static AjPRegexp acdRegExpAndI = NULL;
230 static AjPRegexp acdRegExpAndD = NULL;
231 static AjPRegexp acdRegExpAndT = NULL;
232 static AjPRegexp acdRegExpCond = NULL;
233 static AjPRegexp acdRegExpNot = NULL;
234 static AjPRegexp acdRegExpOneofCase = NULL;
235 static AjPRegexp acdRegExpOneofList = NULL;
236 static AjPRegexp acdRegExpCaseCase = NULL;
237 static AjPRegexp acdRegExpCaseList = NULL;
238 static AjPRegexp acdRegExpFilename = NULL;
239 static AjPRegexp acdRegExpFileExists = NULL;
240 static AjPRegexp acdRegExpValue = NULL;
241 
242 static AjPRegexp acdRegVarname  = NULL;
243 static AjPRegexp acdRegFunction = NULL;
244 static AjPRegexp acdRegToggle   = NULL;
245 
246 static AjPStr acdParseReturn  = NULL;
247 static AjPStr acdReply        = NULL;
248 static AjPStr acdReplyDef     = NULL;
249 static AjPStr acdReplyPrompt  = NULL;
250 static AjPStr acdUserMsg      = NULL;
251 static AjPStr acdUserReplyDef = NULL;
252 static AjPStr acdDirectoryDef = NULL;
253 static AjPStr acdQNameTmp     = NULL;
254 static AjPStr acdQTypeTmp     = NULL;
255 static AjPStr acdAttrValTmp   = NULL;
256 static AjPStr acdQualNameTmp  = NULL;
257 static AjPStr acdQualNumTmp   = NULL;
258 
259 static AjBool acdParseQuotes = AJFALSE;
260 static AjBool acdRegVarInit  = AJFALSE;
261 
262 static AjPStr  acdEdamPath = NULL;
263 static AjPFile acdEdamFile = NULL;
264 static AjPOboData  acdEdam = NULL;
265 
266 static AjPStr acdGalaxyCmdStr = NULL;
267 
268 /*
269 static ajint acdLineCount = 0;
270 static AjPList acdListCount = NULL;
271 */
272 
273 /* keywords (other than qualifier types) */
274 
275 
276 
277 
278 /* @enumstatic AcdEStage ******************************************************
279 **
280 ** ACD level of parsing
281 **
282 ** @value QUAL_STAGE Qualifier parsing
283 ** @value APPL_STAGE Application parsing
284 ** @value VAR_STAGE Variable parsing
285 ** @value REL_STAGE Relation parsing
286 ** @value SEC_STAGE Section parsing
287 ** @value ENDSEC_STAGE End section parsing
288 ** @value BAD_STAGE Stage parsing error
289 ** @value NO_STAGE  No parsing stage defined
290 ******************************************************************************/
291 
292 typedef enum
293 {
294     QUAL_STAGE, APPL_STAGE, VAR_STAGE, REL_STAGE,
295     SEC_STAGE, ENDSEC_STAGE, BAD_STAGE, NO_STAGE
296 } AcdEStage;
297 
298 static AcdEStage acdCurrentStage = NO_STAGE;
299 
300 
301 
302 
303 /* @enumstatic AcdELevel ******************************************************
304 **
305 ** ACD item level as defined in the ACD structure
306 **
307 ** @value ACD_APPL     Application
308 ** @value ACD_PARAM    Positonal parameter
309 ** @value ACD_QUAL     Qualifier
310 ** @value ACD_VAR      Internal variable
311 ** @value ACD_RELATION Standalone relation
312 ** @value ACD_SEC      Section
313 ** @value ACD_ENDSEC   End of section
314 ******************************************************************************/
315 
316 typedef enum
317 {
318     ACD_APPL,
319     ACD_PARAM,
320     ACD_QUAL,
321     ACD_VAR,
322     ACD_RELATION,
323     ACD_SEC,
324     ACD_ENDSEC
325 }  AcdELevel;
326 
327 
328 
329 
330 /* Levels as text, only for use in logging report */
331 
332 static const char* acdLevel[] =
333 {
334     "APPL", "PARAM", "QUAL", "VAR",
335     "IF", "SEC", "ENDSEC"
336 };
337 
338 /* Attribute value types */
339 
340 enum AcdEValtype
341 {
342     VT_APPL, VT_STR, VT_WORD,
343     VT_BOOL, VT_INT, VT_FLOAT, VT_CHAR,
344     VT_NULL
345 };
346 
347 
348 enum AcdEReftype
349 {
350     REF_NONE=0,
351     REF_ALL,
352     REF_SINGLE
353 };
354 
355 
356 /* Attribute value types as text for use in logging report */
357 
358 static const char* acdValNames[] =
359 {
360     "application", "string", "word",
361     "boolean", "integer", "float", "character",
362     NULL
363 };
364 
365 
366 
367 
368 /* @filesection ajacd ********************************************************
369 **
370 ** @nam1rule aj Function belongs to the AJAX library.
371 **
372 */
373 
374 
375 
376 
377 /* @datasection [none] ACD internals ***********************************
378 **
379 ** Function is for processing ACD internals.
380 **
381 ** @nam2rule Acd ACD processing
382 ** @suffix    P  [char*]     Package name provided
383 ** @suffix    V  [char*]     Package version provided
384 */
385 
386 
387 
388 
389 /* @section data definitions **************************************************
390 **
391 ** Data definitions and function lists
392 **
393 ** @fdata [none]
394 ** @fcategory misc
395 **
396 ******************************************************************************/
397 
398 
399 
400 
401 /* @datastatic AcdPAttrAlias **************************************************
402 **
403 ** ACD attribute old names and their new equivalents
404 **
405 ** Commonly used abbreviations of the old names are also included.
406 **
407 ** @alias AcdSAttrAlias
408 ** @alias AcdOAttrAlias
409 **
410 ** @attr OldName [const char*] Attribute name in a previous EMBOSS/AJAX release
411 ** @attr NewName [const char*] Current attribute name
412 ** @@
413 ******************************************************************************/
414 
415 typedef struct AcdSAttrAlias
416 {
417     const char* OldName;
418     const char* NewName;
419 } AcdOAttrAlias;
420 #define AcdPAttrAlias AcdOAttrAlias*
421 
422 static AcdOAttrAlias acdAttrAlias[] =
423 {
424     {"required", "standard"},
425     {"req", "standard"},
426     {"optional", "additional"},
427     {"option", "additional"},
428     {"opt", "additional"},
429     {"standardtype", "knowntype"},
430     {NULL, NULL}
431 };
432 
433 
434 
435 
436 /* @datastatic AcdPAttr *******************************************************
437 **
438 ** ACD attribute definition structure
439 **
440 ** @alias AcdSAttr
441 ** @alias AcdOAttr
442 **
443 ** @attr Name [const char*] Attribute name
444 ** @attr Type [enum AcdEValtype] Type code
445 ** @attr Multiple [AjBool] True if multiple values are allowed
446 ** @attr Default [const char*] Default value as a string for help
447 **                             and documentation
448 ** @attr Help [const char*] Descriptive short text for documentation
449 ** @@
450 ******************************************************************************/
451 
452 typedef struct AcdSAttr
453 {
454     const char* Name;
455     enum AcdEValtype Type;
456     AjBool Multiple;
457     const char* Default;
458     const char* Help;
459 } AcdOAttr;
460 #define AcdPAttr AcdOAttr*
461 
462 
463 
464 
465 /* @datastatic AcdPQual *******************************************************
466 **
467 ** ACD qualifier definition structure
468 **
469 ** @alias AcdSQual
470 ** @alias AcdOQual
471 **
472 ** @attr Name [const char*] Qualifier name
473 ** @attr Default [const char*] Default value as a string for help
474 **                             and documentation
475 ** @attr Type [const char*] Type boolean, integer, float or string
476 ** @attr Help [const char*] Help text for documentation and for -help output
477 ** @@
478 ******************************************************************************/
479 
480 typedef struct AcdSQual
481 {
482     const char* Name;
483     const char* Default;
484     const char* Type;
485     const char* Help;
486 } AcdOQual;
487 #define AcdPQual AcdOQual*
488 
489 
490 
491 
492 /* @datastatic AcdPTableItem **************************************************
493 **
494 ** Help table structure
495 **
496 ** @alias AcdSTableItem
497 ** @alias AcdOTableItem
498 **
499 ** @attr Qual [AjPStr] Qualifier name
500 ** @attr Type [AjPStr] Qualifier type
501 ** @attr Help [AjPStr] Help text
502 ** @attr Valid [AjPStr] Valid input
503 ** @attr Expect [AjPStr] Expected value(s)
504 ** @attr Title [AjPStr] Section title
505 ** @@
506 ******************************************************************************/
507 
508 typedef struct AcdSTableItem
509 {
510     AjPStr Qual;
511     AjPStr Type;
512     AjPStr Help;
513     AjPStr Valid;
514     AjPStr Expect;
515     AjPStr Title;
516 } AcdOTableItem;
517 #define AcdPTableItem AcdOTableItem*
518 
519 
520 
521 
522 /* @datastatic AcdPXsdItem ****************************************************
523 **
524 ** XSD data structure
525 **
526 ** @alias AcdSXsdItem
527 ** @alias AcdOXsdItem
528 **
529 ** @attr Qual [AjPStr] Qualifier name
530 ** @attr Type [AjPStr] Qualifier type
531 ** @attr Annotation [AjPStr] Annotation text
532 ** @attr Relation [AjPStr] Relation attributes text
533 ** @attr Valid [AjPStr] Valid input
534 ** @attr Expect [AjPStr] Expected value(s)
535 ** @attr Required [AjBool] True if a required value
536 ** @attr Optional[AjBool] True if an optional value
537 ** @@
538 ******************************************************************************/
539 
540 typedef struct AcdSXsdItem
541 {
542     AjPStr Qual;
543     AjPStr Type;
544     AjPStr Annotation;
545     AjPStr Relation;
546     AjPStr Valid;
547     AjPStr Expect;
548     AjBool Required;
549     AjBool Optional;
550 } AcdOXsdItem;
551 #define AcdPXsdItem AcdOXsdItem*
552 
553 
554 
555 
556 /* @datastatic AcdPGalaxyItem *************************************************
557 **
558 ** Galaxy data structure
559 **
560 ** @alias AcdSGalaxyItem
561 ** @alias AcdOGalaxyItem
562 **
563 ** @attr Qual [AjPStr] Qualifier name
564 ** @attr Type [AjPStr] Qualifier type
565 ** @attr Prompt [AjPStr] Prompt text
566 ** @attr Annotation [AjPStr] Annotation text
567 ** @attr Relation [AjPStr] Relation attributes text
568 ** @attr Valid [AjPStr] Valid input
569 ** @attr Expect [AjPStr] Expected value(s)
570 ** @attr Required [AjBool] True if a required value
571 ** @attr Optional[AjBool] True if an optional value
572 ** @@
573 ******************************************************************************/
574 
575 typedef struct AcdSGalaxyItem
576 {
577     AjPStr Qual;
578     AjPStr Type;
579     AjPStr Prompt;
580     AjPStr Annotation;
581     AjPStr Relation;
582     AjPStr Valid;
583     AjPStr Expect;
584     AjBool Required;
585     AjBool Optional;
586 } AcdOGalaxyItem;
587 #define AcdPGalaxyItem AcdOGalaxyItem*
588 
589 
590 
591 
592 /* @datastatic AcdPAcd ********************************************************
593 **
594 ** AJAX Command Definition item data.
595 **
596 ** ACDs are built as an ACD file is parsed, and are processed as a
597 ** list in sequential order.
598 **
599 ** ACDs contain type information. Some functions will only work on certain
600 ** types of ACDs.
601 **
602 ** All ACD items are in a list. The base ACD item points to the next,
603 ** and so on until the Next pointer is NULL.
604 **
605 ** There is currently no destructor. No need for one at present.
606 **
607 ** @new acdNewQual Creates a qualifier ACD
608 ** @new acdNewQualQual Creates an associated qualifier ACD
609 ** @new acdNewAppl Creates an ACD application
610 ** @new acdNewVar Creates an ACD variable
611 ** @new acdNewAcd General constructor
612 **
613 ** @attr Next [struct AcdSAcd*] Pointer to next ACD item
614 ** @attr Name [AjPStr] ACD item name
615 ** @attr Token [AjPStr] Command line qualifier (usually the same as Name)
616 ** @attr PNum [ajint] Parameter number, or zero if not a parameter
617 ** @attr Level [AcdELevel] ACD type class (qual/param, var, appl, etc.)
618 ** @attr Type [ajint] Index into acdType or acdKeywords
619 ** @attr NAttr [ajint] Number of ACD type-specific attributes
620 ** @attr AttrStr [AjPStr*] Definitions of ACD type-specific attributes
621 ** @attr SetAttr [AcdPAttr] Definitions of calculated attributes
622 ** @attr SetStr [AjPPStr] Values for the calculated attributes (SetAttr)
623 ** @attr DefStr [AjPPStr] Values for the default attributes
624 ** @attr Defined [AjBool] Set when a value is defined on the commandline
625 **                        or by an associated qualifier ACD attribute
626 ** @attr UserDefined [AjBool] Set when a value is defined by the user
627 **                            including replies to prompts
628 ** @attr UserSetNull [AjBool] Set when a value is undefined by the user
629 **                            with -no before a qualifier name
630 ** @attr Used [ajint] Use count, saved for a possible diagnostic message to
631 **                    catch ACD items declared and never referenced by the
632 **                    calling program.
633 ** @attr RefPassed [ajint] Enumerated value for reference 0= not passed,
634 **                         1= values only passed,
635 **                         2= values and reference passed
636 ** @attr LineNum [ajint] Source file line number of definition start,
637 **                       saved for use in diagnostic messages
638 ** @attr SAttr [ajint] Number of calculated attributes for this ACD type
639 ** @attr Assoc [AjBool] ajTrue if this is an associated qualifier, listed
640 **                      in the AssocQuals structure of another ACD item
641 ** @attr AssocQuals [struct AcdSAcd*] Associated qualifiers list, or
642 **                                    NULL if there are none for this ACD type
643 ** @attr StdPrompt [AjPStr] Standard prompt set for some types by
644 **                          an acdPrompt function
645 ** @attr OrigStr [AjPStr] Original string saved for later processing
646 ** @attr ValStr [AjPStr] Value as a string for printing
647 ** @attr Value [void*] Value as a pointer to the native object to be
648 **                     returned by an ajAcdGet function call
649 ** @@
650 ******************************************************************************/
651 
652 typedef struct AcdSAcd
653 {
654     struct AcdSAcd* Next;
655     AjPStr Name;
656     AjPStr Token;
657     ajint PNum;
658     AcdELevel Level;
659     ajint Type;
660     ajint NAttr;
661     AjPStr* AttrStr;
662     AcdPAttr SetAttr;
663     AjPPStr SetStr;
664     AjPPStr DefStr;
665     AjBool Defined;
666     AjBool UserDefined;
667     AjBool UserSetNull;
668     ajint Used;
669     ajint RefPassed;
670     ajint LineNum;
671     ajint SAttr;
672     AjBool Assoc;
673     struct AcdSAcd* AssocQuals;
674     AjPStr StdPrompt;
675     AjPStr OrigStr;
676     AjPStr ValStr;
677     void* Value;
678 } AcdOAcd;
679 #define AcdPAcd AcdOAcd*
680 
681 
682 
683 
684 /* @datastatic AcdPSection ****************************************************
685 **
686 ** ACD section definition
687 **
688 ** @alias AcdSSection
689 ** @alias AcdOSection
690 **
691 ** @attr Name [const char*] Section name
692 ** @attr Description [const char*] Section description
693 ** @attr Type [const char*] Section type "page"
694 ** @@
695 ******************************************************************************/
696 
697 typedef struct AcdSSection
698 {
699     const char* Name;
700     const char* Description;
701     const char* Type;
702 } AcdOSection;
703 #define AcdPSection AcdOSection*
704 
705 
706 
707 
708 AcdOSection acdSecInput[] =
709 {
710     {"input", "Input section", "page"},
711     {NULL, NULL, NULL}
712 };
713 
714 
715 AcdOSection acdSecRequired[] =
716 {
717     {"required", "Required section", "page"},
718     {NULL, NULL, NULL}
719 };
720 
721 
722 AcdOSection acdSecAdditional[] =
723 {
724     {"additional", "Additional section", "page"},
725     {NULL, NULL, NULL}
726 };
727 
728 
729 AcdOSection acdSecAdvanced[] =
730 {
731     {"advanced", "Advanced section", "page"},
732     {NULL, NULL, NULL}
733 };
734 
735 
736 AcdOSection acdSecOutput[] =
737 {
738     {"output", "Output section", "page"},
739     {NULL, NULL, NULL}
740 };
741 
742 
743 AcdPSection acdSections[] =
744 {
745     acdSecInput,
746     acdSecRequired,
747     acdSecAdditional,
748     acdSecAdvanced,
749     acdSecOutput,
750     NULL
751 };
752 
753 
754 
755 
756 /* @datastatic AcdPType *******************************************************
757 **
758 ** ACD data type structure
759 **
760 ** @alias AcdSType
761 ** @alias AcdOType
762 **
763 ** @attr Name [const char*] Attribute type name
764 ** @attr Group [const char*] Attribute group name
765 ** @attr Section [AcdPSection] Expected section
766 ** @attr Attr [AcdPAttr] Type-specific attributes
767 ** @attr Quals [AcdPQual] Type-specific associated qualifiers
768 ** @attr TypeSet [void function] Function to set value and prompt user
769 ** @attr HelpSet [void function] Function to set help text
770 ** @attr TypeDel [void function] Function to delete value
771 ** @attr PassByRef [AjBool] Pass by reference - so caller owns the object
772 ** @attr Stdprompt [AjBool] Expect a standard prompt
773 ** @attr Prompt [const AjPStr function] Function to set standard prompt
774 ** @attr UseCount [ajint*] Number of times this type has been used
775 ** @attr UseClassCount [ajint*] Number of times this class of types
776 **                              has been used
777 ** @attr Valid [const char*] Valid data help message and description for
778 **                     documentation
779 ** @@
780 ******************************************************************************/
781 
782 typedef struct AcdSType
783 {
784     const char* Name;
785     const char* Group;
786     AcdPSection Section;
787     AcdPAttr Attr;
788     AcdPQual Quals;
789     void (*TypeSet)(AcdPAcd thys);
790     void (*HelpSet)(const AcdPAcd thys, AjPStr* msg);
791     void (*TypeDel)(void**);
792     AjBool PassByRef;
793     AjBool Stdprompt;
794     const AjPStr (*Prompt)(AcdPAcd thys);
795     ajint* UseCount;
796     ajint* UseClassCount;
797     const char* Valid;
798 } AcdOType;
799 #define AcdPType AcdOType*
800 
801 static AjBool* acdParamSet;
802 
803 static AcdPAcd acdNewCurr = NULL;
804 static AcdPAcd acdApplAcd = NULL;
805 static AcdPAcd acdMasterQual = NULL;
806 
807 /*
808 AcdOAcd acdList = {NULL, NULL, NULL, 0, ACD_APPL, 0, 0, NULL, 0, NULL,
809 		   NULL, NULL, NULL, 0, 0, NULL, NULL, NULL};
810 */
811 
812 static AcdPAcd acdList = NULL;
813 static AcdPAcd acdListLast = NULL;
814 static AcdPAcd acdListCurr = NULL;
815 static AcdPAcd acdProcCurr = NULL;
816 static AcdPAcd acdSetCurr = NULL;
817 
818 static ajint acdNParam=0;
819 
820 static AjPTable acdGrpTable = NULL;
821 
822 static void      acdAmbigApp(AjPStr* pambiglist, const AjPStr str);
823 static void      acdAmbigAppC(AjPStr* pambiglist, const char* txt);
824 static void      acdArgsParse(ajint argc, char * const argv[]);
825 static void      acdArgsScan(ajint argc, char * const argv[]);
826 static ajint     acdAttrCount(ajint itype);
827 static ajint     acdAttrKeyCount(ajint ikey);
828 static ajint     acdAttrListCount(const AcdPAttr attr);
829 static AjBool    acdAttrResolve(const AcdPAcd thys, const char *attr,
830 				AjPStr *result);
831 static AjBool    acdAttrToBool(const AcdPAcd thys,
832 			       const char *attr, AjBool defval,
833 			       AjBool *result);
834 static AjBool    acdAttrToBoolTest(const AcdPAcd thys,
835 				   const char *attr, AjBool defval,
836 				   AjBool *result);
837 static AjBool    acdAttrToDouble(const AcdPAcd thys,
838                                  const char *attr, double defval,
839                                  double *result);
840 static AjBool    acdAttrToFloat(const AcdPAcd thys,
841 				const char *attr, float defval,
842 				float *result);
843 static AjBool    acdAttrTest(const AcdPAcd thys, const char *attrib);
844 static AjBool    acdAttrTestDefined(const AcdPAcd thys, const char *attrib);
845 static AjBool    acdAttrTestValue(const AcdPAcd thys,const  char *attrib);
846 static AjBool    acdAttrToChar(const AcdPAcd thys,
847 			       const char *attr, char defval, char *result);
848 static AjBool    acdAttrToInt(const AcdPAcd thys,
849 			      const char *attr, ajint defval, ajint *result);
850 static AjBool    acdAttrToLong(const AcdPAcd thys,
851                                const char *attr, ajlong defval, ajlong *result);
852 static AjBool    acdAttrToStr(const AcdPAcd thys,
853 			      const char *attr, const char* defval,
854 			      AjPStr *result);
855 static AjBool    acdAttrToUint(const AcdPAcd thys,
856 			      const char *attr, ajuint defval, ajuint *result);
857 static const AjPStr acdAttrValue(const AcdPAcd thys, const char *attrib);
858 static AjBool    acdAttrValueStr(const AcdPAcd thys,
859 				 const char *attrib, const char* def,
860 				 AjPStr *str);
861 static void      acdBadRetry(const AcdPAcd thys);
862 static void      acdBadVal(const AcdPAcd thys, AjBool required,
863 			   const char *fmt, ...);
864 static AjBool    acdCodeDef(const AcdPAcd thys, AjPStr *msg);
865 static AjBool    acdCodeGet(const AjPStr code, AjPStr *msg);
866 static void      acdCodeInit(void);
867 static ajint     acdCountType(const char* type);
868 static AjBool    acdDataFilename(AjPStr* datafname,
869 				 const AjPStr name, const AjPStr ext,
870 				 AjBool nullok);
871 static AjBool    acdDef(AcdPAcd thys, const AjPStr value);
872 static void      acdDel(AcdPAcd *Pacd);
873 static AjBool    acdDefinedEmpty (const AcdPAcd thys);
874 static const AjPStr acdEdamTest(const AjPStr relation);
875 
876 __noreturn static void      acdError(const char* fmt, ...);
877 __noreturn static void      acdErrorAcd(const AcdPAcd thys,
878 					const char* fmt, ...);
879 
880 /* expression processing */
881 
882 static AjBool    acdExpPlus(AjPStr* result, const AjPStr str);
883 static AjBool    acdExpMinus(AjPStr* result, const AjPStr str);
884 static AjBool    acdExpStar(AjPStr* result, const AjPStr str);
885 static AjBool    acdExpDiv(AjPStr* result, const AjPStr str);
886 static AjBool    acdExpNot(AjPStr* result, const AjPStr str);
887 static AjBool    acdExpEqual(AjPStr* result, const AjPStr str);
888 static AjBool    acdExpNotEqual(AjPStr* result, const AjPStr str);
889 static AjBool    acdExpGreater(AjPStr* result, const AjPStr str);
890 static AjBool    acdExpLesser(AjPStr* result, const AjPStr str);
891 static AjBool    acdExpAnd(AjPStr* result, const AjPStr str);
892 static AjBool    acdExpOr(AjPStr* result, const AjPStr str);
893 static AjBool    acdExpCond(AjPStr* result, const AjPStr str);
894 static AjBool    acdExpOneof(AjPStr* result, const AjPStr str);
895 static AjBool    acdExpCase(AjPStr* result, const AjPStr str);
896 static AjBool    acdExpFilename(AjPStr* result, const AjPStr str);
897 static AjBool    acdExpExists(AjPStr* result, const AjPStr str);
898 static AjBool    acdExpValue(AjPStr* result, const AjPStr str);
899 
900 static AcdPAcd   acdFindAcd(const AjPStr name, const AjPStr token);
901 static AcdPAcd   acdFindAcdTest(const AjPStr name, const AjPStr token);
902 static AcdPAcd   acdFindAssoc(const AcdPAcd thys,
903 			      const AjPStr name, const AjPStr altname);
904 static ajint     acdFindAttr(const AcdPAttr attr, const AjPStr attrib);
905 static ajint     acdFindAttrC(const AcdPAttr attr, const char* attrib);
906 static AcdPAcd   acdFindItem(const AjPStr item, ajint number);
907 static ajint     acdFindKeyC(const char* key);
908 static AcdPAcd   acdFindParam(ajint PNum);
909 static AcdPAcd   acdFindQual(AjPStr* pqual);
910 static AcdPAcd   acdFindQualAssoc(const AcdPAcd pa, const AjPStr qual,
911 				  const AjPStr noqual,
912 				  const AjPStr master, ajint PNum);
913 static AcdPAcd   acdFindQualDetail(const AjPStr qual, const AjPStr noqual,
914 				   const AjPStr master,
915 				   ajint PNum, ajint *iparam);
916 static AcdPAcd   acdFindQualMaster(const AjPStr qual, const AjPStr noqual,
917 				   const AjPStr master,
918 				   ajint PNum);
919 static ajint     acdFindType(const AjPStr type);
920 static ajint     acdFindTypeC(const char* type);
921 static void      acdFree(void** PPval);
922 static AjBool    acdFunResolve(AjPStr* result, const AjPStr str);
923 static AjBool    acdGetAttr(AjPStr* result, const AjPStr name,
924 			    const AjPStr attrib);
925 static void*     acdGetValue(const char *token, const char* type);
926 static void*     acdGetValueRef(const char *token, const char* type);
927 static void*     acdGetValueSingle(const char *token, const char* type);
928 static AjBool    acdGetValueAssoc(const AcdPAcd thys, const char *token,
929 				  AjPStr *result);
930 static AjBool    acdGetValueAssocDefault(const AcdPAcd thys, const char *token,
931                                          AjPStr *result);
932 static void*     acdGetValueNumC(const char *token, const char* type,
933 				ajint pnum, AjBool passbyref);
934 static void*     acdGetValueNumS(const AjPStr token, const char* type,
935 				ajint pnum, AjBool passbyref);
936 static const AjPStr acdGetValDefault(const char *token);
937 static const AjPStr acdGetValStr(const char *token);
938 static void      acdHelp(void);
939 static void      acdHelpAppend(const AcdPAcd thys, AjPStr* str, char flag);
940 static void      acdHelpAssoc(const AcdPAcd thys, AjPStr *str,
941 			      const char *name);
942 static void      acdHelpAssocTable(const AcdPAcd thys, AjPList tablist);
943 static AjBool    acdHelpCodeDef(const AcdPAcd thys, AjPStr *msg);
944 static void      acdHelpExpect(const AcdPAcd thys, AjBool table, AjPStr *str);
945 static void      acdHelpGalaxy(AcdPAcd thys, AjPList tablist);
946 static void      acdHelpGalaxyShow(const AjPList inlist, const AjPList outlist);
947 static void      acdHelpShow(const AjPStr str, const char* title);
948 static void      acdHelpTable(const AcdPAcd thys, AjPList tablist);
949 static void      acdHelpTableShow(const AjPList tablist, const char* title);
950 static void      acdHelpText(const AcdPAcd thys, AjPStr* msg);
951 static void      acdHelpValid(const AcdPAcd thys, AjBool table, AjPStr *str);
952 static AjBool    acdHelpVarResolve(AjPStr* str, const AjPStr src);
953 static void      acdHelpXsd(const AcdPAcd thys, AjPList tablist);
954 static void      acdHelpXsdShow(const AjPList inlist, const AjPList outlist);
955 static AjBool    acdInFilename(AjPStr* infname);
956 static AjBool    acdInFileSave(const AjPStr infname, const AjPStr seqname,
957                                AjBool reset);
958 static AjBool    acdInTypeFeat(AjPStr* intype);
959 static AjBool    acdInTypeFeatSave(const AjPStr intype);
960 static AjBool    acdInTypeFeatSaveC(const char* intype);
961 static AjBool    acdInTypeSeq(AjPStr* intype);
962 static AjBool    acdInTypeSeqSave(const AjPStr intype);
963 static AjBool    acdIsLeftB(AjPList listwords);
964 static AjBool    acdIsAtype(const AcdPAcd thys);
965 static AjBool    acdIsParam(const char* arg, AjPStr* param, ajint* iparam,
966 			    AcdPAcd* acd);
967 static AjBool    acdIsParamValue(const AjPStr pval);
968 static ajint     acdIsQual(const char* arg, const char* arg2, ajint *iparam,
969 			   AjPStr *pqual, AjPStr *pnoqual, AjPStr *pvalue,
970 			   ajint* number, AjPStr *pmaster, AcdPAcd* acd);
971 static AjBool    acdIsQtype(const AcdPAcd thys);
972 static AjBool    acdIsRequired(const AcdPAcd thys);
973 static AjBool    acdIsRightB(AjPStr* pstr, AjPList listwords);
974 static AjBool    acdIsStype(const AcdPAcd thys);
975 static AjBool    acdIsVtype(const AcdPAcd thys);
976 static const AjPStr acdKnowntypeDesc(const AcdPAcd thys);
977 static void      acdKnowntypeInit(void);
978 static void      acdListAttr(const AcdPAttr attr, const AjPPStr valstr,
979 			     ajint nattr);
980 static void      acdListPrompt(const AcdPAcd thys);
981 static void      acdListReport(const char *title);
982 static AjPStr*   acdListValue(const AcdPAcd thys, ajint min, ajint max,
983 			      const AjPStr reply);
984 static void      acdLog(const char *fmt, ...);
985 static AcdPAcd   acdNewAcd(const AjPStr name, const AjPStr token,
986 			   ajint itype);
987 static AcdPAcd   acdNewAcdKey(const AjPStr name, const AjPStr token,
988 			      ajint ikey);
989 static AcdPAcd   acdNewAppl(const AjPStr name);
990 static AcdPAcd   acdNewEndsec(const AjPStr name);
991 static AcdPAcd   acdNewQual(const AjPStr name, const AjPStr token,
992 			    AjPStr* type);
993 static AcdPAcd   acdNewQualQual(const AjPStr name, AjPStr* type);
994 static AcdPAcd   acdNewRel(const AjPStr name);
995 static AcdPAcd   acdNewSec(const AjPStr name);
996 static AcdPAcd   acdNewVar(const AjPStr name);
997 static ajint     acdNextParam(ajint pnum);
998 static AjBool    acdNotLeftB(const AjPList listwords);
999 static AjBool    acdOutDirectory(AjPStr* outdir);
1000 static AjBool    acdOutFilename(AjPStr* outfname, const AjPStr name,
1001 				const AjPStr ext);
1002 static AjBool    acdOutFormatCpdb(const AjPStr format, ajint* iformat);
1003 static AjBool    acdOutFormatData(const AjPStr format, ajint* iformat);
1004 static AjBool    acdOutFormatDiscrete(const AjPStr format, ajint* iformat);
1005 static AjBool    acdOutFormatDistance(const AjPStr format, ajint* iformat);
1006 static AjBool    acdOutFormatFreq(const AjPStr format, ajint* iformat);
1007 static AjBool    acdOutFormatMatrix(const AjPStr forma, ajint* iformatt);
1008 static AjBool    acdOutFormatMatrixf(const AjPStr format, ajint* iformat);
1009 static AjBool    acdOutFormatProperties(const AjPStr format, ajint* iformat);
1010 static AjBool    acdOutFormatScop(const AjPStr format, ajint* iformat);
1011 static AjBool    acdOutFormatTree(const AjPStr format, ajint* iformat);
1012 static void      acdParse(AjPList listwords, AjPList listcount);
1013 static void      acdParseAlpha(AjPList listwords, AjPStr* pword);
1014 static void      acdParseAttributes(const AcdPAcd acd,
1015 				    AjPList listwords);
1016 static void      acdParseName(AjPList listwords, AjPStr* pword);
1017 static AjPStr    acdParseValue(AjPList listwords);
1018 static void      acdPretty(const char *fmt, ...);
1019 static void      acdPrettyClose(void);
1020 static void      acdPrettyComment(const AjPStr comment);
1021 static void      acdPrettyShift(void);
1022 static void      acdPrettyWrap(ajint left, const char *fmt, ...);
1023 static void      acdPrettyUnShift(void);
1024 static void      acdPrintCalcattr(AjPFile outf, const char* acdtype,
1025 				  const AcdOAttr calcattr[]);
1026 static void      acdPrintUsed(void);
1027 static void      acdProcess(void);
1028 static const AjPStr acdPromptAlign(AcdPAcd thys);
1029 static const AjPStr acdPromptAssembly(AcdPAcd thys);
1030 static const AjPStr acdPromptCodon(AcdPAcd thys);
1031 static const AjPStr acdPromptCpdb(AcdPAcd thys);
1032 static const AjPStr acdPromptDatafile(AcdPAcd thys);
1033 static const AjPStr acdPromptDirectory(AcdPAcd thys);
1034 static const AjPStr acdPromptDirlist(AcdPAcd thys);
1035 static const AjPStr acdPromptDiscretestates(AcdPAcd thys);
1036 static const AjPStr acdPromptDistances(AcdPAcd thys);
1037 static const AjPStr acdPromptFeatout(AcdPAcd thys);
1038 static const AjPStr acdPromptFeatures(AcdPAcd thys);
1039 static const AjPStr acdPromptFilelist(AcdPAcd thys);
1040 static const AjPStr acdPromptFrequencies(AcdPAcd thys);
1041 static const AjPStr acdPromptGraph(AcdPAcd thys);
1042 static const AjPStr acdPromptInfile(AcdPAcd thys);
1043 static const AjPStr acdPromptMatrix(AcdPAcd thys);
1044 static const AjPStr acdPromptObo(AcdPAcd thys);
1045 static const AjPStr acdPromptOutassembly(AcdPAcd thys);
1046 static const AjPStr acdPromptOutcodon(AcdPAcd thys);
1047 static const AjPStr acdPromptOutcpdb(AcdPAcd thys);
1048 static const AjPStr acdPromptOutdata(AcdPAcd thys);
1049 static const AjPStr acdPromptOutdir(AcdPAcd thys);
1050 static const AjPStr acdPromptOutdiscrete(AcdPAcd thys);
1051 static const AjPStr acdPromptOutdistance(AcdPAcd thys);
1052 static const AjPStr acdPromptOutfile(AcdPAcd thys);
1053 static const AjPStr acdPromptOutfreq(AcdPAcd thys);
1054 static const AjPStr acdPromptOutmatrix(AcdPAcd thys);
1055 static const AjPStr acdPromptOutobo(AcdPAcd thys);
1056 static const AjPStr acdPromptOutproperties(AcdPAcd thys);
1057 static const AjPStr acdPromptOutrefseq(AcdPAcd thys);
1058 static const AjPStr acdPromptOutresource(AcdPAcd thys);
1059 static const AjPStr acdPromptOutscop(AcdPAcd thys);
1060 static const AjPStr acdPromptOuttaxon(AcdPAcd thys);
1061 static const AjPStr acdPromptOuttext(AcdPAcd thys);
1062 static const AjPStr acdPromptOuttree(AcdPAcd thys);
1063 static const AjPStr acdPromptOuturl(AcdPAcd thys);
1064 static const AjPStr acdPromptOutvariation(AcdPAcd thys);
1065 static const AjPStr acdPromptOutxml(AcdPAcd thys);
1066 static const AjPStr acdPromptPattern(AcdPAcd thys);
1067 static const AjPStr acdPromptProperties(AcdPAcd thys);
1068 static const AjPStr acdPromptRefseq(AcdPAcd thys);
1069 static const AjPStr acdPromptRegexp(AcdPAcd thys);
1070 static const AjPStr acdPromptReport(AcdPAcd thys);
1071 static const AjPStr acdPromptResource(AcdPAcd thys);
1072 static const AjPStr acdPromptScop(AcdPAcd thys);
1073 static const AjPStr acdPromptSeq(AcdPAcd thys);
1074 static const AjPStr acdPromptSeqout(AcdPAcd thys);
1075 static void         acdPromptStandard(AcdPAcd thys, const char* type,
1076 				   ajint* count);
1077 static void         acdPromptStandardS(AcdPAcd thys, const AjPStr str);
1078 static void         acdPromptStandardAlt(AcdPAcd thys, const char* firsttype,
1079 				      const char* type, ajint* count);
1080 static void         acdPromptStandardAppend(AcdPAcd thys, const char* str);
1081 static const AjPStr acdPromptTaxon(AcdPAcd thys);
1082 static const AjPStr acdPromptText(AcdPAcd thys);
1083 static const AjPStr acdPromptTree(AcdPAcd thys);
1084 static const AjPStr acdPromptUrl(AcdPAcd thys);
1085 static const AjPStr acdPromptVariation(AcdPAcd thys);
1086 static const AjPStr acdPromptXml(AcdPAcd thys);
1087 static void      acdQualParse(AjPStr* pqual, AjPStr* pnoqual,
1088 			      AjPStr* pqmaster, ajint* number);
1089 static AjBool    acdQualToBool(const AcdPAcd thys, const char *qual,
1090 			       AjBool defval, AjBool *result, AjPStr* valstr);
1091 static AjBool    acdQualToFloat(const AcdPAcd thys, const char *qual,
1092  				float defval, ajint precision,
1093 				float *result, AjPStr* valstr);
1094 static AjBool    acdQualToInt(const AcdPAcd thys, const char *qual,
1095 			      ajint defval, ajint *result, AjPStr* valstr);
1096 static AjBool    acdQualToLong(const AcdPAcd thys, const char *qual,
1097                                ajlong defval, ajlong *result, AjPStr* valstr);
1098 static AjBool    acdQualToSeqbegin(const AcdPAcd thys, const char *qual,
1099 				   ajint defval, ajint *result,
1100 				   AjPStr* valstr);
1101 static AjBool    acdQualToSeqend(const AcdPAcd thys, const char *qual,
1102 				 ajint defval, ajint *result,
1103 				 AjPStr* valstr);
1104 static AjBool     acdRangeTestCalc(const AcdPAcd thys);
1105 static AjPTable  acdReadGroups(void);
1106 static AjPTable  acdReadKeywords(void);
1107 static void      acdReadKnowntype(AjPTable* desctable, AjPTable* infotable);
1108 static void      acdReadSections(AjPTable* typetable, AjPTable* infotable);
1109 static void      acdRegVarDefine(void);
1110 static AjBool    acdReplyInitC(const AcdPAcd thys,
1111                                const char *defval, AjPStr* reply);
1112 static AjBool    acdReplyInitS(const AcdPAcd thys,
1113                                const AjPStr defval, AjPStr* reply);
1114 static void      acdReset(void);
1115 static AjBool    acdSet(const AcdPAcd thys, AjPStr* attrib,
1116 			const AjPStr value);
1117 static void      acdSetAll(void);
1118 static AjBool    acdSetDef(AcdPAcd thys, const AjPStr value);
1119 static AjBool    acdSetDefC(AcdPAcd thys, const char* value);
1120 static AjPOutfile acdSetOutType(AcdPAcd thys, const char* type);
1121 static AjBool    acdSetQualAppl(const AcdPAcd thys, AjBool val);
1122 static AjBool    acdSetQualDefBool(AcdPAcd thys,
1123 				   const char* name, AjBool value);
1124 static AjBool    acdSetQualDefInt(AcdPAcd thys,
1125 				  const char* name, ajint value);
1126 static AjBool    acdSetKey(const AcdPAcd thys, AjPStr* attrib,
1127 			   const AjPStr value);
1128 static AjBool    acdSetVarDef(AcdPAcd thys, const AjPStr value);
1129 static void      acdSelectPrompt(const AcdPAcd thys);
1130 static AjPStr*   acdSelectValue(const AcdPAcd thys, ajint min, ajint max,
1131 				const AjPStr reply);
1132 static AcdEStage acdStage(const AjPStr token);
1133 static AcdPAcd   acdTestAssoc(const AcdPAcd thys,
1134 			      const AjPStr name, const AjPStr altname);
1135 static void      acdTestAssocUnknown(const AjPStr name);
1136 static AjBool    acdTestQualC(const char *name);
1137 static void      acdTestUnknown(const AjPStr name, const AjPStr alias);
1138 static AjBool    acdTextFormat(AjPStr* text);
1139 static void      acdTextTrim(AjPStr* text);
1140 static void      acdTokenToLowerS(AjPStr *token, ajint* number);
1141 static AjBool    acdUserGet(AcdPAcd thys, AjPStr* reply);
1142 static AjBool    acdUserGetPrompt(const AcdPAcd thys, const char* assocqual,
1143 				  const char* prompt, AjPStr* reply);
1144 static void      acdUserSavereply(const AcdPAcd thys, const char* assocqual,
1145 				  AjBool userset, const AjPStr reply);
1146 static void      acdValidAppl(const AcdPAcd thys);
1147 static void      acdValidApplGroup(const AjPStr groups);
1148 static void      acdValidApplKeywords(const AjPStr groups);
1149 static void      acdValidKnowntype(const AcdPAcd thys);
1150 static void      acdValidRelation(const AcdPAcd thys);
1151 static void      acdValidSection(const AcdPAcd thys);
1152 static void      acdValidSectionFull(AjPStr* secname);
1153 static AjBool    acdValidSectionMatch(const char* secname);
1154 static void      acdValidQual(AcdPAcd thys);
1155 static AjBool    acdValIsBool(const char* arg);
1156 static AjBool    acdVarResolve(AjPStr* str);
1157 static AjBool    acdVarSimple(const AjPStr var, AjPStr* varname);
1158 static AjBool    acdVarSimpleResolve(const AjPStr var, AjPStr* newvar);
1159 static AjBool    acdVarSplit(const AjPStr var, AjPStr* name, AjPStr* attrname);
1160 static AjBool    acdVarTest(const AjPStr var);
1161 static AjBool    acdVarTestValid(const AjPStr var, AjBool* toggle);
1162 static AjBool    acdVocabCheck(const AjPStr str, const char** vocab);
1163 static void      acdWarn(const char* fmt, ...);
1164 static void      acdWarnObsolete(const AjPStr str);
1165 static AjBool    acdWordNext(AjPList listwords, AjPStr* pword);
1166 static AjBool    acdWordNextLower(AjPList listwords, AjPStr* pword);
1167 static AjBool    acdWordNextName(AjPList listwords, AjPStr* pword);
1168 
1169 
1170 
1171 
1172 /* @datastatic AcdPExpList ****************************************************
1173 **
1174 ** Exression list structure for named expressions @plus etc.
1175 **
1176 ** @alias AcdSExpList
1177 ** @alias AcdOExpList
1178 **
1179 ** @attr Name [const char*] Expression name
1180 ** @attr Func [AjBool function] Function to evaluate expression
1181 ** @@
1182 ******************************************************************************/
1183 
1184 typedef struct AcdSExpList
1185 {
1186     const char* Name;
1187     AjBool (*Func) (AjPStr *result, const AjPStr str);
1188 } AcdOExpList;
1189 #define AcdPExpList AcdOExpList*
1190 
1191 
1192 
1193 
1194 /* @funclist acdExpList *******************************************************
1195 **
1196 ** Functions for processing expressions in ACD dependencies
1197 **
1198 ******************************************************************************/
1199 
1200 static AcdOExpList explist[] =
1201 {
1202     {"plus", &acdExpPlus},
1203     {"minus", &acdExpMinus},
1204     {"star", &acdExpStar},
1205     {"div", &acdExpDiv},
1206     {"not", &acdExpNot},
1207     {"equal", &acdExpEqual},
1208     {"notequal", &acdExpNotEqual},
1209     {"greater", &acdExpGreater},
1210     {"lesser", &acdExpLesser},
1211     {"or", &acdExpOr},
1212     {"and", &acdExpAnd},
1213     {"cond", &acdExpCond},
1214     {"oneof", &acdExpOneof},
1215     {"case", &acdExpCase},
1216     {"filename", &acdExpFilename},
1217     {"exists", &acdExpExists},
1218     {"value", &acdExpValue},
1219     {NULL, NULL}
1220 };
1221 
1222 
1223 
1224 
1225 /* Dummy model routine for new data types - but these must not be static
1226    and will be defined in ajacd.h instead */
1227 
1228 /*static void*  ajAcdGetXxxx (const char *token);*/
1229 
1230 static void acdHelpExpectCodon(const AcdPAcd thys, AjBool table, AjPStr* str);
1231 static void acdHelpExpectDirlist(const AcdPAcd thys, AjBool table,
1232 				 AjPStr* str);
1233 static void acdHelpExpectData(const AcdPAcd thys, AjBool table, AjPStr* str);
1234 static void acdHelpExpectFeatout(const AcdPAcd thys, AjBool table,
1235 				 AjPStr* str);
1236 static void acdHelpExpectFeatures(const AcdPAcd thys, AjBool table,
1237                                   AjPStr* str);
1238 static void acdHelpExpectFilelist(const AcdPAcd thys, AjBool table,
1239 				  AjPStr* str);
1240 static void acdHelpExpectFloat(const AcdPAcd thys, AjBool table, AjPStr* str);
1241 static void acdHelpExpectGraph(const AcdPAcd thys, AjBool table, AjPStr* str);
1242 static void acdHelpExpectIn(const AcdPAcd thys, AjBool table, AjPStr* str);
1243 static void acdHelpExpectInt(const AcdPAcd thys, AjBool table, AjPStr* str);
1244 static void acdHelpExpectMatrix(const AcdPAcd thys, AjBool table, AjPStr* str);
1245 static void acdHelpExpectOut(const AcdPAcd thys, AjBool table, AjPStr* str);
1246 static void acdHelpExpectRange(const AcdPAcd thys, AjBool table, AjPStr* str);
1247 static void acdHelpExpectRegexp(const AcdPAcd thys, AjBool table, AjPStr* str);
1248 static void acdHelpExpectSeq(const AcdPAcd thys, AjBool table, AjPStr* str);
1249 static void acdHelpExpectSeqout(const AcdPAcd thys, AjBool table, AjPStr* str);
1250 static void acdHelpExpectString(const AcdPAcd thys, AjBool table, AjPStr* str);
1251 
1252 static void acdHelpTextObo(const AcdPAcd thys, AjPStr* str);
1253 static void acdHelpTextResource(const AcdPAcd thys, AjPStr* str);
1254 static void acdHelpTextSeq(const AcdPAcd thys, AjPStr* str);
1255 static void acdHelpTextSeqout(const AcdPAcd thys, AjPStr* str);
1256 static void acdHelpTextTaxon(const AcdPAcd thys, AjPStr* str);
1257 static void acdHelpTextText(const AcdPAcd thys, AjPStr* str);
1258 static void acdHelpTextUrl(const AcdPAcd thys, AjPStr* str);
1259 static void acdHelpTextVariation(const AcdPAcd thys, AjPStr* str);
1260 static void acdHelpTextXml(const AcdPAcd thys, AjPStr* str);
1261 
1262 static void acdHelpValidAlign(const AcdPAcd thys, AjBool table, AjPStr* str);
1263 static void acdHelpValidCodon(const AcdPAcd thys, AjBool table, AjPStr* str);
1264 static void acdHelpValidDirlist(const AcdPAcd thys, AjBool table, AjPStr* str);
1265 static void acdHelpValidData(const AcdPAcd thys, AjBool table, AjPStr* str);
1266 static void acdHelpValidFeatout(const AcdPAcd thys, AjBool table, AjPStr* str);
1267 static void acdHelpValidFeatures(const AcdPAcd thys, AjBool table, AjPStr* str);
1268 static void acdHelpValidFilelist(const AcdPAcd thys, AjBool table,
1269 				 AjPStr* str);
1270 static void acdHelpValidFloat(const AcdPAcd thys, AjBool table, AjPStr* str);
1271 static void acdHelpValidGraph(const AcdPAcd thys, AjBool table, AjPStr* str);
1272 static void acdHelpValidIn(const AcdPAcd thys, AjBool table, AjPStr* str);
1273 static void acdHelpValidInt(const AcdPAcd thys, AjBool table, AjPStr* str);
1274 static void acdHelpValidList(const AcdPAcd thys, AjBool table, AjPStr* str);
1275 static void acdHelpValidMatrix(const AcdPAcd thys, AjBool table, AjPStr* str);
1276 static void acdHelpValidOut(const AcdPAcd thys, AjBool table, AjPStr* str);
1277 static void acdHelpValidRange(const AcdPAcd thys, AjBool table, AjPStr* str);
1278 static void acdHelpValidRegexp(const AcdPAcd thys, AjBool table, AjPStr* str);
1279 static void acdHelpValidReport(const AcdPAcd thys, AjBool table, AjPStr* str);
1280 static void acdHelpValidSelect(const AcdPAcd thys, AjBool table, AjPStr* str);
1281 static void acdHelpValidSeq(const AcdPAcd thys, AjBool table, AjPStr* str);
1282 static void acdHelpValidSeqout(const AcdPAcd thys, AjBool table, AjPStr* str);
1283 static void acdHelpValidString(const AcdPAcd thys, AjBool table, AjPStr* str);
1284 
1285 static AjBool acdKnownValueList(const AcdPAcd thys, AjPStr* value);
1286 static AjBool acdKnownValueSelect(const AcdPAcd thys, AjPStr* value);
1287 static AjBool acdResourceList(const AcdPAcd thys,
1288 			      const AjPStr list, AjPStr* value);
1289 
1290 /* Type-specific routines to prompt user and set the value.  each new
1291 ** type requires one of these routines */
1292 
1293 static void acdDelAlign(void** PPval);
1294 static void acdDelAssembly(void** PPval);
1295 static void acdDelCod(void** PPval);
1296 static void acdDelDir(void** PPval);
1297 static void acdDelDirout(void** PPval);
1298 static void acdDelFeattabOut(void** PPval);
1299 static void acdDelFeattable(void** PPval);
1300 static void acdDelFile(void** PPval);
1301 static void acdDelFloat(void** PPval);
1302 static void acdDelList(void** PPval);
1303 static void acdDelMatrix(void** PPval);
1304 static void acdDelMatrixf(void** PPval);
1305 static void acdDelObo(void** PPval);
1306 static void acdDelOutfile(void** PPval);
1307 static void acdDelPatlist(void** PPval);
1308 static void acdDelPhyloDist(void** PPval);
1309 static void acdDelPhyloFreq(void** PPval);
1310 static void acdDelPhyloProp(void** PPval);
1311 static void acdDelPhyloState(void** PPval);
1312 static void acdDelPhyloTree(void** PPval);
1313 static void acdDelRange(void** PPval);
1314 static void acdDelRefseq(void** PPval);
1315 static void acdDelReg(void** PPval);
1316 static void acdDelReport(void** PPval);
1317 static void acdDelResource(void** PPval);
1318 static void acdDelSeq(void** PPval);
1319 static void acdDelSeqall(void** PPval);
1320 static void acdDelSeqout(void** PPval);
1321 static void acdDelSeqset(void** PPval);
1322 static void acdDelSeqsetArray(void** PPval);
1323 static void acdDelStr(void** PPval);
1324 static void acdDelStrArray(void** PPval);
1325 static void acdDelTaxon(void** PPval);
1326 static void acdDelText(void** PPval);
1327 static void acdDelUrl(void** PPval);
1328 static void acdDelVariation(void** PPval);
1329 static void acdDelXml(void** PPval);
1330 
1331 static void acdSetXxxx(AcdPAcd thys);
1332 static void acdSetAppl(AcdPAcd thys);
1333 static void acdSetEndsec(AcdPAcd thys);
1334 static void acdSetRel(AcdPAcd thys);
1335 static void acdSetSec(AcdPAcd thys);
1336 static void acdSetVar(AcdPAcd thys);
1337 static void acdSetAlign(AcdPAcd thys);
1338 static void acdSetArray(AcdPAcd thys);
1339 static void acdSetAssembly(AcdPAcd thys);
1340 static void acdSetBoolean(AcdPAcd thys);
1341 static void acdSetCodon(AcdPAcd thys);
1342 static void acdSetCpdb(AcdPAcd thys);
1343 static void acdSetDirlist(AcdPAcd thys);
1344 static void acdSetDatafile(AcdPAcd thys);
1345 static void acdSetDirectory(AcdPAcd thys);
1346 static void acdSetDiscretestates(AcdPAcd thys);
1347 static void acdSetDistances(AcdPAcd thys);
1348 static void acdSetFeatout(AcdPAcd thys);
1349 static void acdSetFeatures(AcdPAcd thys);
1350 static void acdSetFilelist(AcdPAcd thys);
1351 static void acdSetFloat(AcdPAcd thys);
1352 static void acdSetFrequencies(AcdPAcd thys);
1353 static void acdSetGraph(AcdPAcd thys);
1354 static void acdSetGraphxy(AcdPAcd thys);
1355 static void acdSetInt(AcdPAcd thys);
1356 static void acdSetInfile(AcdPAcd thys);
1357 static void acdSetList(AcdPAcd thys);
1358 static void acdSetMatrix(AcdPAcd thys);
1359 static void acdSetMatrixf(AcdPAcd thys);
1360 static void acdSetObo(AcdPAcd thys);
1361 static void acdSetOutassembly(AcdPAcd thys);
1362 static void acdSetOutcodon(AcdPAcd thys);
1363 static void acdSetOutcpdb(AcdPAcd thys);
1364 static void acdSetOutdata(AcdPAcd thys);
1365 static void acdSetOutdir(AcdPAcd thys);
1366 static void acdSetOutdiscrete(AcdPAcd thys);
1367 static void acdSetOutdistance(AcdPAcd thys);
1368 static void acdSetOutfile(AcdPAcd thys);
1369 static void acdSetOutfreq(AcdPAcd thys);
1370 static void acdSetOutmatrix(AcdPAcd thys);
1371 static void acdSetOutmatrixf(AcdPAcd thys);
1372 static void acdSetOutobo(AcdPAcd thys);
1373 static void acdSetOutproperties(AcdPAcd thys);
1374 static void acdSetOutrefseq(AcdPAcd thys);
1375 static void acdSetOutresource(AcdPAcd thys);
1376 static void acdSetOutscop(AcdPAcd thys);
1377 static void acdSetOuttaxon(AcdPAcd thys);
1378 static void acdSetOuttext(AcdPAcd thys);
1379 static void acdSetOuttree(AcdPAcd thys);
1380 static void acdSetOuturl(AcdPAcd thys);
1381 static void acdSetOutvariation(AcdPAcd thys);
1382 static void acdSetOutxml(AcdPAcd thys);
1383 static void acdSetPattern(AcdPAcd thys);
1384 static void acdSetProperties(AcdPAcd thys);
1385 static void acdSetRange(AcdPAcd thys);
1386 static void acdSetRefseq(AcdPAcd thys);
1387 static void acdSetRegexp(AcdPAcd thys);
1388 /*static void acdSetRegions(AcdPAcd thys);*/
1389 static void acdSetReport(AcdPAcd thys);
1390 static void acdSetResource(AcdPAcd thys);
1391 static void acdSetScop(AcdPAcd thys);
1392 static void acdSetSelect(AcdPAcd thys);
1393 static void acdSetSeq(AcdPAcd thys);
1394 static void acdSetSeqall(AcdPAcd thys);
1395 static void acdSetSeqout(AcdPAcd thys);
1396 static void acdSetSeqoutall(AcdPAcd thys);
1397 static void acdSetSeqoutset(AcdPAcd thys);
1398 static void acdSetSeqset(AcdPAcd thys);
1399 static void acdSetSeqsetall(AcdPAcd thys);
1400 static void acdSetString(AcdPAcd thys);
1401 static void acdSetTaxon(AcdPAcd thys);
1402 static void acdSetText(AcdPAcd thys);
1403 static void acdSetToggle(AcdPAcd thys);
1404 static void acdSetTree(AcdPAcd thys);
1405 static void acdSetUrl(AcdPAcd thys);
1406 static void acdSetVariation(AcdPAcd thys);
1407 static void acdSetXml(AcdPAcd thys);
1408 
1409 /*
1410 ** Known item types
1411 **
1412 ** Each has 2 functions, used below in the definition of "types"
1413 ** The first is global, and passes the results to the application.
1414 ** The other is static and are used in command line and user management
1415 **
1416 ** The argument definition is the same for each.
1417 ** Items have a type and undefined pointers to the actual data.
1418 ** Each function knows the structure they must use, and the validations
1419 ** needed.
1420 **
1421 ** Type   ajAcdGetType : globally available. returns the value
1422 **
1423 ** ajBool acdSetType   : sets the value using the default value (if any)
1424 **
1425 */
1426 
1427 /* Default attributes available for all types */
1428 
1429 static ajint nDefAttr = 18;
1430 
1431 enum AcdEDef
1432 {
1433     DEF_DEFAULT,
1434     DEF_INFO,
1435     DEF_PROMPT,
1436     DEF_CODE,
1437     DEF_HELP,
1438     DEF_PARAMETER,
1439     DEF_STANDARD,
1440     DEF_ADDITIONAL,
1441     DEF_MISSING,
1442     DEF_VALID,
1443     DEF_EXPECTED,
1444     DEF_NEEDED,
1445     DEF_KNOWNTYPE,
1446     DEF_RELATIONS,
1447     DEF_OUTPUTMODIFIER,
1448     DEF_STYLE,
1449     DEF_QUALIFIER,
1450     DEF_TEMPLATE,
1451     DEF_COMMENT
1452 };
1453 
1454 
1455 AcdOAttr acdAttrDef[] =
1456 {
1457     {"default", VT_STR, AJFALSE, "",
1458 	 "Default value"},
1459     {"information", VT_STR, AJFALSE, "",
1460 	 "Information for menus etc., and default prompt"},
1461     {"prompt", VT_STR, AJFALSE, "",
1462 	 "Prompt (if information string is unclear)"},
1463     {"code", VT_STR, AJFALSE, "",
1464 	 "Code name for information/prompt to be looked up in standard table"},
1465     {"help", VT_STR, AJFALSE, "",
1466 	 "Text for help documentation"},
1467     {"parameter", VT_BOOL, AJFALSE, "N",
1468 	 "Command line parameter. "
1469 	     "Can be on the command line with no qualifier name. "
1470 		 "Implies 'standard' qualifier"},
1471     {"standard", VT_BOOL, AJFALSE, "N",
1472 	 "Standard qualifier, value required. Interactive prompt if missing"},
1473     {"additional", VT_BOOL, AJFALSE, "N",
1474 	 "Additional qualifier. "
1475 	     "Value required if -options is on the command line, "
1476 		 "or set by default"},
1477     {"missing", VT_BOOL, AJFALSE, "N",
1478 	 "Allow with no value on the command line to set to ''"},
1479     {"valid", VT_STR, AJFALSE, "",
1480 	 "Help: String description of allowed values for -help output, "
1481 	     "used if the default help is nuclear"},
1482     {"expected", VT_STR, AJFALSE, "",
1483 	 "Help: String description of the expected value for -help output, "
1484 	     "used if the default help is nuclear"},
1485     {"needed", VT_BOOL, AJFALSE, "y",
1486 	 "Include in GUI form, "
1487 	     "used to hide options if they are unclear in GUIs"},
1488     {"knowntype", VT_STR, AJFALSE, "",
1489 	 "Known standard type, "
1490 	     "used to define input and output types for workflows"},
1491     {"relations", VT_STR, AJTRUE, "",
1492 	 "Relationships between this ACD item and others, "
1493 	     "defined as specially formatted text"},
1494     {"outputmodifier", VT_BOOL, AJFALSE, "N",
1495 	 "Modifies the output in ways that can break parsers"},
1496     {"style", VT_STR, AJFALSE, "",
1497 	 "Style for SoapLab's ACD files"},
1498     {"qualifier", VT_STR, AJFALSE, "",
1499 	 "Qualifier name for SoapLab's ACD files"},
1500     {"template", VT_STR, AJFALSE, "",
1501 	 "Commandline template for SoapLab's ACD files"},
1502     {"comment", VT_STR, AJTRUE, "",
1503 	 "Comment for SoapLab's ACD files"},
1504     {NULL, VT_NULL, AJFALSE, NULL,
1505 	 NULL}
1506 };
1507 
1508 
1509 /* Type-specific attributes
1510 ** each must end with "NULL, VT_NULL" to define the end of the list
1511 */
1512 
1513 AcdOAttr acdAttrXxxx[] =
1514 {
1515     {NULL, VT_NULL, AJFALSE, NULL,
1516 	 NULL}
1517 };
1518 
1519 
1520 AcdOAttr acdAttrAppl[] =
1521 {
1522     {"documentation", VT_STR, AJFALSE, "",
1523 	 "Short description of the application function"},
1524     {"groups", VT_STR, AJTRUE, "",
1525 	 "Standard application group(s) for wossname and GUIs"},
1526     {"keywords", VT_STR, AJTRUE, "",
1527 	 "Standard application keyword(s) for wossname and GUIs"},
1528     {"gui", VT_STR, AJFALSE, "",
1529 	 "Suitability for launching in a GUI"},
1530     {"batch", VT_STR, AJFALSE,"",
1531 	 "Suitability for running in batch"},
1532     {"obsolete", VT_STR, AJFALSE,"",
1533 	 "Reason for obsolete status"},
1534     {"embassy", VT_STR, AJFALSE,"",
1535 	 "EMBASSY package name"},
1536     {"external", VT_STR, AJTRUE, "",
1537 	 "Third party tool(s) required by this program"},
1538     {"wrapper", VT_BOOL, AJFALSE, "N",
1539 	 "Wrapper around original command line"},
1540     {"cpu", VT_STR, AJFALSE, "",
1541 	 "Estimated maximum CPU usage"},
1542     {"supplier", VT_STR, AJFALSE, "",
1543 	 "Supplier name"},
1544     {"versionnumber", VT_STR, AJFALSE, "",
1545 	 "Version number"},
1546     {"nonemboss", VT_STR, AJFALSE, "",
1547 	 "Non-emboss application name for SoapLab"},
1548     {"executable", VT_STR, AJFALSE,"",
1549 	 "Non-emboss executable for SoapLab"},
1550     {"template", VT_STR, AJFALSE, "",
1551 	 "Commandline template for SoapLab's ACD files"},
1552     {"comment", VT_STR, AJFALSE, "",
1553 	 "Comment for SoapLab's ACD files"},
1554     {"relations", VT_STR, AJTRUE, "",
1555 	 "Relationships between this ACD item and others, "
1556 	     "defined as specially formatted text"},
1557     {NULL, VT_NULL, AJFALSE, NULL,
1558 	 NULL}
1559 };
1560 
1561 
1562 AcdOAttr acdAttrAlign[] =
1563 {
1564     {"type", VT_STR, AJFALSE, "",
1565 	 "P:protein or N:nucleotide"},
1566     {"taglist", VT_STR, AJFALSE, "",
1567 	 "Extra tags to report"},
1568     {"minseqs", VT_INT, AJFALSE, "1",
1569 	 "Minimum number of sequences"},
1570     {"maxseqs", VT_INT, AJFALSE, "(INT_MAX)",
1571 	 "Maximum number of sequences"},
1572     {"multiple", VT_BOOL, AJFALSE, "N",
1573 	 "More than one alignment in one file"},
1574     {"nulldefault", VT_BOOL, AJFALSE, "N",
1575 	 "Defaults to 'no file'"},
1576     {"nullok", VT_BOOL, AJFALSE, "N",
1577 	 "Can accept a null filename as 'no file'"},
1578     {NULL, VT_NULL, AJFALSE, NULL,
1579 	 NULL}
1580 };
1581 
1582 
1583 AcdOAttr acdAttrArray[] =
1584 {
1585     {"minimum", VT_FLOAT, AJFALSE, "(-FLT_MAX)",
1586 	 "Minimum value"},
1587     {"maximum", VT_FLOAT, AJFALSE, "(FLT_MAX)",
1588 	 "Maximum value"},
1589     {"increment", VT_FLOAT, AJFALSE, "0",
1590 	 "(Not used by ACD) Increment for GUIs"},
1591     {"precision", VT_INT, AJFALSE, "3",
1592 	 "(Not used by ACD) Floating precision for GUIs"},
1593     {"warnrange", VT_BOOL, AJFALSE, "Y",
1594 	 "Warning if values are out of range"},
1595     {"size", VT_INT, AJFALSE, "1",
1596 	 "Number of values required"},
1597     {"sum", VT_FLOAT, AJFALSE, "1.0",
1598 	 "Total for all values"},
1599     {"sumtest", VT_BOOL, AJFALSE, "Y",
1600          "Test sum of all values"},
1601     {"trueminimum", VT_BOOL, AJFALSE, "N",
1602          "If max/min overlap, use minimum"},
1603     {"failrange", VT_BOOL, AJTRUE, "",
1604 	 "Fail if (calculated) ranges overlap"},
1605     {"rangemessage", VT_STR, AJFALSE, "",
1606 	 "Failure message if (calculated ranges) overlap"},
1607     {"tolerance", VT_FLOAT, AJFALSE, "0.01",
1608 	 "Tolerance (sum +/- tolerance) of the total"},
1609     {NULL, VT_NULL, AJFALSE, NULL,
1610 	 NULL}
1611 };
1612 
1613 
1614 AcdOAttr acdAttrAssembly[] =
1615 {
1616     {"entry", VT_BOOL, AJFALSE, "N",
1617 	 "Read whole entry text"},
1618     {"nullok", VT_BOOL, AJFALSE, "N",
1619 	 "Can accept a null filename as 'no file'"},
1620     {NULL, VT_NULL, AJFALSE, NULL,
1621 	 NULL}
1622 };
1623 
1624 
1625 AcdOAttr acdAttrBool[] =
1626 {
1627     {NULL, VT_NULL, AJFALSE, NULL,
1628 	 NULL}
1629 };
1630 
1631 
1632 AcdOAttr acdAttrCodon[] =
1633 {
1634     {"name", VT_STR, AJFALSE, "Ehum.cut",
1635 	 "Codon table name"},
1636     {"nullok", VT_BOOL, AJFALSE, "N",
1637 	 "Can accept a null filename as 'no file'"},
1638     {NULL, VT_NULL, AJFALSE, NULL,
1639 	 NULL}
1640 };
1641 
1642 
1643 AcdOAttr acdAttrCpdb[] =
1644 {
1645     {"nullok", VT_BOOL, AJFALSE, "N",
1646 	 "Can accept a null filename as 'no file'"},
1647     {NULL, VT_NULL, AJFALSE, NULL,
1648 	 NULL}
1649 };
1650 
1651 
1652 AcdOAttr acdAttrDatafile[] =
1653 {
1654     {"name", VT_STR, AJFALSE, "",
1655 	 "Default file base name"},
1656     {"extension", VT_STR, AJFALSE, "",
1657 	 "Default file extension"},
1658     {"directory", VT_STR, AJFALSE, "",
1659 	 "Default installed data directory"},
1660     {"nullok", VT_BOOL, AJFALSE, "N",
1661 	 "Can accept a null filename as 'no file'"},
1662     {NULL, VT_NULL, AJFALSE, NULL,
1663 	 NULL}
1664 };
1665 
1666 
1667 AcdOAttr acdAttrDirectory[] =
1668 {
1669     {"fullpath", VT_BOOL, AJFALSE, "N",
1670 	 "Require full path in value"},
1671     {"nulldefault", VT_BOOL, AJFALSE, "N",
1672 	 "Defaults to 'no file'"},
1673     {"nullok", VT_BOOL, AJFALSE, "N",
1674 	 "Can accept a null filename as 'no file'"},
1675     {NULL, VT_NULL, AJFALSE, NULL,
1676 	 NULL}
1677 };
1678 
1679 
1680 AcdOAttr acdAttrDirlist[] =
1681 {
1682     {"fullpath", VT_BOOL, AJFALSE, "N",
1683 	 "Require full path in value"},
1684     {"nullok", VT_BOOL, AJFALSE, "N",
1685 	 "Can accept a null filename as 'no file'"},
1686     {NULL, VT_NULL, AJFALSE, NULL,
1687 	 NULL}
1688 };
1689 
1690 
1691 AcdOAttr acdAttrDiscretestates[] =
1692 {
1693     {"length", VT_INT, AJFALSE, "0",
1694 	 "Number of discrete state values per set"},
1695     {"size", VT_INT, AJFALSE, "1",
1696 	 "Number of discrete state set"},
1697     {"characters", VT_STR, AJFALSE, "01",
1698 	 "Allowed discrete state characters (default is '' "
1699          "for all non-space characters"},
1700     {"nullok", VT_BOOL, AJFALSE, "N",
1701 	 "Can accept a null filename as 'no file'"},
1702     {NULL, VT_NULL, AJFALSE, NULL,
1703 	 NULL}
1704 };
1705 
1706 
1707 AcdOAttr acdAttrDistances[] =
1708 {
1709     {"size", VT_INT, AJFALSE, "1",
1710 	 "Number of rows"},
1711     {"nullok", VT_BOOL, AJFALSE, "N",
1712 	 "Can accept a null filename as 'no file'"},
1713     {"missval", VT_BOOL, AJFALSE, "N",
1714 	 "Can have missing values (replicates zero)"},
1715     {NULL, VT_NULL, AJFALSE, NULL,
1716 	 NULL}
1717 };
1718 
1719 
1720 AcdOAttr acdAttrEndsec[] =
1721 {
1722     {NULL, VT_NULL, AJFALSE, NULL,
1723 	 NULL}
1724 };
1725 
1726 
1727 AcdOAttr acdAttrFeatures[] =
1728 {
1729     {"type", VT_STR, AJFALSE, "",
1730 	 "Feature type (protein, nucleotide, etc.)"},
1731     {"entry", VT_BOOL, AJFALSE, "N",
1732 	 "Read whole entry text"},
1733     {"minreads", VT_INT, AJFALSE, "1",
1734 	 "Minimum number of inputs"},
1735     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
1736 	 "Maximum number of inputs"},
1737     {"nullok", VT_BOOL, AJFALSE, "N",
1738 	 "Can accept a null filename as 'no file'"},
1739     {NULL, VT_NULL, AJFALSE, NULL,
1740 	 NULL}
1741 };
1742 
1743 
1744 AcdOAttr acdAttrFeatout[] =
1745 {
1746     {"name", VT_STR, AJFALSE, "",
1747 	 "Default base file name (use of -ofname preferred)"},
1748     {"extension", VT_STR, AJFALSE, "",
1749 	 "Default file extension (use of -offormat preferred)"},
1750     {"type", VT_STR, AJFALSE, "",
1751 	 "Feature type (protein, nucleotide, etc.)"},
1752     {"multiple", VT_BOOL, AJFALSE, "N",
1753 	 "Features for multiple sequences"},
1754     {"nulldefault", VT_BOOL, AJFALSE, "N",
1755 	 "Defaults to 'no file'"},
1756     {"nullok", VT_BOOL, AJFALSE, "N",
1757 	 "Can accept a null UFO as 'no output'"},
1758     {NULL, VT_NULL, AJFALSE, NULL,
1759 	 NULL}
1760 };
1761 
1762 
1763 AcdOAttr acdAttrFilelist[] =
1764 {
1765     {"nullok", VT_BOOL, AJFALSE, "N",
1766 	 "Can accept a null filename as 'no file'"},
1767     {"binary", VT_BOOL, AJFALSE, "N",
1768 	 "File contains binary data"},
1769     {NULL, VT_NULL, AJFALSE, NULL,
1770 	 NULL}
1771 };
1772 
1773 
1774 AcdOAttr acdAttrFloat[] =
1775 {
1776     {"minimum", VT_FLOAT, AJFALSE, "(-FLT_MAX)",
1777 	 "Minimum value"},
1778     {"maximum", VT_FLOAT, AJFALSE, "(FLT_MAX)",
1779 	 "Maximum value"},
1780     {"increment", VT_FLOAT, AJFALSE, "1.0",
1781 	 "(Not used by ACD) Increment for GUIs"},
1782     {"precision", VT_INT, AJFALSE, "3",
1783 	 "Precision for printing values"},
1784     {"warnrange", VT_BOOL, AJFALSE, "Y",
1785 	 "Warning if values are out of range"},
1786     {"trueminimum", VT_BOOL, AJFALSE, "N",
1787          "If max/min overlap, use minimum"},
1788     {"failrange", VT_BOOL, AJTRUE, "",
1789 	 "Fail if calculated ranges overlap"},
1790     {"rangemessage", VT_STR, AJFALSE, "",
1791 	 "Failure message if calculated ranges overlap"},
1792     {"large", VT_BOOL, AJFALSE, "N",
1793 	 "Large values returned as double"},
1794 	{"trueminimum", VT_BOOL, AJFALSE, "N",
1795 	 "If max/min overlap, use minimum"},
1796    {NULL, VT_NULL, AJFALSE, NULL,
1797 	 NULL}
1798 };
1799 
1800 
1801 AcdOAttr acdAttrFrequencies[] =
1802 {
1803     {"length", VT_INT, AJFALSE, "0",
1804 	 "Number of frequency loci/values per set"},
1805     {"size", VT_INT, AJFALSE, "1",
1806 	 "Number of frequency sets"},
1807     {"continuous", VT_BOOL, AJFALSE, "N",
1808 	 "Continuous character data only"},
1809     {"genedata", VT_BOOL, AJFALSE, "N",
1810 	 "Gene frequency data only"},
1811     {"within", VT_BOOL, AJFALSE, "N",
1812 	 "Continuous data for multiple individuals"},
1813     {"nullok", VT_BOOL, AJFALSE, "N",
1814 	 "Can accept a null filename as 'no file'"},
1815     {NULL, VT_NULL, AJFALSE, NULL,
1816 	 NULL}
1817 };
1818 
1819 
1820 AcdOAttr acdAttrGraph[] =
1821 {
1822     {"sequence", VT_BOOL, AJFALSE, "N",
1823 	 "Sequence on x axis"},
1824     {"nulldefault", VT_BOOL, AJFALSE, "N",
1825 	 "Defaults to 'no file'"},
1826     {"nullok", VT_BOOL, AJFALSE, "N",
1827 	 "Can accept a null graph type as 'no graph'"},
1828     {NULL, VT_NULL, AJFALSE, NULL,
1829 	 NULL}
1830 };
1831 
1832 
1833 AcdOAttr acdAttrGraphxy[] =
1834 {
1835     {"multiple", VT_INT, AJFALSE, "1",
1836 	 "Number of graphs"},
1837     {"sequence", VT_BOOL, AJFALSE, "N",
1838 	 "Sequence on x axis"},
1839     {"nulldefault", VT_BOOL, AJFALSE, "N",
1840 	 "Defaults to 'no file'"},
1841     {"nullok", VT_BOOL, AJFALSE, "N",
1842 	 "Can accept a null graph type as 'no graph'"},
1843     {NULL, VT_NULL, AJFALSE, NULL,
1844 	 NULL}
1845 };
1846 
1847 
1848 AcdOAttr acdAttrInt[] =
1849 {
1850     {"minimum", VT_INT, AJFALSE, "(INT_MIN)",
1851 	 "Minimum value"},
1852     {"maximum", VT_INT, AJFALSE, "(INT_MAX)",
1853 	 "Maximum value"},
1854     {"increment", VT_INT, AJFALSE, "0",
1855 	 "(Not used by ACD) Increment for GUIs"},
1856     {"warnrange", VT_BOOL, AJFALSE, "Y",
1857 	 "Warning if values are out of range"},
1858     {"failrange", VT_BOOL, AJTRUE, "",
1859 	 "Fail if calculated ranges overlap"},
1860     {"rangemessage", VT_STR, AJFALSE, "",
1861 	 "Failure message if calculated ranges overlap"},
1862     {"large", VT_BOOL, AJFALSE, "N",
1863 	 "Large values returned as long"},
1864     {"trueminimum", VT_BOOL, AJFALSE, "N",
1865 	 "If max/min overlap, use minimum"},
1866     {NULL, VT_NULL, AJFALSE, NULL,
1867 	 NULL}
1868 };
1869 
1870 
1871 AcdOAttr acdAttrInfile[] =
1872 {
1873     {"directory", VT_STR, AJFALSE, "",
1874 	 "Default directory"},
1875     {"nullok", VT_BOOL, AJFALSE, "N",
1876 	 "Can accept a null filename as 'no file'"},
1877     {"trydefault", VT_BOOL, AJFALSE, "N",
1878 	 "Default filename may not exist if nullok is true"},
1879     {"binary", VT_BOOL, AJFALSE, "N",
1880 	 "File contains binary data"},
1881     {NULL, VT_NULL, AJFALSE, NULL,
1882 	 NULL}
1883 };
1884 
1885 
1886 AcdOAttr acdAttrList[] =
1887 {
1888     {"minimum", VT_INT, AJFALSE, "1",
1889 	 "Minimum number of selections"},
1890     {"maximum", VT_INT, AJFALSE, "1",
1891 	 "Maximum number of selections"},
1892     {"button", VT_BOOL, AJFALSE, "N",
1893 	 "(Not used by ACD) Prefer check boxes in GUI"},
1894     {"casesensitive", VT_BOOL, AJFALSE, "N",
1895 	 "Case sensitive"},
1896     {"header", VT_STR, AJFALSE, "",
1897 	 "Header description for list"},
1898     {"delimiter", VT_STR, AJFALSE, ";",
1899 	 "Delimiter for parsing values"},
1900     {"codedelimiter", VT_STR, AJFALSE, ":",
1901 	 "Delimiter for parsing"},
1902     {"values", VT_STR, AJFALSE, "",
1903 	 "Codes and values with delimiters"},
1904     {NULL, VT_NULL, AJFALSE, NULL,
1905 	 NULL}
1906 };
1907 
1908 
1909 AcdOAttr acdAttrMatrix[] =
1910 {
1911     {"pname", VT_STR, AJFALSE, "EBLOSUM62",
1912 	 "Default name for protein matrix"},
1913     {"nname", VT_STR, AJFALSE, "EDNAFULL",
1914 	 "Default name for nucleotide matrix"},
1915     {"protein", VT_BOOL, AJFALSE, "Y",
1916 	 "Protein matrix"},
1917     {NULL, VT_NULL, AJFALSE, NULL,
1918 	 NULL}
1919 };
1920 
1921 
1922 AcdOAttr acdAttrMatrixf[] =
1923 {
1924     {"pname", VT_STR, AJFALSE, "EBLOSUM62",
1925 	 "Default name for protein matrix"},
1926     {"nname", VT_STR, AJFALSE, "EDNAFULL",
1927 	 "Default name for nucleotide matrix"},
1928     {"protein", VT_BOOL, AJFALSE, "Y",
1929 	 "Protein matrix"},
1930     {NULL, VT_NULL, AJFALSE, NULL,
1931 	 NULL}
1932 };
1933 
1934 
1935 AcdOAttr acdAttrObo[] =
1936 {
1937     {"entry", VT_BOOL, AJFALSE, "N",
1938 	 "Read whole entry text"},
1939     {"minreads", VT_INT, AJFALSE, "1",
1940 	 "Minimum number of inputs"},
1941     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
1942 	 "Maximum number of inputs"},
1943     {"nullok", VT_BOOL, AJFALSE, "N",
1944 	 "Can accept a null filename as 'no file'"},
1945     {NULL, VT_NULL, AJFALSE, NULL,
1946 	 NULL}
1947 };
1948 
1949 
1950 AcdOAttr acdAttrOutassembly[] =
1951 {
1952     {"name", VT_STR, AJFALSE, "",
1953 	 "Default file name"},
1954     {"extension", VT_STR, AJFALSE, "",
1955 	 "Default file extension"},
1956     {"nulldefault", VT_BOOL, AJFALSE, "N",
1957 	 "Defaults to 'no file'"},
1958     {"nullok", VT_BOOL, AJFALSE, "N",
1959 	 "Can accept a null filename as 'no file'"},
1960     {NULL, VT_NULL, AJFALSE, NULL,
1961 	 NULL}
1962 };
1963 
1964 
1965 AcdOAttr acdAttrOutcodon[] =
1966 {
1967     {"name", VT_STR, AJFALSE, "",
1968 	 "Default file name"},
1969     {"extension", VT_STR, AJFALSE, "",
1970 	 "Default file extension"},
1971     {"nulldefault", VT_BOOL, AJFALSE, "N",
1972 	 "Defaults to 'no file'"},
1973     {"nullok", VT_BOOL, AJFALSE, "N",
1974 	 "Can accept a null filename as 'no file'"},
1975     {NULL, VT_NULL, AJFALSE, NULL,
1976 	 NULL}
1977 };
1978 
1979 
1980 AcdOAttr acdAttrOutcpdb[] =
1981 {
1982     {"nulldefault", VT_BOOL, AJFALSE, "N",
1983 	 "Defaults to 'no file'"},
1984     {"nullok", VT_BOOL, AJFALSE, "N",
1985 	 "Can accept a null filename as 'no file'"},
1986     {NULL, VT_NULL, AJFALSE, NULL,
1987 	 NULL}
1988 };
1989 
1990 
1991 AcdOAttr acdAttrOutdata[] =
1992 {
1993     {"type", VT_STR, AJFALSE, "",
1994 	 "Data type"},
1995     {"nulldefault", VT_BOOL, AJFALSE, "N",
1996 	 "Defaults to 'no file'"},
1997     {"nullok", VT_BOOL, AJFALSE, "N",
1998 	 "Can accept a null filename as 'no file'"},
1999     {"binary", VT_BOOL, AJFALSE, "N",
2000 	 "File contains binary data"},
2001     {NULL, VT_NULL, AJFALSE, NULL,
2002 	 NULL}
2003 };
2004 
2005 
2006 AcdOAttr acdAttrOutdir[] =
2007 {
2008     {"fullpath", VT_BOOL, AJFALSE, "N",
2009 	 "Require full path in value"},
2010     {"nulldefault", VT_BOOL, AJFALSE, "N",
2011 	 "Defaults to 'no file'"},
2012     {"nullok", VT_BOOL, AJFALSE, "N",
2013 	 "Can accept a null filename as 'no file'"},
2014     {"binary", VT_BOOL, AJFALSE, "N",
2015 	 "Files contain binary data"},
2016     {"create", VT_BOOL, AJFALSE, "N",
2017 	 "Can create directory if not found"},
2018     {"temporary", VT_BOOL, AJFALSE, "N",
2019 	 "Scratch directory for temporary files deleted on completion"},
2020     {NULL, VT_NULL, AJFALSE, NULL,
2021 	 NULL}
2022 };
2023 
2024 
2025 AcdOAttr acdAttrOutdiscrete[] =
2026 {
2027     {"nulldefault", VT_BOOL, AJFALSE, "N",
2028 	 "Defaults to 'no file'"},
2029     {"nullok", VT_BOOL, AJFALSE, "N",
2030 	 "Can accept a null filename as 'no file'"},
2031     {NULL, VT_NULL, AJFALSE, NULL,
2032 	 NULL}
2033 };
2034 
2035 
2036 AcdOAttr acdAttrOutdistance[] =
2037 {
2038     {"nulldefault", VT_BOOL, AJFALSE, "N",
2039 	 "Defaults to 'no file'"},
2040     {"nullok", VT_BOOL, AJFALSE, "N",
2041 	 "Can accept a null filename as 'no file'"},
2042     {NULL, VT_NULL, AJFALSE, NULL,
2043 	 NULL}
2044 };
2045 
2046 
2047 AcdOAttr acdAttrOutfile[] =
2048 {
2049     {"name", VT_STR, AJFALSE, "",
2050 	 "Default file name"},
2051     {"extension", VT_STR, AJFALSE, "",
2052 	 "Default file extension"},
2053     {"append", VT_BOOL, AJFALSE, "N",
2054 	 "Append to an existing file"},
2055     {"nulldefault", VT_BOOL, AJFALSE, "N",
2056 	 "Defaults to 'no file'"},
2057     {"nullok", VT_BOOL, AJFALSE, "N",
2058 	 "Can accept a null filename as 'no file'"},
2059     {"binary", VT_BOOL, AJFALSE, "N",
2060 	 "File contains binary data"},
2061     {NULL, VT_NULL, AJFALSE, NULL,
2062 	 NULL}
2063 };
2064 
2065 
2066 AcdOAttr acdAttrOutfreq[] =
2067 {
2068     {"nulldefault", VT_BOOL, AJFALSE, "N",
2069 	 "Defaults to 'no file'"},
2070     {"nullok", VT_BOOL, AJFALSE, "N",
2071 	 "Can accept a null filename as 'no file'"},
2072     {NULL, VT_NULL, AJFALSE, NULL,
2073 	 NULL}
2074 };
2075 
2076 
2077 AcdOAttr acdAttrOutmatrix[] =
2078 {
2079     {"nulldefault", VT_BOOL, AJFALSE, "N",
2080 	 "Defaults to 'no file'"},
2081     {"nullok", VT_BOOL, AJFALSE, "N",
2082 	 "Can accept a null filename as 'no file'"},
2083     {NULL, VT_NULL, AJFALSE, NULL,
2084 	 NULL}
2085 };
2086 
2087 
2088 AcdOAttr acdAttrOutmatrixf[] =
2089 {
2090     {"nulldefault", VT_BOOL, AJFALSE, "N",
2091 	 "Defaults to 'no file'"},
2092     {"nullok", VT_BOOL, AJFALSE, "N",
2093 	 "Can accept a null filename as 'no file'"},
2094     {NULL, VT_NULL, AJFALSE, NULL,
2095 	 NULL}
2096 };
2097 
2098 
2099 AcdOAttr acdAttrOutobo[] =
2100 {
2101     {"name", VT_STR, AJFALSE, "",
2102 	 "Default file name"},
2103     {"extension", VT_STR, AJFALSE, "",
2104 	 "Default file extension"},
2105     {"nulldefault", VT_BOOL, AJFALSE, "N",
2106 	 "Defaults to 'no file'"},
2107     {"nullok", VT_BOOL, AJFALSE, "N",
2108 	 "Can accept a null filename as 'no file'"},
2109     {NULL, VT_NULL, AJFALSE, NULL,
2110 	 NULL}
2111 };
2112 
2113 
2114 AcdOAttr acdAttrOutproperties[] =
2115 {
2116     {"nulldefault", VT_BOOL, AJFALSE, "N",
2117 	 "Defaults to 'no file'"},
2118     {"nullok", VT_BOOL, AJFALSE, "N",
2119 	 "Can accept a null filename as 'no file'"},
2120     {NULL, VT_NULL, AJFALSE, NULL,
2121 	 NULL}
2122 };
2123 
2124 
2125 AcdOAttr acdAttrOutrefseq[] =
2126 {
2127     {"name", VT_STR, AJFALSE, "",
2128 	 "Default file name"},
2129     {"extension", VT_STR, AJFALSE, "",
2130 	 "Default file extension"},
2131     {"nulldefault", VT_BOOL, AJFALSE, "N",
2132 	 "Defaults to 'no file'"},
2133     {"nullok", VT_BOOL, AJFALSE, "N",
2134 	 "Can accept a null filename as 'no file'"},
2135     {NULL, VT_NULL, AJFALSE, NULL,
2136 	 NULL}
2137 };
2138 
2139 
2140 AcdOAttr acdAttrOutresource[] =
2141 {
2142     {"name", VT_STR, AJFALSE, "",
2143 	 "Default file name"},
2144     {"extension", VT_STR, AJFALSE, "",
2145 	 "Default file extension"},
2146     {"nulldefault", VT_BOOL, AJFALSE, "N",
2147 	 "Defaults to 'no file'"},
2148     {"nullok", VT_BOOL, AJFALSE, "N",
2149 	 "Can accept a null filename as 'no file'"},
2150     {NULL, VT_NULL, AJFALSE, NULL,
2151 	 NULL}
2152 };
2153 
2154 
2155 AcdOAttr acdAttrOutscop[] =
2156 {
2157     {"nulldefault", VT_BOOL, AJFALSE, "N",
2158 	 "Defaults to 'no file'"},
2159     {"nullok", VT_BOOL, AJFALSE, "N",
2160 	 "Can accept a null filename as 'no file'"},
2161     {NULL, VT_NULL, AJFALSE, NULL,
2162 	 NULL}
2163 };
2164 
2165 
2166 AcdOAttr acdAttrOuttaxon[] =
2167 {
2168     {"name", VT_STR, AJFALSE, "",
2169 	 "Default file name"},
2170     {"extension", VT_STR, AJFALSE, "",
2171 	 "Default file extension"},
2172     {"nulldefault", VT_BOOL, AJFALSE, "N",
2173 	 "Defaults to 'no file'"},
2174     {"nullok", VT_BOOL, AJFALSE, "N",
2175 	 "Can accept a null filename as 'no file'"},
2176     {NULL, VT_NULL, AJFALSE, NULL,
2177 	 NULL}
2178 };
2179 
2180 
2181 AcdOAttr acdAttrOuttext[] =
2182 {
2183     {"name", VT_STR, AJFALSE, "",
2184 	 "Default file name"},
2185     {"extension", VT_STR, AJFALSE, "",
2186 	 "Default file extension"},
2187     {"nulldefault", VT_BOOL, AJFALSE, "N",
2188 	 "Defaults to 'no file'"},
2189     {"nullok", VT_BOOL, AJFALSE, "N",
2190 	 "Can accept a null filename as 'no file'"},
2191     {NULL, VT_NULL, AJFALSE, NULL,
2192 	 NULL}
2193 };
2194 
2195 
2196 AcdOAttr acdAttrOuttree[] =
2197 {
2198     {"name", VT_STR, AJFALSE, "",
2199 	 "Default file name"},
2200     {"extension", VT_STR, AJFALSE, "",
2201 	 "Default file extension"},
2202     {"nulldefault", VT_BOOL, AJFALSE, "N",
2203 	 "Defaults to 'no file'"},
2204     {"nullok", VT_BOOL, AJFALSE, "N",
2205 	 "Can accept a null filename as 'no file'"},
2206     {NULL, VT_NULL, AJFALSE, NULL,
2207 	 NULL}
2208 };
2209 
2210 
2211 AcdOAttr acdAttrOuturl[] =
2212 {
2213     {"name", VT_STR, AJFALSE, "",
2214 	 "Default file name"},
2215     {"extension", VT_STR, AJFALSE, "",
2216 	 "Default file extension"},
2217     {"nulldefault", VT_BOOL, AJFALSE, "N",
2218 	 "Defaults to 'no file'"},
2219     {"nullok", VT_BOOL, AJFALSE, "N",
2220 	 "Can accept a null filename as 'no file'"},
2221     {NULL, VT_NULL, AJFALSE, NULL,
2222 	 NULL}
2223 };
2224 
2225 
2226 AcdOAttr acdAttrOutvariation[] =
2227 {
2228     {"name", VT_STR, AJFALSE, "",
2229 	 "Default file name"},
2230     {"extension", VT_STR, AJFALSE, "",
2231 	 "Default file extension"},
2232     {"nulldefault", VT_BOOL, AJFALSE, "N",
2233 	 "Defaults to 'no file'"},
2234     {"nullok", VT_BOOL, AJFALSE, "N",
2235 	 "Can accept a null filename as 'no file'"},
2236     {NULL, VT_NULL, AJFALSE, NULL,
2237 	 NULL}
2238 };
2239 
2240 
2241 AcdOAttr acdAttrOutxml[] =
2242 {
2243     {"name", VT_STR, AJFALSE, "",
2244 	 "Default file name"},
2245     {"extension", VT_STR, AJFALSE, "",
2246 	 "Default file extension"},
2247     {"nulldefault", VT_BOOL, AJFALSE, "N",
2248 	 "Defaults to 'no file'"},
2249     {"nullok", VT_BOOL, AJFALSE, "N",
2250 	 "Can accept a null filename as 'no file'"},
2251     {NULL, VT_NULL, AJFALSE, NULL,
2252 	 NULL}
2253 };
2254 
2255 
2256 
2257 AcdOAttr acdAttrPattern[] =
2258 {
2259     {"minlength", VT_INT, AJFALSE, "1",
2260 	 "Minimum pattern length"},
2261     {"maxlength", VT_INT, AJFALSE, "(INT_MAX)",
2262 	 "Maximum pattern length"},
2263     {"maxsize", VT_INT, AJFALSE, "(INT_MAX)",
2264 	 "Maximum number of patterns"},
2265     {"upper", VT_BOOL, AJFALSE, "N",
2266 	 "Convert to upper case"},
2267     {"lower", VT_BOOL, AJFALSE, "N",
2268 	 "Convert to lower case"},
2269     {"type", VT_STR, AJFALSE, "string",
2270 	 "Type (nucleotide, protein)"},
2271     {NULL, VT_NULL, AJFALSE, NULL,
2272 	 NULL}
2273 };
2274 
2275 
2276 AcdOAttr acdAttrProperties[] =
2277 {
2278     {"length", VT_INT, AJFALSE, "0",
2279 	 "Number of property values per set"},
2280     {"size", VT_INT, AJFALSE, "1",
2281 	 "Number of property sets"},
2282     {"characters", VT_STR, AJFALSE, "",
2283 	 "Allowed property characters (default is '' for all non-space)"},
2284     {"nullok", VT_BOOL, AJFALSE, "N",
2285 	 "Can accept a null filename as 'no file'"},
2286     {NULL, VT_NULL, AJFALSE, NULL,
2287 	 NULL}
2288 };
2289 
2290 
2291 AcdOAttr acdAttrRange[] =
2292 {
2293     {"minimum", VT_INT, AJFALSE, "1",
2294 	 "Minimum value"},
2295     {"maximum", VT_INT, AJFALSE, "(INT_MAX)",
2296 	 "Maximum value"},
2297     {"trueminimum", VT_BOOL, AJFALSE, "N",
2298          "If max/min overlap, use minimum"},
2299     {"warnrange", VT_BOOL, AJFALSE, "",
2300 	 "Warning if values are out of range"},
2301     {"failrange", VT_BOOL, AJTRUE, "",
2302 	 "Fail if calculated ranges overlap"},
2303     {"rangemessage", VT_STR, AJFALSE, "",
2304 	 "Failure message if calculated ranges overlap"},
2305     {"size", VT_INT, AJFALSE, "0",
2306 	 "Exact number of values required"},
2307     {"minsize", VT_INT, AJFALSE, "0",
2308 	 "Minimum number of values required"},
2309     {NULL, VT_NULL, AJFALSE, NULL,
2310 	 NULL}
2311 };
2312 
2313 
2314 AcdOAttr acdAttrRegexp[] =
2315 {
2316     {"minlength", VT_INT, AJFALSE, "1",
2317 	 "Minimum pattern length"},
2318     {"maxlength", VT_INT, AJFALSE, "(INT_MAX)",
2319 	 "Maximum pattern length"},
2320     {"maxsize", VT_INT, AJFALSE, "(INT_MAX)",
2321 	 "Maximum number of patterns"},
2322     {"upper", VT_BOOL, AJFALSE, "N",
2323 	 "Convert to upper case"},
2324     {"lower", VT_BOOL, AJFALSE, "N",
2325 	 "Convert to lower case"},
2326     {"type", VT_STR, AJFALSE, "string",
2327 	 "Type (string, nucleotide, protein)"},
2328     {NULL, VT_NULL, AJFALSE, NULL,
2329 	 NULL}
2330 };
2331 
2332 
2333 AcdOAttr acdAttrRel[] =
2334 {
2335     {"relations", VT_STR, AJTRUE, "",
2336 	 "Relationships between this ACD item and others, "
2337 	     "defined as specially formatted text"},
2338     {NULL, VT_NULL, AJFALSE, NULL,
2339 	 NULL}
2340 };
2341 
2342 
2343 AcdOAttr acdAttrReport[] =
2344 {
2345     {"type", VT_STR, AJFALSE, "",
2346 	 "P:protein or N:nucleotide"},
2347     {"taglist", VT_STR, AJFALSE, "",
2348 	 "Extra tag names to report"},
2349     {"multiple", VT_BOOL, AJFALSE, "N",
2350 	 "Multiple sequences in one report"},
2351     {"precision", VT_INT, AJFALSE, "3",
2352 	 "Score precision"},
2353     {"nulldefault", VT_BOOL, AJFALSE, "N",
2354 	 "Defaults to 'no file'"},
2355     {"nullok", VT_BOOL, AJFALSE, "N",
2356 	 "Can accept a null filename as 'no file'"},
2357     {NULL, VT_NULL, AJFALSE, NULL,
2358 	 NULL}
2359 };
2360 
2361 
2362 AcdOAttr acdAttrRefseq[] =
2363 {
2364     {"entry", VT_BOOL, AJFALSE, "N",
2365 	 "Read whole entry text"},
2366     {"nullok", VT_BOOL, AJFALSE, "N",
2367 	 "Can accept a null filename as 'no file'"},
2368     {NULL, VT_NULL, AJFALSE, NULL,
2369 	 NULL}
2370 };
2371 
2372 
2373 AcdOAttr acdAttrResource[] =
2374 {
2375     {"entry", VT_BOOL, AJFALSE, "N",
2376 	 "Read whole entry text"},
2377     {"minreads", VT_INT, AJFALSE, "1",
2378 	 "Minimum number of inputs"},
2379     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
2380 	 "Maximum number of inputs"},
2381     {"nullok", VT_BOOL, AJFALSE, "N",
2382 	 "Can accept a null filename as 'no file'"},
2383     {NULL, VT_NULL, AJFALSE, NULL,
2384 	 NULL}
2385 };
2386 
2387 
2388 AcdOAttr acdAttrScop[] =
2389 {
2390     {"nullok", VT_BOOL, AJFALSE, "N",
2391 	 "Can accept a null filename as 'no file'"},
2392     {NULL, VT_NULL, AJFALSE, NULL,
2393 	 NULL}
2394 };
2395 
2396 
2397 AcdOAttr acdAttrSec[] =
2398 {
2399     {"information", VT_STR, AJFALSE, "",
2400 	 "(Not used by ACD) Section description"},
2401     {"type", VT_STR, AJFALSE, "",
2402 	 "(Not used by ACD) Type (frame, page)"},
2403     {"comment", VT_STR, AJFALSE, "",
2404 	 "(Not used by ACD) Free text comment"},
2405     {"border", VT_INT, AJFALSE, "1",
2406 	 "(Not used by ACD) Border width"},
2407     {"side", VT_STR, AJFALSE, "",
2408 	 "(Not used by ACD) Side (top, bottom, left, right) "
2409 	 "for type:frame"},
2410     {"folder", VT_STR, AJFALSE, "",
2411 	 "(Not used by ACD) Folder name for type:page"},
2412     {NULL, VT_NULL, AJFALSE, NULL,
2413 	 NULL}
2414 };
2415 
2416 
2417 AcdOAttr acdAttrSelect[] =
2418 {
2419     {"minimum", VT_INT, AJFALSE, "1",
2420 	 "Minimum number of selections"},
2421     {"maximum", VT_INT, AJFALSE, "1",
2422 	 "Maximum number of selections"},
2423     {"button", VT_BOOL, AJFALSE, "N",
2424 	 "(Not used by ACD) Prefer radio buttons in GUI"},
2425     {"casesensitive", VT_BOOL, AJFALSE, "N",
2426 	 "Case sensitive matching"},
2427     {"header", VT_STR, AJFALSE, "",
2428 	 "Header description for selection list"},
2429     {"delimiter", VT_STR, AJFALSE, ":",
2430 	 "Delimiter for parsing values"},
2431     {"values", VT_STR, AJFALSE, "",
2432 	 "Values with delimiters"},
2433     {NULL, VT_NULL, AJFALSE, NULL,
2434 	 NULL}
2435 };
2436 
2437 
2438 AcdOAttr acdAttrSeq[] =
2439 {
2440     {"type", VT_STR, AJFALSE, "",
2441 	 "Input sequence type (protein, gapprotein, etc.)"},
2442     {"features", VT_BOOL, AJFALSE, "N",
2443 	 "Read features if any"},
2444     {"entry", VT_BOOL, AJFALSE, "N",
2445 	 "Read whole entry text"},
2446     {"nullok", VT_BOOL, AJFALSE, "N",
2447 	 "Can accept a null filename as 'no file'"},
2448     {NULL, VT_NULL, AJFALSE, NULL,
2449 	 NULL}
2450 };
2451 
2452 
2453 AcdOAttr acdAttrSeqall[] =
2454 {
2455     {"type", VT_STR, AJFALSE, "",
2456 	 "Input sequence type (protein, gapprotein, etc.)"},
2457     {"features", VT_BOOL, AJFALSE, "N",
2458 	 "Read features if any"},
2459     {"entry", VT_BOOL, AJFALSE, "N",
2460 	 "Read whole entry text"},
2461     {"minseqs", VT_INT, AJFALSE, "1",
2462 	 "Minimum number of sequences"},
2463     {"maxseqs", VT_INT, AJFALSE, "(INT_MAX)",
2464 	 "Maximum number of sequences"},
2465     {"nullok", VT_BOOL, AJFALSE, "N",
2466 	 "Can accept a null filename as 'no file'"},
2467     {NULL, VT_NULL, AJFALSE, NULL,
2468 	 NULL}
2469 };
2470 
2471 
2472 AcdOAttr acdAttrSeqout[] =
2473 {
2474     {"name", VT_STR, AJFALSE, "",
2475 	 "Output base name (use of -osname preferred)"},
2476     {"extension", VT_STR, AJFALSE, "",
2477 	 "Output extension (use of -osextension preferred)"},
2478     {"features", VT_BOOL, AJFALSE, "N",
2479 	 "Write features if any"},
2480     {"type", VT_STR, AJFALSE, "",
2481 	 "Output sequence type (protein, gapprotein, etc.)"},
2482     {"nulldefault", VT_BOOL, AJFALSE, "N",
2483 	 "Defaults to 'no file'"},
2484     {"nullok", VT_BOOL, AJFALSE, "N",
2485 	 "Can accept a null USA as 'no output'"},
2486     {NULL, VT_NULL, AJFALSE, NULL,
2487 	 NULL}
2488 };
2489 
2490 
2491 AcdOAttr acdAttrSeqoutall[] =
2492 {
2493     {"name", VT_STR, AJFALSE, "",
2494 	 "Output base name (use of -osname preferred)"},
2495     {"extension", VT_STR, AJFALSE, "",
2496 	 "Output extension (use of -osextension preferred)"},
2497     {"features", VT_BOOL, AJFALSE, "N",
2498 	 "Write features if any"},
2499     {"type", VT_STR, AJFALSE, "",
2500 	 "Output sequence type (protein, gapprotein, etc.)"},
2501     {"minseqs", VT_INT, AJFALSE, "1",
2502 	 "Minimum number of sequences"},
2503     {"maxseqs", VT_INT, AJFALSE, "(INT_MAX)",
2504 	 "Maximum number of sequences"},
2505     {"nulldefault", VT_BOOL, AJFALSE, "N",
2506 	 "Defaults to 'no file'"},
2507     {"nullok", VT_BOOL, AJFALSE, "N",
2508 	 "Can accept a null USA as 'no output'"},
2509     {"aligned", VT_BOOL, AJFALSE, "N",
2510          "Sequences are aligned"},
2511     {NULL, VT_NULL, AJFALSE, NULL,
2512 	 NULL}
2513 };
2514 
2515 
2516 AcdOAttr acdAttrSeqoutset[] =
2517 {
2518     {"name", VT_STR, AJFALSE, "",
2519 	 "Output base name (use of -osname preferred)"},
2520     {"extension", VT_STR, AJFALSE, "",
2521 	 "Output extension (use of -osextension preferred)"},
2522     {"features", VT_BOOL, AJFALSE, "N",
2523 	 "Write features if any"},
2524     {"type", VT_STR, AJFALSE, "",
2525 	 "Output sequence type (protein, gapprotein, etc.)"},
2526     {"minseqs", VT_INT, AJFALSE, "1",
2527 	 "Minimum number of sequences"},
2528     {"maxseqs", VT_INT, AJFALSE, "(INT_MAX)",
2529 	 "Maximum number of sequences"},
2530     {"nulldefault", VT_BOOL, AJFALSE, "N",
2531 	 "Defaults to 'no file'"},
2532     {"nullok", VT_BOOL, AJFALSE, "N",
2533 	 "Can accept a null USA as 'no output'"},
2534     {"aligned", VT_BOOL, AJFALSE, "N",
2535 	 "Sequences are aligned"},
2536     {NULL, VT_NULL, AJFALSE, NULL,
2537 	 NULL}
2538 };
2539 
2540 
2541 AcdOAttr acdAttrSeqset[] =
2542 {
2543     {"type", VT_STR, AJFALSE, "",
2544 	 "Input sequence type (protein, gapprotein, etc.)"},
2545     {"features", VT_BOOL, AJFALSE, "N",
2546 	 "Read features if any"},
2547     {"aligned", VT_BOOL, AJFALSE, "N",
2548 	 "Sequences are aligned"},
2549     {"minseqs", VT_INT, AJFALSE, "1",
2550 	 "Minimum number of sequences"},
2551     {"maxseqs", VT_INT, AJFALSE, "(INT_MAX)",
2552 	 "Maximum number of sequences"},
2553     {"nullok", VT_BOOL, AJFALSE, "N",
2554 	 "Can accept a null filename as 'no file'"},
2555     {NULL, VT_NULL, AJFALSE, NULL,
2556 	 NULL}
2557 };
2558 
2559 
2560 AcdOAttr acdAttrSeqsetall[] =
2561 {
2562     {"type", VT_STR, AJFALSE, "",
2563 	 "Input sequence type (protein, gapprotein, etc.)"},
2564     {"features", VT_BOOL, AJFALSE, "N",
2565 	 "Read features if any"},
2566     {"aligned", VT_BOOL, AJFALSE, "N",
2567 	 "Sequences are aligned"},
2568     {"minseqs", VT_INT, AJFALSE, "1",
2569 	 "Minimum number of sequences"},
2570     {"maxseqs", VT_INT, AJFALSE, "(INT_MAX)",
2571 	 "Maximum number of sequences"},
2572     {"minsets", VT_INT, AJFALSE, "1",
2573 	 "Minimum number of sequence sets"},
2574     {"maxsets", VT_INT, AJFALSE, "(INT_MAX)",
2575 	 "Maximum number of sequence sets"},
2576     {"nulldefault", VT_BOOL, AJFALSE, "N",
2577 	 "Defaults to 'no file'"},
2578     {"nullok", VT_BOOL, AJFALSE, "N",
2579 	 "Can accept a null filename as 'no file'"},
2580     {NULL, VT_NULL, AJFALSE, NULL,
2581 	 NULL}
2582 };
2583 
2584 
2585 AcdOAttr acdAttrString[] =
2586 {
2587     {"minlength", VT_INT, AJFALSE, "0",
2588 	 "Minimum length"},
2589     {"maxlength", VT_INT, AJFALSE, "(INT_MAX)",
2590 	 "Maximum length"},
2591     {"pattern", VT_STR, AJFALSE, "",
2592 	 "Regular expression for validation"},
2593     {"upper", VT_BOOL, AJFALSE, "N",
2594 	 "Convert to upper case"},
2595     {"lower", VT_BOOL, AJFALSE, "N",
2596 	 "Convert to lower case"},
2597     {"word", VT_BOOL, AJFALSE, "N",
2598 	 "Disallow whitespace in strings"},
2599     {NULL, VT_NULL, AJFALSE, NULL,
2600 	 NULL}
2601 };
2602 
2603 
2604 AcdOAttr acdAttrTaxon[] =
2605 {
2606     {"entry", VT_BOOL, AJFALSE, "N",
2607 	 "Read whole entry text"},
2608     {"minreads", VT_INT, AJFALSE, "1",
2609 	 "Minimum number of inputs"},
2610     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
2611 	 "Maximum number of inputs"},
2612     {"nullok", VT_BOOL, AJFALSE, "N",
2613 	 "Can accept a null filename as 'no file'"},
2614     {NULL, VT_NULL, AJFALSE, NULL,
2615 	 NULL}
2616 };
2617 
2618 
2619 AcdOAttr acdAttrText[] =
2620 {
2621     {"entry", VT_BOOL, AJFALSE, "N",
2622 	 "Read whole entry text"},
2623     {"minreads", VT_INT, AJFALSE, "1",
2624 	 "Minimum number of inputs"},
2625     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
2626 	 "Maximum number of inputs"},
2627     {"nullok", VT_BOOL, AJFALSE, "N",
2628 	 "Can accept a null filename as 'no file'"},
2629     {NULL, VT_NULL, AJFALSE, NULL,
2630 	 NULL}
2631 };
2632 
2633 
2634 AcdOAttr acdAttrToggle[] =
2635 {
2636     {NULL, VT_NULL, AJFALSE, NULL,
2637 	 NULL}
2638 };
2639 
2640 
2641 AcdOAttr acdAttrTree[] =
2642 {
2643     {"size", VT_INT, AJFALSE, "0",
2644 	 "Number of trees (0 means any number)"},
2645     {"nullok", VT_BOOL, AJFALSE, "N",
2646 	 "Can accept a null filename as 'no file'"},
2647     {NULL, VT_NULL, AJFALSE, NULL,
2648 	 NULL}
2649 };
2650 
2651 
2652 AcdOAttr acdAttrUrl[] =
2653 {
2654     {"entry", VT_BOOL, AJFALSE, "N",
2655 	 "Read whole entry text"},
2656     {"minreads", VT_INT, AJFALSE, "1",
2657 	 "Minimum number of inputs"},
2658     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
2659 	 "Maximum number of inputs"},
2660     {"nullok", VT_BOOL, AJFALSE, "N",
2661 	 "Can accept a null filename as 'no file'"},
2662     {NULL, VT_NULL, AJFALSE, NULL,
2663 	 NULL}
2664 };
2665 
2666 
2667 AcdOAttr acdAttrVariation[] =
2668 {
2669     {"entry", VT_BOOL, AJFALSE, "N",
2670 	 "Read whole entry text"},
2671     {"minreads", VT_INT, AJFALSE, "1",
2672 	 "Minimum number of inputs"},
2673     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
2674 	 "Maximum number of inputs"},
2675     {"nullok", VT_BOOL, AJFALSE, "N",
2676 	 "Can accept a null filename as 'no file'"},
2677     {NULL, VT_NULL, AJFALSE, NULL,
2678 	 NULL}
2679 };
2680 
2681 
2682 AcdOAttr acdAttrXml[] =
2683 {
2684     {"entry", VT_BOOL, AJFALSE, "N",
2685 	 "Read whole entry text"},
2686     {"minreads", VT_INT, AJFALSE, "1",
2687 	 "Minimum number of inputs"},
2688     {"maxreads", VT_INT, AJFALSE, "(INT_MAX)",
2689 	 "Maximum number of inputs"},
2690     {"nullok", VT_BOOL, AJFALSE, "N",
2691 	 "Can accept a null filename as 'no file'"},
2692     {NULL, VT_NULL, AJFALSE, NULL,
2693 	 NULL}
2694 };
2695 
2696 
2697 AcdOAttr acdAttrVar[] =
2698 {
2699     {NULL, VT_NULL, AJFALSE, NULL,
2700 	 NULL}
2701 };
2702 
2703 
2704 /* Calculated attributes */
2705 
2706 static AcdOAttr acdCalcDiscrete[] =
2707 {
2708     {"discretelength", VT_INT, AJFALSE, "",
2709 	 "Number of discrete state values per set"},
2710     {"discretesize", VT_INT, AJFALSE, "",
2711 	 "Number of discrete state sets"},
2712     {"discretecount", VT_INT, AJFALSE, "",
2713 	 "Number of sets of discrete states"},
2714     {NULL, VT_NULL, AJFALSE, NULL,
2715 	 NULL}
2716 };
2717 
2718 
2719 static AcdOAttr acdCalcDistances[] =
2720 {
2721     {"distancecount", VT_INT, AJFALSE, "",
2722 	 "Number of distance matrices"},
2723     {"distancesize", VT_INT, AJFALSE, "",
2724 	 "Number of distance rows"},
2725     {"replicates", VT_BOOL, AJFALSE, "",
2726 	 "Replicates data found in input"},
2727     {"hasmissing", VT_BOOL, AJFALSE, "",
2728 	 "Missing values found (replicates=N)"},
2729     {NULL, VT_NULL, AJFALSE, NULL,
2730 	 NULL}
2731 };
2732 
2733 
2734 static AcdOAttr acdCalcFeat[] =
2735 {
2736     {"fbegin", VT_INT, AJFALSE, "(0 if unspecified)",
2737 	 "Start of the features to be used"},
2738     {"fend", VT_INT, AJFALSE, "(0 if unspecified)",
2739 	 "End of the features to be used"},
2740     {"flength", VT_INT, AJFALSE, "",
2741 	 "Total length of sequence (fsize is feature count)"},
2742     {"fprotein", VT_BOOL, AJFALSE, "",
2743 	 "Feature table is protein"},
2744     {"fnucleic", VT_BOOL, AJFALSE, "",
2745 	 "Feature table is nucleotide"},
2746     {"fname", VT_STR, AJFALSE, "",
2747 	 "The name of the feature table"},
2748     {"fsize", VT_INT, AJFALSE, "",
2749 	 "Number of features"},
2750     {NULL, VT_NULL, AJFALSE, NULL,
2751 	 NULL}
2752 };
2753 
2754 
2755 static AcdOAttr acdCalcFrequencies[] =
2756 {
2757     {"freqlength", VT_INT, AJFALSE, "",
2758 	 "Number of frequency values per set"},
2759     {"freqsize", VT_INT, AJFALSE, "",
2760 	 "Number of frequency sets"},
2761     {"freqloci", VT_INT, AJFALSE, "",
2762 	 "Number of frequency loci"},
2763     {"freqgenedata", VT_BOOL, AJFALSE, "",
2764 	 "Gene frequency data"},
2765     {"freqcontinuous", VT_BOOL, AJFALSE, "",
2766 	 "Continuous frequency data"},
2767     {"freqwithin", VT_BOOL, AJFALSE, "",
2768 	 "Individual within species frequency data"},
2769     {NULL, VT_NULL, AJFALSE, NULL,
2770 	 NULL}
2771 };
2772 
2773 
2774 static AcdOAttr acdCalcProperties[] =
2775 {
2776     {"propertylength", VT_INT, AJFALSE, "",
2777 	 "Number of property values per set"},
2778     {"propertysize", VT_INT, AJFALSE, "",
2779 	 "Number of property sets"},
2780     {NULL, VT_NULL, AJFALSE, NULL,
2781 	 NULL}
2782 };
2783 
2784 
2785 static AcdOAttr acdCalcRegexp[] =
2786 {
2787     {"length", VT_INT, AJFALSE, "",
2788 	 "The length of the regular expression"},
2789     {NULL, VT_NULL, AJFALSE, NULL,
2790 	 NULL}
2791 };
2792 
2793 
2794 static AcdOAttr acdCalcSeq[] =
2795 {
2796     {"begin", VT_INT, AJFALSE, "",
2797 	 "Start of the sequence used"},
2798     {"end", VT_INT, AJFALSE, "",
2799 	 "End of the sequence used"},
2800     {"length", VT_INT, AJFALSE, "",
2801 	  "Total length of the sequence"},
2802     {"protein", VT_BOOL, AJFALSE, "",
2803 	 "Sequence is protein"},
2804     {"nucleic", VT_BOOL, AJFALSE, "",
2805 	 "Sequence is nucleotide"},
2806     {"name", VT_STR, AJFALSE, "",
2807 	 "The name/ID/accession of the sequence"},
2808     {"usa", VT_STR, AJFALSE, "",
2809 	 "The USA of the sequence"},
2810     {NULL, VT_NULL, AJFALSE, NULL,
2811 	 NULL}
2812 };
2813 
2814 
2815 static AcdOAttr acdCalcSeqall[] =
2816 {
2817     {"begin", VT_INT, AJFALSE, "",
2818 	 "Start of the first sequence used"},
2819     {"end", VT_INT, AJFALSE, "",
2820 	 "End of the first sequence used"},
2821     {"length", VT_INT, AJFALSE, "",
2822 	 "Total length of the first sequence"},
2823     {"protein", VT_BOOL, AJFALSE, "",
2824 	 "Sequence is protein"},
2825     {"nucleic", VT_BOOL, AJFALSE, "",
2826 	 "Sequence is nucleotide"},
2827     {"name", VT_STR, AJFALSE, "",
2828 	 "The name/ID/accession of the sequence"},
2829     {"usa", VT_STR, AJFALSE, "",
2830 	 "The USA of the sequence"},
2831     {NULL, VT_NULL, AJFALSE, NULL,
2832 	 NULL}
2833 };
2834 
2835 
2836 static AcdOAttr acdCalcSeqset[] =
2837 {
2838     {"begin", VT_INT, AJFALSE, "",
2839 	 "The beginning of the selection of the sequence"},
2840     {"end", VT_INT, AJFALSE, "",
2841 	 "The end of the selection of the sequence"},
2842     {"length", VT_INT, AJFALSE, "",
2843 	 "The maximum length of the sequence set"},
2844     {"protein", VT_BOOL, AJFALSE, "",
2845 	 "Sequence set is protein"},
2846     {"nucleic", VT_BOOL, AJFALSE, "",
2847 	 "Sequence set is nucleotide"},
2848     {"name", VT_STR, AJFALSE, "",
2849 	 "The name of the sequence set"},
2850     {"usa", VT_STR, AJFALSE, "",
2851 	 "The USA of the sequence set"},
2852     {"totweight", VT_FLOAT, AJFALSE, "",
2853 	 "Total sequence weight for a set"},
2854     {"count", VT_INT, AJFALSE, "",
2855 	 "Number of sequences in the set"},
2856     {NULL, VT_NULL, AJFALSE, NULL,
2857 	 NULL}
2858 };
2859 
2860 
2861 static AcdOAttr acdCalcSeqsetall[] =
2862 {
2863     {"begin", VT_INT, AJFALSE, "",
2864 	 "The beginning of the selection of the sequence"},
2865     {"end", VT_INT, AJFALSE, "",
2866 	 "The end of the selection of the sequence"},
2867     {"length", VT_INT, AJFALSE, "",
2868 	 "The maximum length of the sequence set"},
2869     {"protein", VT_BOOL, AJFALSE, "",
2870 	 "Sequence set is protein"},
2871     {"nucleic", VT_BOOL, AJFALSE, "",
2872 	 "Sequence set is nucleotide"},
2873     {"name", VT_STR, AJFALSE, "",
2874 	 "The name of the sequence set"},
2875     {"usa", VT_STR, AJFALSE, "",
2876 	 "The USA of the sequence set"},
2877     {"totweight", VT_FLOAT, AJFALSE, "",
2878 	 "Total sequence weight for each set"},
2879     {"count", VT_INT, AJFALSE, "",
2880 	 "Number of sequences in each set"},
2881     {"multicount", VT_INT, AJFALSE, "",
2882 	 "Number of sets of sequences"},
2883     {NULL, VT_NULL, AJFALSE, NULL,
2884 	 NULL}
2885 };
2886 
2887 
2888 static AcdOAttr acdCalcString[] =
2889 {
2890     {"length", VT_INT, AJFALSE, "",
2891 	 "The length of the string"},
2892     {NULL, VT_NULL, AJFALSE, NULL,
2893 	 NULL}
2894 };
2895 
2896 
2897 static AcdOAttr acdCalcTree[] =
2898 {
2899     {"treecount", VT_INT, AJFALSE, "",
2900 	 "Number of trees"},
2901     {"speciescount", VT_INT, AJFALSE, "",
2902 	 "Number of species"},
2903     {"haslengths", VT_BOOL, AJFALSE, "",
2904 	 "Branch lengths defined"},
2905     {NULL, VT_NULL, AJFALSE, NULL,
2906 	 NULL}
2907 };
2908 
2909 
2910 
2911 
2912 /* @datastatic AcdPKey ********************************************************
2913 **
2914 ** Keywords data structure for non-ACD types (application, variable, section,
2915 ** endsection) data
2916 **
2917 ** @alias AcdSKey
2918 ** @alias AcdOKey
2919 **
2920 ** @attr Name [const char*] Keyword name
2921 ** @attr Stage [AcdEStage] Enumerated stage
2922 ** @attr Padding [ajint] Padding to alignment boundary
2923 ** @attr Attr [AcdPAttr] Type-specific attributes
2924 ** @attr KeySet [void function] Function to set value and prompt user
2925 ** @@
2926 ******************************************************************************/
2927 
2928 typedef struct AcdSKey
2929 {
2930     const char* Name;
2931     AcdEStage Stage;
2932     ajint Padding;
2933     AcdPAttr Attr;
2934     void (*KeySet)(AcdPAcd thys);
2935 } AcdOKey;
2936 
2937 #define AcdPKey AcdOKey*
2938 
2939 
2940 
2941 
2942 /* @funclist acdKeywords ******************************************************
2943 **
2944 ** Processing predefined ACD keywords (application, variable, section,
2945 ** endsection)
2946 **
2947 ******************************************************************************/
2948 
2949 AcdOKey acdKeywords[] =
2950 {
2951     {"qualifier",   QUAL_STAGE,   0,  NULL,          NULL},
2952     {"application", APPL_STAGE,   0,  acdAttrAppl,   acdSetAppl},
2953     {"variable",    VAR_STAGE,    0,  acdAttrVar,    acdSetVar},
2954     {"relations",   REL_STAGE,    0,  acdAttrRel,    acdSetRel},
2955     {"section",     SEC_STAGE,    0,  acdAttrSec,    acdSetSec},
2956     {"endsection",  ENDSEC_STAGE, 0,  acdAttrEndsec, acdSetEndsec},
2957     {NULL, BAD_STAGE, 0, NULL, NULL}
2958 };
2959 
2960 
2961 
2962 
2963 /* @datastatic AcdPOuttype ****************************************************
2964 **
2965 ** Output types data structure for utput data types and format validation
2966 **
2967 ** @alias AcdSOuttype
2968 ** @alias AcdOouttype
2969 **
2970 ** @attr Name [const char*] Output type name
2971 ** @attr Format [const char*] Default format (needs to be stored elsewhere)
2972 ** @attr Type [AjEOutfileType] AJAX Output File enumeration
2973 ** @attr Padding [ajint] Padding to alignment boundary
2974 ** @attr Prompt [const AjPStr function] Function to define standard prompt
2975 ** @attr Outformat [AjBool function] Function to test output format
2976 ** @@
2977 ******************************************************************************/
2978 
2979 typedef struct AcdSOuttype
2980 {
2981     const char* Name;
2982     const char* Format;
2983     AjEOutfileType Type;
2984     ajint Padding;
2985 
2986     const AjPStr (*Prompt)(AcdPAcd thys);
2987     AjBool (*Outformat)(const AjPStr format, ajint* iformat);
2988 
2989 } AcdOOuttype;
2990 
2991 #define AcdPOuttype AcdOOuttype*
2992 
2993 
2994 
2995 
2996 /* @funclist acdOuttype *******************************************************
2997 **
2998 ** Processing output types and their formats
2999 **
3000 ******************************************************************************/
3001 
3002 AcdOOuttype acdOuttype[] =
3003 {
3004 /*    Name             Format         Type              Padding
3005          Prompt                  Outformat */
3006     {"outassembly",   "bam",           ajEOutfileTypeAssembly, 0,
3007 	 acdPromptOutassembly,   ajAssemoutformatFind},
3008     {"outcodon",      "cut",           ajEOutfileTypeCodon, 0,
3009 	 acdPromptOutcodon,      ajCodoutformatFind},
3010     {"outcpdb",       "cpdb",          ajEOutfileTypeCPDB, 0,
3011 	 acdPromptOutcpdb,       acdOutFormatCpdb},
3012     {"outdata",       "text",          ajEOutfileTypeUnknown, 0,
3013 	 acdPromptOutdata,       acdOutFormatData},
3014     {"outdiscrete",   "phylip",        ajEOutfileTypeDiscrete, 0,
3015 	 acdPromptOutdiscrete,   acdOutFormatDiscrete},
3016     {"outdistance",   "phylip",        ajEOutfileTypeDistance, 0,
3017 	 acdPromptOutdistance,   acdOutFormatDistance},
3018     {"outfreq",       "phylip",        ajEOutfileTypeFrequency, 0,
3019 	 acdPromptOutfreq,       acdOutFormatFreq},
3020     {"outmatrix",     "emboss",        ajEOutfileTypeMatrix, 0,
3021 	 acdPromptOutmatrix,     acdOutFormatMatrix},
3022     {"outmatrixf",    "emboss",        ajEOutfileTypeMatrixF, 0,
3023 	 acdPromptOutmatrix,     acdOutFormatMatrixf},
3024     {"outobo",        "obo",           ajEOutfileTypeOBO, 0,
3025 	 acdPromptOutobo,        ajObooutformatFind},
3026     {"outproperties", "phylip",        ajEOutfileTypeProperties, 0,
3027 	 acdPromptOutproperties, acdOutFormatProperties},
3028     {"outrefseq",     "embl",          ajEOutfileTypeRefseq, 0,
3029 	 acdPromptOutrefseq,     ajRefseqoutformatFind},
3030     {"outresource",   "drcat",         ajEOutfileTypeResource, 0,
3031 	 acdPromptOutresource,   ajResourceoutformatFind},
3032     {"outscop",       "scop",          ajEOutfileTypeSCOP, 0,
3033 	 acdPromptOutscop,       acdOutFormatScop},
3034     {"outtaxon",      "tax",           ajEOutfileTypeTaxon, 0,
3035 	 acdPromptOuttaxon,      ajTaxoutformatFind},
3036     {"outtext",       "text",           ajEOutfileTypeText, 0,
3037 	 acdPromptOuttext,       ajTextoutformatFind},
3038     {"outtree",       "phylip",        ajEOutfileTypeTree, 0,
3039 	 acdPromptOuttree,       acdOutFormatTree},
3040     {"outurl",        "url",           ajEOutfileTypeURL, 0,
3041 	 acdPromptOuturl,        ajUrloutformatFind},
3042     {"outvariation",  "vcf",           ajEOutfileTypeVariation, 0,
3043 	 acdPromptOutvariation,  ajVaroutformatFind},
3044     {"outxml",        "xml",           ajEOutfileTypeXml, 0,
3045 	 acdPromptOutxml,        ajXmloutformatFind},
3046     {NULL, NULL, ajEOutfileTypeUnknown, 0, NULL, NULL}
3047 };
3048 
3049 
3050 /* Type-specific associated qualifiers which can be used positionally
3051 ** or numbered if tied to a parameter */
3052 
3053 /* "qualifier"  "default" "type" */
3054 
3055 AcdOQual acdQualAppl[] =	  /* careful: index numbers used in */
3056 				  /* acdSetQualAppl */
3057 {
3058     {"auto",       "N", "boolean", "Turn off prompts"},
3059     {"stdout",     "N", "boolean", "Write first file to standard output"},
3060     {"filter",     "N", "boolean", "Read first file from standard input, "
3061 	                           "write first file to standard output"},
3062     /* after auto and stdout so it can replace */
3063     {"options",    "N", "boolean", "Prompt for standard and additional values"},
3064     {"debug",      "N", "boolean", "Write debug output to program.dbg"},
3065     /* deprecated - to be removed in a future version */
3066 /* removed in 2.8.0
3067     {"acdlog",     "N", "boolean", "Write ACD processing log "
3068                                      "to program.acdlog"},
3069     {"acdpretty",  "N", "boolean", "Rewrite ACD file as program.acdpretty"},
3070     {"acdtable",   "N", "boolean", "Write HTML table of options"},
3071 */
3072 
3073     /* end of deprecated set */
3074     {"verbose",    "N", "boolean", "Report some/full command line options"},
3075     {"help",       "N", "boolean", "Report command line options and exit. "
3076 	                           "More information on associated and "
3077 				   "general qualifiers "
3078 				   "can be found with -help -verbose"},
3079     {"warning",    "Y", "boolean", "Report warnings"},
3080     {"error",      "Y", "boolean", "Report errors"},
3081     {"fatal",      "Y", "boolean", "Report fatal errors"},
3082     {"die",        "Y", "boolean", "Report dying program messages"},
3083     {"version",    "N", "boolean", "Report version number and exit"},
3084     {NULL, NULL, NULL, NULL}
3085 };
3086 
3087 
3088 AcdOQual acdQualAlign[] =
3089 {
3090     {"aformat",    "",  "string",  "Alignment format"},
3091     {"aextension", "",  "string",  "File name extension"},
3092     {"adirectory", "",  "string",  "Output directory"},
3093     {"aname",      "",  "string",  "Base file name"},
3094     {"awidth",     "0", "integer", "Alignment width"},
3095     {"aaccshow",   "N", "boolean", "Show accession number in the header"},
3096     {"adesshow",   "N", "boolean", "Show description in the header"},
3097     {"ausashow",   "N", "boolean", "Show the full USA in the alignment"},
3098     {"aglobal",    "N", "boolean", "Show the full sequence in alignment"},
3099     {NULL, NULL, NULL, NULL}
3100 };
3101 
3102 
3103 AcdOQual acdQualAssembly[] =
3104 {
3105     {"cbegin",     "0", "integer", "Start of the contig/consensus sequences"},
3106     {"cend",       "0", "integer", "End of the contig/consensus sequences"},
3107     {"iformat",    "",  "string",  "Input assembly format"},
3108     {"iquery",     "",  "string",  "Input query fields or ID list"},
3109     {"ioffset",    "",  "integer", "Input start position offset"},
3110     {"idbname",    "",  "string",  "User-provided database name"},
3111     {NULL, NULL, NULL, NULL}
3112 };
3113 
3114 
3115 AcdOQual acdQualCodon[] =
3116 {
3117     {"format",    "",  "string",   "Data format"},
3118     {NULL, NULL, NULL, NULL}
3119 };
3120 
3121 
3122 AcdOQual acdQualCpdb[] =
3123 {
3124     {"format",     "",  "string",   "Data format"},
3125     {NULL, NULL, NULL, NULL}
3126 };
3127 
3128 
3129 AcdOQual acdQualDirectory[] =
3130 {
3131     {"extension",  "",  "string",    "Default file extension"},
3132     {NULL, NULL, NULL, NULL}
3133 };
3134 
3135 
3136 AcdOQual acdQualDirlist[] =
3137 {
3138     {"extension",  "",  "string",    "Default file extension"},
3139     {NULL, NULL, NULL, NULL}
3140 };
3141 
3142 
3143 AcdOQual acdQualFeatures[] =
3144 {
3145     {"fformat",    "",  "string",  "Features format"},
3146     {"iquery",     "",  "string",  "Input query fields or ID list"},
3147     {"ioffset",    "",  "integer", "Input start position offset"},
3148     {"fopenfile",  "",  "string",  "Features file name"},
3149     {"fask",       "N", "boolean", "Prompt for begin/end/reverse"},
3150     {"fbegin",     "0", "integer", "Start of the features to be used"},
3151     {"fend",       "0", "integer", "End of the features to be used"},
3152     {"freverse",   "N", "boolean", "Reverse (if DNA)"},
3153     {"fcircular",  "N", "boolean", "Circular sequence features"},
3154     {NULL, NULL, NULL, NULL}
3155 };
3156 
3157 
3158 AcdOQual acdQualFeatout[] =
3159 {
3160     {"offormat",   "",  "string",  "Output feature format"},
3161     {"ofopenfile", "",  "string",  "Features file name"},
3162     {"ofextension","",  "string",  "File name extension"},
3163     {"ofdirectory","",  "string",  "Output directory"},
3164     {"ofname",     "",  "string",  "Base file name"},
3165     {"ofsingle",   "N", "boolean", "Separate file for each entry"},
3166     {NULL, NULL, NULL, NULL}
3167 };
3168 
3169 
3170 AcdOQual acdQualGraph[] =
3171 {
3172     {"gprompt",   "N", "boolean", "Graph prompting"},
3173     {"gdesc",     "",  "string",  "Graph description"},
3174     {"gtitle",    "",  "string",  "Graph title"},
3175     {"gsubtitle", "",  "string",  "Graph subtitle"},
3176     {"gxtitle",   "",  "string",  "Graph x axis title"},
3177     {"gytitle",   "",  "string",  "Graph y axis title"},
3178     {"goutfile",  "",  "string",  "Output file for non interactive displays"},
3179     {"gdirectory","",  "string",  "Output directory"},
3180     {NULL, NULL, NULL, NULL}
3181 };
3182 
3183 
3184 AcdOQual acdQualGraphxy[] =
3185 {
3186     {"gprompt",   "N", "boolean", "Graph prompting"},
3187     {"gdesc",     "",  "string",  "Graph description"},
3188     {"gtitle",    "",  "string",  "Graph title"},
3189     {"gsubtitle", "",  "string",  "Graph subtitle"},
3190     {"gxtitle",   "",  "string",  "Graph x axis title"},
3191     {"gytitle",   "",  "string",  "Graph y axis title"},
3192     {"goutfile",  "",  "string",  "Output file for non interactive displays"},
3193     {"gdirectory","",  "string",  "Output directory"},
3194     {NULL, NULL, NULL, NULL}
3195 };
3196 
3197 
3198 AcdOQual acdQualObo[] =
3199 {
3200     {"iformat",    "",  "string",  "Input obo format"},
3201     {"iquery",     "",  "string",  "Input query fields or ID list"},
3202     {"ioffset",    "",  "integer", "Input start position offset"},
3203     {"idbname",    "",  "string",  "User-provided database name"},
3204     {NULL, NULL, NULL, NULL}
3205 };
3206 
3207 
3208 AcdOQual acdQualOutassembly[] =
3209 {
3210     {"odirectory", "",  "string",  "Output directory"},
3211     {"oformat",    "",  "string",  "Assembly output format"},
3212     {NULL, NULL, NULL, NULL}
3213 };
3214 
3215 
3216 AcdOQual acdQualOutcodon[] =
3217 {
3218     {"odirectory", "",  "string",  "Output directory"},
3219     {"oformat",    "",  "string",  "Output format specific to this data type"},
3220     {NULL, NULL, NULL, NULL}
3221 };
3222 
3223 
3224 AcdOQual acdQualOutcpdb[] =
3225 {
3226     {"odirectory", "",  "string",  "Output directory"},
3227     {"oformat",    "",  "string",  "Output format specific to this data type"},
3228     {NULL, NULL, NULL, NULL}
3229 };
3230 
3231 
3232 AcdOQual acdQualOutdata[] =
3233 {
3234     {"odirectory", "",  "string",  "Output directory"},
3235     {"oformat",    "",  "string",  "Output format specific to this data type"},
3236     {NULL, NULL, NULL, NULL}
3237 };
3238 
3239 
3240 AcdOQual acdQualOutdir[] =
3241 {
3242     {"extension",  "",  "string",    "Default file extension"},
3243     {NULL, NULL, NULL, NULL}
3244 };
3245 
3246 
3247 AcdOQual acdQualOutdiscrete[] =
3248 {
3249     {"odirectory", "",  "string",  "Output directory"},
3250     {"oformat",    "",  "string",  "Output format specific to this data type"},
3251     {NULL, NULL, NULL, NULL}
3252 };
3253 
3254 
3255 AcdOQual acdQualOutdistance[] =
3256 {
3257     {"odirectory", "",  "string",  "Output directory"},
3258     {"oformat",    "",  "string",  "Output format specific to this data type"},
3259     {NULL, NULL, NULL, NULL}
3260 };
3261 
3262 
3263 AcdOQual acdQualOutfile[] =
3264 {
3265     {"odirectory", "",  "string",  "Output directory"},
3266     {NULL, NULL, NULL, NULL}
3267 };
3268 
3269 
3270 AcdOQual acdQualOutfreq[] =
3271 {
3272     {"odirectory", "",  "string",  "Output directory"},
3273     {"oformat",    "",  "string",  "Output format specific to this data type"},
3274     {NULL, NULL, NULL, NULL}
3275 };
3276 
3277 
3278 AcdOQual acdQualOutmatrix[] =
3279 {
3280     {"odirectory", "",  "string",  "Output directory"},
3281     {"oformat",    "",  "string",  "Output format specific to this data type"},
3282     {NULL, NULL, NULL, NULL}
3283 };
3284 
3285 
3286 AcdOQual acdQualOutmatrixf[] =
3287 {
3288     {"odirectory", "",  "string",  "Output directory"},
3289     {"oformat",    "",  "string",  "Output format specific to this data type"},
3290     {NULL, NULL, NULL, NULL}
3291 };
3292 
3293 
3294 AcdOQual acdQualOutobo[] =
3295 {
3296     {"odirectory", "",  "string",  "Output directory"},
3297     {"oformat",    "",  "string",  "Ontology term output format"},
3298     {NULL, NULL, NULL, NULL}
3299 };
3300 
3301 
3302 AcdOQual acdQualOutproperties[] =
3303 {
3304     {"odirectory", "",  "string",  "Output directory"},
3305     {"oformat",    "",  "string",  "Output format specific to this data type"},
3306     {NULL, NULL, NULL, NULL}
3307 };
3308 
3309 
3310 AcdOQual acdQualOutrefseq[] =
3311 {
3312     {"odirectory", "",  "string",  "Output directory"},
3313     {"oformat",    "",  "string",  "Referece sequence output format"},
3314     {NULL, NULL, NULL, NULL}
3315 };
3316 
3317 
3318 AcdOQual acdQualOutresource[] =
3319 {
3320     {"odirectory", "",  "string",  "Output directory"},
3321     {"oformat",    "",  "string",  "Data resource output format"},
3322     {NULL, NULL, NULL, NULL}
3323 };
3324 
3325 
3326 AcdOQual acdQualOutscop[] =
3327 {
3328     {"odirectory", "",  "string",  "Output directory"},
3329     {"oformat",    "",  "string",  "Output format specific to this data type"},
3330     {NULL, NULL, NULL, NULL}
3331 };
3332 
3333 
3334 AcdOQual acdQualOuttaxon[] =
3335 {
3336     {"odirectory", "",  "string",  "Output directory"},
3337     {"oformat",    "",  "string",  "Taxonomy output format"},
3338     {NULL, NULL, NULL, NULL}
3339 };
3340 
3341 
3342 AcdOQual acdQualOuttext[] =
3343 {
3344     {"odirectory", "",  "string",  "Output directory"},
3345     {"oformat",    "",  "string",  "Text output format"},
3346     {NULL, NULL, NULL, NULL}
3347 };
3348 
3349 
3350 AcdOQual acdQualOuttree[] =
3351 {
3352     {"odirectory", "",  "string",  "Output directory"},
3353     {"oformat",    "",  "string",  "Output format specific to this data type"},
3354     {NULL, NULL, NULL, NULL}
3355 };
3356 
3357 
3358 AcdOQual acdQualOuturl[] =
3359 {
3360     {"odirectory", "",  "string",  "Output directory"},
3361     {"oformat",    "",  "string",  "URL output format"},
3362     {NULL, NULL, NULL, NULL}
3363 };
3364 
3365 
3366 AcdOQual acdQualOutvariation[] =
3367 {
3368     {"odirectory", "",  "string",  "Output directory"},
3369     {"oformat",    "",  "string",  "Variation output format"},
3370     {NULL, NULL, NULL, NULL}
3371 };
3372 
3373 
3374 AcdOQual acdQualOutxml[] =
3375 {
3376     {"odirectory", "",  "string",  "Output directory"},
3377     {"oformat",    "",  "string",  "Xml output format"},
3378     {NULL, NULL, NULL, NULL}
3379 };
3380 
3381 
3382 AcdOQual acdQualPattern[] =
3383 {
3384     {"pformat",    "",  "string",  "File format"},
3385     {"pmismatch", "0",  "integer", "Pattern mismatch"},
3386     {"pname",      "",  "string",  "Pattern base name"},
3387     {NULL, NULL, NULL, NULL}
3388 };
3389 
3390 
3391 AcdOQual acdQualRefseq[] =
3392 {
3393     {"iformat",    "",  "string",  "Input reference sequence format"},
3394     {"iquery",     "",  "string",  "Input query fields or ID list"},
3395     {"ioffset",    "",  "integer", "Input start position offset"},
3396     {"idbname",    "",  "string",  "User-provided database name"},
3397     {NULL, NULL, NULL, NULL}
3398 };
3399 
3400 
3401 AcdOQual acdQualRegexp[] =
3402 {
3403     {"pformat",    "",  "string",  "File format"},
3404     {"pname",      "",  "string",  "Pattern base name"},
3405     {NULL, NULL, NULL, NULL}
3406 };
3407 
3408 
3409 AcdOQual acdQualReport[] =
3410 {
3411     {"rformat",    "",  "string",  "Report format"},
3412     {"rname",      "",  "string",  "Base file name"},
3413     {"rextension", "",  "string",  "File name extension"},
3414     {"rdirectory", "",  "string",  "Output directory"},
3415     {"raccshow",   "N", "boolean", "Show accession number in the report"},
3416     {"rdesshow",   "N", "boolean", "Show description in the report"},
3417     {"rscoreshow", "Y", "boolean", "Show the score in the report"},
3418     {"rstrandshow","Y", "boolean", "Show the nucleotide strand in the report"},
3419     {"rusashow",   "N", "boolean", "Show the full USA in the report"},
3420     {"rmaxall",    "0", "integer", "Maximum total hits to report"},
3421     {"rmaxseq",    "0", "integer", "Maximum hits to report for one sequence"},
3422     {NULL, NULL, NULL, NULL}
3423 };
3424 
3425 
3426 AcdOQual acdQualResource[] =
3427 {
3428     {"iformat",    "",  "string",  "Input resource format"},
3429     {"iquery",     "",  "string",  "Input query fields or ID list"},
3430     {"ioffset",    "",  "integer", "Input start position offset"},
3431     {"idbname",    "",  "string",  "User-provided database name"},
3432     {NULL, NULL, NULL, NULL}
3433 };
3434 
3435 
3436 AcdOQual acdQualScop[] =
3437 {
3438     {"format",    "",  "string",   "Data format"},
3439     {NULL, NULL, NULL, NULL}
3440 };
3441 
3442 
3443 AcdOQual acdQualSeq[] =
3444 {
3445     {"sbegin",     "0", "integer", "Start of the sequence to be used"},
3446     {"send",       "0", "integer", "End of the sequence to be used"},
3447     {"sreverse",   "N", "boolean", "Reverse (if DNA)"},
3448     {"sask",       "N", "boolean", "Ask for begin/end/reverse"},
3449     {"snucleotide","N", "boolean", "Sequence is nucleotide"},
3450     {"sprotein",   "N", "boolean", "Sequence is protein"},
3451     {"slower",     "N", "boolean", "Make lower case"},
3452     {"supper",     "N", "boolean", "Make upper case"},
3453     {"scircular",  "N", "boolean", "Sequence is circular"},
3454     {"squick",     "N", "boolean", "Read id and sequence only"},
3455     {"sformat",    "",  "string",  "Input sequence format"},
3456 /*    {"sopenfile",  "", "string",   "Input filename"},*/ /* obsolete */
3457     {"iquery",     "",  "string",  "Input query fields or ID list"},
3458     {"ioffset",    "",  "integer", "Input start position offset"},
3459     {"sdbname",    "",  "string",  "Database name"},
3460     {"sid",        "",  "string",  "Entryname"},
3461     {"ufo",        "",  "string",  "UFO features"},
3462     {"fformat",    "",  "string",  "Features format"},
3463     {"fopenfile",  "",  "string",  "Features file name"},
3464     {NULL, NULL, NULL, NULL}
3465 };
3466 
3467 
3468 AcdOQual acdQualSeqall[] =
3469 {
3470     {"sbegin",     "0", "integer", "Start of each sequence to be used"},
3471     {"send",       "0", "integer", "End of each sequence to be used"},
3472     {"sreverse",   "N", "boolean", "Reverse (if DNA)"},
3473     {"sask",       "N", "boolean", "Ask for begin/end/reverse"},
3474     {"snucleotide","N", "boolean", "Sequence is nucleotide"},
3475     {"sprotein",   "N", "boolean", "Sequence is protein"},
3476     {"slower",     "N", "boolean", "Make lower case"},
3477     {"supper",     "N", "boolean", "Make upper case"},
3478     {"scircular",  "N", "boolean", "Sequence is circular"},
3479     {"squick",     "N", "boolean", "Read id and sequence only"},
3480     {"sformat",    "",  "string",  "Input sequence format"},
3481 /*    {"sopenfile",  "",  "string",  "Input filename"},*/ /* obsolete */
3482     {"iquery",     "",  "string",  "Input query fields or ID list"},
3483     {"ioffset",    "",  "integer", "Input start position offset"},
3484     {"sdbname",    "",  "string",  "Database name"},
3485     {"sid",        "",  "string",  "Entryname"},
3486     {"ufo",        "",  "string",  "UFO features"},
3487     {"fformat",    "",  "string",  "Features format"},
3488     {"fopenfile",  "",  "string",  "Features file name"},
3489     {NULL, NULL, NULL, NULL}
3490 };
3491 
3492 
3493 AcdOQual acdQualSeqset[] =
3494 {
3495     {"sbegin",     "0", "integer", "Start of each sequence to be used"},
3496     {"send",       "0", "integer", "End of each sequence to be used"},
3497     {"sreverse",   "N", "boolean", "Reverse (if DNA)"},
3498     {"sask",       "N", "boolean", "Ask for begin/end/reverse"},
3499     {"snucleotide","N", "boolean", "Sequence is nucleotide"},
3500     {"sprotein",   "N", "boolean", "Sequence is protein"},
3501     {"slower",     "N", "boolean", "Make lower case"},
3502     {"supper",     "N", "boolean", "Make upper case"},
3503     {"scircular",  "N", "boolean", "Sequence is circular"},
3504     {"squick",     "N", "boolean", "Read id and sequence only"},
3505     {"sformat",    "",  "string",  "Input sequence format"},
3506 /*    {"sopenfile",  "",  "string",  "Input filename"},*/ /* obsolete */
3507     {"iquery",     "",  "string",  "Input query fields or ID list"},
3508     {"ioffset",    "",  "integer", "Input start position offset"},
3509     {"sdbname",    "",  "string",  "Database name"},
3510     {"sid",        "",  "string",  "Entryname"},
3511     {"ufo",        "",  "string",  "UFO features"},
3512     {"fformat",    "",  "string",  "Features format"},
3513     {"fopenfile",  "",  "string",  "Features file name"},
3514     {NULL, NULL, NULL, NULL}
3515 };
3516 
3517 
3518 AcdOQual acdQualSeqsetall[] =
3519 {
3520     {"sbegin",     "0", "integer", "Start of each sequence to be used"},
3521     {"send",       "0", "integer", "End of each sequence to be used"},
3522     {"sreverse",   "N", "boolean", "Reverse (if DNA)"},
3523     {"sask",       "N", "boolean", "Ask for begin/end/reverse"},
3524     {"snucleotide","N", "boolean", "Sequence is nucleotide"},
3525     {"sprotein",   "N", "boolean", "Sequence is protein"},
3526     {"slower",     "N", "boolean", "Make lower case"},
3527     {"supper",     "N", "boolean", "Make upper case"},
3528     {"scircular",  "N", "boolean", "Sequence is circular"},
3529     {"squick",     "N", "boolean", "Read id and sequence only"},
3530     {"sformat",    "",  "string",  "Input sequence format"},
3531 /*    {"sopenfile",  "",  "string",  "Input filename"},*/ /* obsolete */
3532     {"iquery",     "",  "string",  "Input query fields or ID list"},
3533     {"ioffset",    "",  "integer", "Input start position offset"},
3534     {"sdbname",    "",  "string",  "Database name"},
3535     {"sid",        "",  "string",  "Entryname"},
3536     {"ufo",        "",  "string",  "UFO features"},
3537     {"fformat",    "",  "string",  "Features format"},
3538     {"fopenfile",  "",  "string",  "Features file name"},
3539     {NULL, NULL, NULL, NULL}
3540 };
3541 
3542 
3543 AcdOQual acdQualSeqout[] =
3544 {
3545     {"osformat",   "",  "string",  "Output seq format"},
3546     {"osextension","",  "string",  "File name extension"},
3547     {"osname",     "",  "string",  "Base file name"},
3548     {"osdirectory","",  "string",  "Output directory"},
3549     {"osdbname",   "",  "string",  "Database name to add"},
3550     {"ossingle",   "N", "boolean", "Separate file for each entry"},
3551     {"oufo",       "",  "string",  "UFO features"},
3552     {"offormat",   "",  "string",  "Features format"},
3553     {"ofname",     "",  "string",  "Features file name"},
3554     {"ofdirectory","",  "string",  "Output directory"},
3555     {NULL, NULL, NULL, NULL}
3556 };
3557 
3558 
3559 AcdOQual acdQualSeqoutset[] =
3560 {
3561     {"osformat",   "",  "string",  "Output seq format"},
3562     {"osextension","",  "string",  "File name extension"},
3563     {"osname",     "",  "string",  "Base file name"},
3564     {"osdirectory","",  "string",  "Output directory"},
3565     {"osdbname",   "",  "string",  "Database name to add"},
3566     {"ossingle",   "N", "boolean", "Separate file for each entry"},
3567     {"oufo",       "",  "string",  "UFO features"},
3568     {"offormat",   "",  "string",  "Features format"},
3569     {"ofname",     "",  "string",  "Features file name"},
3570     {"ofdirectory","",  "string",  "Output directory"},
3571     {NULL, NULL, NULL, NULL}
3572 };
3573 
3574 
3575 AcdOQual acdQualSeqoutall[] =
3576 {
3577     {"osformat",   "",  "string",  "Output seq format"},
3578     {"osextension","",  "string",  "File name extension"},
3579     {"osname",     "",  "string",  "Base file name"},
3580     {"osdirectory","",  "string",  "Output directory"},
3581     {"osdbname",   "",  "string",  "Database name to add"},
3582     {"ossingle",   "N", "boolean", "Separate file for each entry"},
3583     {"oufo",       "",  "string",  "UFO features"},
3584     {"offormat",   "",  "string",  "Features format"},
3585     {"ofname",     "",  "string",  "Features file name"},
3586     {"ofdirectory","",  "string",  "Output directory"},
3587     {NULL, NULL, NULL, NULL}
3588 };
3589 
3590 AcdOQual acdQualTaxon[] =
3591 {
3592     {"iformat",    "",  "string",  "Input taxonomy format"},
3593     {"iquery",     "",  "string",  "Input query fields or ID list"},
3594     {"ioffset",    "",  "integer", "Input start position offset"},
3595     {"idbname",    "",  "string",  "User-provided database name"},
3596     {NULL, NULL, NULL, NULL}
3597 };
3598 
3599 
3600 AcdOQual acdQualText[] =
3601 {
3602     {"iformat",    "",  "string",  "Input text format"},
3603     {"iquery",     "",  "string",  "Input query fields or ID list"},
3604     {"ioffset",    "",  "integer", "Input start position offset"},
3605     {"idbname",    "",  "string",  "User-provided database name"},
3606     {NULL, NULL, NULL, NULL}
3607 };
3608 
3609 
3610 AcdOQual acdQualUrl[] =
3611 {
3612     {"iformat",    "",  "string",  "Input URL format"},
3613     {"idbname",    "",  "string",  "User-provided database name"},
3614     {"swiss",      "N", "boolean", "Swissprot cross-reference"},
3615     {"embl",       "N", "boolean", "EMBL/GenBank/DDBJ cross-reference"},
3616     {"accession",  "",  "string",  "Primary accession for source data"},
3617     {"identifier", "",  "string",  "Identifier term name in EDAM"},
3618     {NULL, NULL, NULL, NULL}
3619 };
3620 
3621 
3622 AcdOQual acdQualVariation[] =
3623 {
3624     {"iformat",    "",  "string",  "Input variation format"},
3625     {"iquery",     "",  "string",  "Input query fields or ID list"},
3626     {"ioffset",    "",  "integer", "Input start position offset"},
3627     {"idbname",    "",  "string",  "User-provided database name"},
3628     {NULL, NULL, NULL, NULL}
3629 };
3630 
3631 
3632 AcdOQual acdQualXml[] =
3633 {
3634     {"iformat",    "",  "string",  "Input xml format"},
3635     {"iquery",     "",  "string",  "Input query fields or ID list"},
3636     {"ioffset",    "",  "integer", "Input start position offset"},
3637     {"idbname",    "",  "string",  "User-provided database name"},
3638     {NULL, NULL, NULL, NULL}
3639 };
3640 
3641 
3642 /* Type definitions - must be after attributes and functions are defined
3643 ** Add new types here as needed
3644 ** Create attribute list acdAttrType
3645 */
3646 
3647 /*
3648    "Type"         Attributes        Function
3649    Qualifiers     "Help Text"
3650 */
3651 
3652 
3653 
3654 
3655 /* @funclist acdType **********************************************************
3656 **
3657 ** Processing for ACD types
3658 **
3659 ** Includes the acdSet functions for each ACD type
3660 **
3661 ******************************************************************************/
3662 
3663 AcdOType acdType[] =
3664 {
3665 /*   Name               Group       Section
3666 **       Attributes             Qualifiers
3667 **       SetFunction            HelpFunction           Destructor
3668 **       PassRef  StdPrompt PromptFunction     UseCount      UseClassCount
3669 **       Description of valid string for help */
3670     {"align",          "output",    acdSecOutput,
3671 	 acdAttrAlign,          acdQualAlign,
3672 	 &acdSetAlign,          NULL,                  &acdDelAlign,
3673 	 AJTRUE,  AJTRUE,  &acdPromptAlign,    &acdUseAlign, &acdUseOut,
3674 	 "Alignment output file" },
3675     {"array",          "simple",    NULL,
3676 	 acdAttrArray,          NULL,
3677 	 &acdSetArray,          NULL,                  &acdDelFloat,
3678 	 AJTRUE,  AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3679 	 "List of floating point numbers" },
3680     {"assembly",       "input",     acdSecInput,
3681 	 acdAttrAssembly,       acdQualAssembly,
3682 	 &acdSetAssembly,       NULL,                  &acdDelAssembly,
3683 	 AJTRUE,  AJTRUE,  &acdPromptAssembly, &acdUseData, &acdUseIn,
3684 	 "Assembly of sequence reads" },
3685     {"boolean",        "simple",    NULL,
3686 	 acdAttrBool,           NULL,
3687 	 &acdSetBoolean,        NULL,                  &acdFree,
3688 	 AJFALSE, AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3689 	 "Boolean value Yes/No" },
3690     {"codon",	       "input",     acdSecInput,
3691 	 acdAttrCodon,          acdQualCodon,
3692 	 &acdSetCodon,          NULL,                  &acdDelCod,
3693 	 AJTRUE,  AJTRUE,  &acdPromptCodon,    &acdUseData, &acdUseIn,
3694 	 "Codon usage file in EMBOSS data path" },
3695     {"cpdb",           "input",     acdSecInput,
3696 	 acdAttrCpdb,           acdQualCpdb,
3697 	 &acdSetCpdb,           NULL,                  &acdDelFile,
3698 	 AJTRUE,  AJTRUE,  acdPromptCpdb,      &acdUseInfile, &acdUseIn,
3699 	 "Clean PDB file" },
3700     {"datafile",       "input",     acdSecInput,
3701 	 acdAttrDatafile,       NULL,
3702 	 &acdSetDatafile,       NULL,                  &acdDelFile,
3703 	 AJTRUE,  AJTRUE,  &acdPromptDatafile, &acdUseData, &acdUseIn,
3704 	 "Data file" },
3705     {"directory",      "input",     acdSecInput,
3706 	 acdAttrDirectory,      acdQualDirectory,
3707 	 &acdSetDirectory,      NULL,                  &acdDelDir,
3708 	 AJTRUE,  AJTRUE,  &acdPromptDirectory,&acdUseMisc, &acdUseIn,
3709 	 "Directory" },
3710     {"dirlist",	       "input",     acdSecInput,
3711 	 acdAttrDirlist,        acdQualDirlist,
3712 	 &acdSetDirlist,        NULL,                  &acdDelList,
3713 	 AJTRUE,  AJTRUE,  &acdPromptDirlist,  &acdUseMisc, &acdUseIn,
3714 	 "Directory with files" },
3715     {"discretestates", "input",     acdSecInput,
3716 	 acdAttrDiscretestates, NULL,
3717 	 &acdSetDiscretestates, NULL,                  &acdDelPhyloState,
3718 	 AJTRUE,  AJTRUE,  &acdPromptDiscretestates, &acdUseData, &acdUseIn,
3719 	 "Discrete states file" },
3720     {"distances",      "input",     acdSecInput,
3721 	 acdAttrDistances,      NULL,
3722 	 &acdSetDistances,      NULL,                  &acdDelPhyloDist,
3723 	 AJTRUE,  AJTRUE,  &acdPromptDistances, &acdUseData, &acdUseIn,
3724 	 "Distance matrix" },
3725     {"featout",        "output",    acdSecOutput,
3726 	 acdAttrFeatout,        acdQualFeatout,
3727 	 &acdSetFeatout,        NULL,                  &acdDelFeattabOut,
3728 	 AJTRUE,  AJTRUE,  &acdPromptFeatout,  &acdUseFeatout, &acdUseOut,
3729 	 "Writeable feature table" },
3730     {"features",       "input",     acdSecInput,
3731 	 acdAttrFeatures,       acdQualFeatures,
3732 	 &acdSetFeatures,       NULL,                  &acdDelFeattable,
3733 	 AJTRUE,  AJTRUE,  &acdPromptFeatures, &acdUseFeatures, &acdUseIn,
3734 	 "Readable feature table" },
3735     {"filelist",       "input",     acdSecInput,
3736 	 acdAttrFilelist,       NULL,
3737 	 &acdSetFilelist,       NULL,                  &acdDelList,
3738 	 AJTRUE,  AJTRUE,  &acdPromptFilelist, &acdUseMisc, &acdUseIn,
3739 	 "Comma-separated file list" },
3740     {"float",          "simple",    NULL,
3741 	 acdAttrFloat,          NULL,
3742 	 &acdSetFloat,          NULL,                  &acdFree,
3743 	 AJFALSE, AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3744 	 "Floating point number" },
3745     {"frequencies",    "input",     acdSecInput,
3746 	 acdAttrFrequencies,    NULL,
3747 	 &acdSetFrequencies,    NULL,                  &acdDelPhyloFreq,
3748 	 AJTRUE,  AJTRUE,   &acdPromptFrequencies, &acdUseData, &acdUseIn,
3749 	 "Frequency value(s)" },
3750     {"graph",          "graph",     acdSecOutput,
3751 	 acdAttrGraph,          acdQualGraph,
3752 	 &acdSetGraph,          NULL,                  &acdFree,
3753 	 AJTRUE,  AJTRUE,  &acdPromptGraph,    &acdUseGraph, &acdUseOut,
3754 	 "Graph device for a general graph" },
3755     {"infile",         "input",     acdSecInput,
3756 	 acdAttrInfile,         NULL,
3757 	 &acdSetInfile,          NULL,                  &acdDelFile,
3758 	 AJTRUE,  AJTRUE,  &acdPromptInfile,   &acdUseInfile, &acdUseIn,
3759 	 "Input file" },
3760     {"integer",        "simple",    NULL,
3761 	 acdAttrInt,            NULL,
3762 	 &acdSetInt,            NULL,                  &acdFree,
3763 	 AJFALSE, AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3764 	 "Integer" },
3765     {"list",           "selection", NULL,
3766 	 acdAttrList,           NULL,
3767 	 acdSetList,            NULL,                  acdDelStrArray,
3768 	 AJTRUE,  AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3769 	 "Choose from menu list of values" },
3770     {"matrix",         "input",     acdSecInput,
3771 	 acdAttrMatrix,         NULL,
3772 	 &acdSetMatrix,         NULL,                  &acdDelMatrix,
3773 	 AJTRUE,  AJFALSE, &acdPromptMatrix,   &acdUseData, &acdUseIn,
3774 	 "Comparison matrix file in EMBOSS data path" },
3775     {"matrixf",        "input",     acdSecInput,
3776 	 acdAttrMatrixf,        NULL,
3777 	 &acdSetMatrixf,        NULL,                  &acdDelMatrixf,
3778 	 AJTRUE,  AJFALSE, &acdPromptMatrix,   &acdUseData, &acdUseIn,
3779 	 "Comparison matrix file in EMBOSS data path" },
3780     {"obo",            "input",     acdSecInput,
3781 	 acdAttrObo,            acdQualObo,
3782 	 &acdSetObo,            &acdHelpTextObo,       &acdDelObo,
3783 	 AJTRUE,  AJTRUE,  &acdPromptObo,      &acdUseData, &acdUseIn,
3784 	 "OBO bio-ontology term(s)" },
3785     {"outassembly",     "output",    acdSecOutput,
3786 	 acdAttrOutassembly,    acdQualOutassembly,
3787 	 &acdSetOutassembly,    NULL,                  &acdDelOutfile,
3788 	 AJTRUE,  AJTRUE,  &acdPromptOutassembly, &acdUseOutfile, &acdUseOut,
3789 	 "Assembly of sequence reads" },
3790     {"outcodon",       "output",    acdSecOutput,
3791 	 acdAttrOutcodon,       acdQualOutcodon,
3792 	 &acdSetOutcodon,       NULL,                  &acdDelOutfile,
3793 	 AJTRUE,  AJTRUE,  &acdPromptOutcodon, &acdUseOutfile, &acdUseOut,
3794 	 "Codon usage file" },
3795     {"outcpdb",        "output",    acdSecOutput,
3796 	 acdAttrOutcpdb,        NULL,
3797 	 &acdSetOutcpdb,        NULL,                  &acdDelOutfile,
3798 	 AJTRUE,  AJTRUE,  &acdPromptOutcpdb,  &acdUseOutfile, &acdUseOut,
3799 	 "Cleaned PDB file" },
3800     {"outdata",        "output",    acdSecOutput,
3801 	 acdAttrOutdata,        acdQualOutdata,
3802 	 &acdSetOutdata,        NULL,                  &acdDelOutfile,
3803 	 AJTRUE,  AJTRUE,  &acdPromptOutdata,  &acdUseOutfile, &acdUseOut,
3804 	 "Formatted output file" },
3805     {"outdir",         "output",    acdSecOutput,
3806 	 acdAttrOutdir,         acdQualOutdir,
3807 	 &acdSetOutdir,         NULL,                  &acdDelDirout,
3808 	 AJTRUE,  AJTRUE,  &acdPromptOutdir,   &acdUseMisc, &acdUseOut,
3809 	 "Output directory" },
3810     {"outdiscrete",    "output",    acdSecOutput,
3811 	 acdAttrOutdiscrete,    acdQualOutdiscrete,
3812 	 &acdSetOutdiscrete,    NULL,                  &acdDelOutfile,
3813 	 AJTRUE,  AJTRUE,  &acdPromptOutdiscrete, &acdUseOutfile, &acdUseOut,
3814 	 "Discrete states file" },
3815     {"outdistance",    "output",    acdSecOutput,
3816 	 acdAttrOutdistance,    NULL,
3817 	 &acdSetOutdistance,    NULL,                  &acdDelOutfile,
3818 	 AJTRUE,  AJTRUE,  &acdPromptOutdistance, &acdUseOutfile, &acdUseOut,
3819 	 "Distance matrix" },
3820     {"outfile",        "output",     acdSecOutput,
3821 	 acdAttrOutfile,        acdQualOutfile,
3822 	 &acdSetOutfile,        NULL,                  &acdDelFile,
3823 	 AJTRUE,  AJTRUE,  &acdPromptOutfile,    &acdUseOutfile, &acdUseOut,
3824 	 "Output file" },
3825     {"outfreq",        "output",    acdSecOutput,
3826 	 acdAttrOutfreq,        acdQualOutfreq,
3827 	 &acdSetOutfreq,        NULL,                  &acdDelOutfile,
3828 	 AJTRUE,  AJTRUE,  &acdPromptOutfreq,    &acdUseOutfile, &acdUseOut,
3829 	 "Frequency value(s)" },
3830     {"outmatrix",      "output",    acdSecOutput,
3831 	 acdAttrOutmatrix,      acdQualOutmatrix,
3832 	 &acdSetOutmatrix,      NULL,                  &acdDelOutfile,
3833 	 AJTRUE,  AJTRUE,  &acdPromptOutmatrix,  &acdUseOutfile, &acdUseOut,
3834 	 "Comparison matrix file" },
3835     {"outmatrixf",     "output",    acdSecOutput,
3836 	 acdAttrOutmatrixf,     acdQualOutmatrixf,
3837 	 &acdSetOutmatrixf,     NULL,                  &acdDelOutfile,
3838 	 AJTRUE,  AJTRUE,  &acdPromptOutmatrix,  &acdUseOutfile, &acdUseOut,
3839 	 "Comparison matrix file" },
3840     {"outobo",         "output",    acdSecOutput,
3841          acdAttrOutobo,         acdQualOutobo,
3842 	 &acdSetOutobo,         NULL,                  &acdDelOutfile,
3843 	 AJTRUE,  AJTRUE,  &acdPromptOutobo,     &acdUseOutfile, &acdUseOut,
3844 	 "OBO ontology term(s)" },
3845     {"outproperties",  "output",    acdSecOutput,
3846 	 acdAttrOutproperties,  acdQualOutproperties,
3847 	 &acdSetOutproperties,  NULL,                  &acdDelOutfile,
3848 	 AJTRUE,  AJTRUE,  &acdPromptOutproperties, &acdUseOutfile, &acdUseOut,
3849 	 "Property value(s)" },
3850     {"outrefseq",       "output",    acdSecOutput,
3851 	 acdAttrOutrefseq,      acdQualOutrefseq,
3852 	 &acdSetOutrefseq,      NULL,                  &acdDelOutfile,
3853 	 AJTRUE,  AJTRUE,  &acdPromptOutrefseq,   &acdUseOutfile, &acdUseOut,
3854 	 "Reference sequence" },
3855     {"outresource",    "output",    acdSecOutput,
3856          acdAttrOutresource,    acdQualOutresource,
3857 	 &acdSetOutresource,    NULL,                  &acdDelOutfile,
3858          AJTRUE,  AJTRUE,  &acdPromptOutresource, &acdUseOutfile, &acdUseOut,
3859 	 "Data resource entry" },
3860     {"outscop",        "output",    acdSecOutput,
3861 	 acdAttrOutscop,        acdQualOutscop,
3862 	 &acdSetOutscop,        NULL,                  &acdDelOutfile,
3863 	 AJTRUE,  AJTRUE,  &acdPromptOutscop,    &acdUseOutfile, &acdUseOut,
3864 	 "Scop entry" },
3865     {"outtaxon",       "output",    acdSecOutput,
3866          acdAttrOuttaxon,       acdQualOuttaxon,
3867 	 &acdSetOuttaxon,       NULL,                  &acdDelOutfile,
3868 	 AJTRUE,  AJTRUE,  &acdPromptOuttaxon,   &acdUseOutfile, &acdUseOut,
3869 	 "NCBI taxonomy entries" },
3870     {"outtext",        "output",    acdSecOutput,
3871          acdAttrOuttext,        acdQualOuttext,
3872 	 &acdSetOuttext,        NULL,                  &acdDelOutfile,
3873 	 AJTRUE,  AJTRUE,  &acdPromptOuttext,    &acdUseOutfile, &acdUseOut,
3874 	 "Text entries" },
3875     {"outtree",        "output",    acdSecOutput,
3876 	 acdAttrOuttree,        acdQualOuttree,
3877 	 &acdSetOuttree,        NULL,                  &acdDelOutfile,
3878 	 AJTRUE,  AJTRUE,  &acdPromptOuttree,    &acdUseOutfile, &acdUseOut,
3879 	 "Phylogenetic tree" },
3880     {"outurl",         "output",    acdSecOutput,
3881          acdAttrOuturl,         acdQualOuturl,
3882 	 &acdSetOuturl,         NULL,                  &acdDelOutfile,
3883 	 AJTRUE,  AJTRUE,  &acdPromptOuturl,     &acdUseOutfile, &acdUseOut,
3884 	 "URL entries" },
3885     {"outvariation",   "output",    acdSecOutput,
3886          acdAttrOutvariation,   acdQualOutvariation,
3887 	 &acdSetOutvariation,   NULL,                  &acdDelOutfile,
3888 	 AJTRUE,  AJTRUE,  &acdPromptOutvariation, &acdUseOutfile, &acdUseOut,
3889 	 "Variation entries" },
3890     {"outxml",     "output",    acdSecOutput,
3891 	 acdAttrOutxml,    acdQualOutxml,
3892 	 acdSetOutxml,     NULL,                  acdDelOutfile,
3893 	 AJTRUE,  AJTRUE,  acdPromptOutxml,  &acdUseOutfile, &acdUseOut,
3894 	 "Xml" },
3895     {"pattern",       "input",     acdSecInput,
3896 	 acdAttrPattern,        acdQualPattern,
3897 	 &acdSetPattern,        NULL,                  &acdDelPatlist,
3898 	 AJTRUE,  AJTRUE,  &acdPromptPattern,     &acdUseData, &acdUseIn,
3899 	 "Property value(s)" },
3900     {"properties",     "input",     acdSecInput,
3901 	 acdAttrProperties,     NULL,
3902 	 &acdSetProperties,     NULL,                  &acdDelPhyloProp,
3903 	 AJTRUE,  AJTRUE,  &acdPromptProperties, &acdUseData, &acdUseIn,
3904 	 "Property value(s)" },
3905     {"range",	       "simple",    NULL,
3906 	 acdAttrRange,          NULL,
3907 	 &acdSetRange,          NULL,                  &acdDelRange,
3908 	 AJTRUE,  AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3909 	 "Sequence range" },
3910     {"refseq",         "input",     acdSecInput,
3911 	 acdAttrRefseq,         acdQualRefseq,
3912 	 &acdSetRefseq,         NULL,                  &acdDelRefseq,
3913 	 AJTRUE,  AJTRUE,  &acdPromptRefseq, &acdUseData, &acdUseIn,
3914 	 "Reference sequence" },
3915     {"regexp",	       "input",     acdSecInput,
3916 	 acdAttrRegexp,         acdQualRegexp,
3917 	 &acdSetRegexp,         NULL,                  &acdDelReg,
3918 	 AJTRUE,  AJTRUE, &acdPromptRegexp,    &acdUseMisc, &acdUseIn,
3919 	 "Regular expression pattern" },
3920     {"report",         "output",    acdSecOutput,
3921 	 acdAttrReport,         acdQualReport,
3922 	 &acdSetReport,         NULL,                  &acdDelReport,
3923 	 AJTRUE,  AJTRUE,  &acdPromptReport,   &acdUseReport, &acdUseOut,
3924 	 "Report output file" },
3925     {"resource",       "input",     acdSecInput,
3926          acdAttrResource,       acdQualResource,
3927 	 &acdSetResource,       &acdHelpTextResource,  &acdDelResource,
3928 	 AJTRUE,  AJTRUE,  &acdPromptResource, &acdUseData, &acdUseIn,
3929 	 "Data resource catalogue entry(s)" },
3930     {"scop",           "input",     acdSecInput,
3931 	 acdAttrScop,           acdQualScop,
3932 	 &acdSetScop,           NULL,                  &acdDelFile,
3933 	 AJTRUE,  AJTRUE,  &acdPromptScop,     &acdUseInfile, &acdUseIn,
3934 	 "Clean PDB file" },
3935     {"selection",      "selection", NULL,
3936 	 acdAttrSelect,         NULL,
3937 	 &acdSetSelect,         NULL,                  &acdDelStrArray,
3938 	 AJTRUE,  AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3939 	 "Choose from selection list of values" },
3940     {"sequence",       "input",     acdSecInput,
3941 	 acdAttrSeq,            acdQualSeq,
3942 	 &acdSetSeq,            &acdHelpTextSeq,       &acdDelSeq,
3943 	 AJTRUE,  AJTRUE,  &acdPromptSeq,      &acdUseSeq, &acdUseIn,
3944 	 "Readable sequence" },
3945     {"seqall",         "input",     acdSecInput,
3946 	 acdAttrSeqall,         acdQualSeqall,
3947 	 &acdSetSeqall,         &acdHelpTextSeq,       &acdDelSeqall,
3948 	 AJTRUE,  AJTRUE,  &acdPromptSeq,      &acdUseSeq, &acdUseIn,
3949 	 "Readable sequence(s)" },
3950     {"seqout",         "output",    acdSecOutput,
3951 	 acdAttrSeqout,         acdQualSeqout,
3952 	 &acdSetSeqout,         &acdHelpTextSeqout,    &acdDelSeqout,
3953 	 AJTRUE,  AJTRUE,  &acdPromptSeqout,   &acdUseSeqout, &acdUseOut,
3954 	 "Writeable sequence" },
3955     {"seqoutall",      "output",    acdSecOutput,
3956 	 acdAttrSeqoutall,      acdQualSeqoutall,
3957 	 &acdSetSeqoutall,      &acdHelpTextSeqout,    &acdDelSeqout,
3958 	 AJTRUE,  AJTRUE,  &acdPromptSeqout,   &acdUseSeqout, &acdUseOut,
3959 	 "Writeable sequence(s)" },
3960     {"seqoutset",      "output",    acdSecOutput,
3961 	 acdAttrSeqoutset,      acdQualSeqoutset,
3962 	 &acdSetSeqoutset,      &acdHelpTextSeqout,    &acdDelSeqout,
3963 	 AJTRUE,  AJTRUE,  &acdPromptSeqout,   &acdUseSeqout, &acdUseOut,
3964 	 "Writeable sequences" },
3965     {"seqset",         "input",     acdSecInput,
3966 	 acdAttrSeqset,         acdQualSeqset,
3967 	 &acdSetSeqset,         &acdHelpTextSeq,       &acdDelSeqset,
3968 	 AJTRUE,  AJTRUE,  &acdPromptSeq,      &acdUseSeq, &acdUseIn,
3969 	 "Readable set of sequences" },
3970     {"seqsetall",      "input",     acdSecInput,
3971 	 acdAttrSeqsetall,      acdQualSeqsetall,
3972 	 &acdSetSeqsetall,      &acdHelpTextSeq,       &acdDelSeqsetArray,
3973 	 AJTRUE,  AJTRUE,  &acdPromptSeq,      &acdUseSeq, &acdUseIn,
3974 	 "Readable sets of sequences" },
3975     {"string",         "simple",    NULL,
3976 	 acdAttrString,          NULL,
3977 	 acdSetString,           NULL,                 acdDelStr,
3978 	 AJTRUE,  AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3979 	 "String value" },
3980     {"taxon",          "input",     acdSecInput,
3981 	 acdAttrTaxon,           acdQualTaxon,
3982 	 &acdSetTaxon,           &acdHelpTextTaxon,    &acdDelTaxon,
3983 	 AJTRUE,  AJTRUE,  &acdPromptTaxon,      &acdUseData, &acdUseIn,
3984 	 "NCBI taxonomy entries" },
3985     {"text",           "input",     acdSecInput,
3986 	 acdAttrText,            acdQualText,
3987 	 &acdSetText,            &acdHelpTextText,     &acdDelText,
3988 	 AJTRUE,  AJTRUE,  &acdPromptText,       &acdUseData, &acdUseIn,
3989 	 "Text entries" },
3990     {"toggle",         "simple",     NULL,
3991 	 acdAttrToggle,          NULL,
3992 	 &acdSetToggle,          NULL,                 &acdFree,
3993 	 AJFALSE, AJFALSE, NULL,               &acdUseMisc, &acdUseMisc,
3994 	 "Toggle value Yes/No" },
3995     {"tree",           "input",      acdSecInput,
3996 	 acdAttrTree,            NULL,
3997 	 &acdSetTree,            NULL,                 &acdDelPhyloTree,
3998 	 AJTRUE,  AJTRUE,  &acdPromptTree,     &acdUseData, &acdUseIn,
3999 	 "Phylogenetic tree" },
4000     {"url",            "input",     acdSecInput,
4001 	 acdAttrUrl,             acdQualUrl,
4002 	 &acdSetUrl,             &acdHelpTextUrl,       &acdDelUrl,
4003 	 AJTRUE,  AJTRUE,  &acdPromptUrl,        &acdUseData, &acdUseIn,
4004 	 "URL entries" },
4005     {"variation",      "input",     acdSecInput,
4006 	 acdAttrVariation,       acdQualVariation,
4007 	 &acdSetVariation,       &acdHelpTextVariation, &acdDelVariation,
4008 	 AJTRUE,  AJTRUE,  &acdPromptVariation,  &acdUseData, &acdUseIn,
4009 	 "Variation entries" },
4010     {"xml",       "input",     acdSecInput,
4011 	 acdAttrXml,       acdQualXml,
4012 	 acdSetXml,        acdHelpTextXml,   acdDelXml,
4013 	 AJTRUE,  AJTRUE,  acdPromptXml,  &acdUseData, &acdUseIn,
4014 	 "Xml" },
4015     {"xygraph",        "graph",      acdSecOutput,
4016 	 acdAttrGraphxy,         acdQualGraphxy,
4017 	 &acdSetGraphxy,         NULL,                 &acdFree,
4018 	 AJTRUE,  AJTRUE,  &acdPromptGraph,    &acdUseGraph, &acdUseOut,
4019 	 "Graph device for a 2D graph" },
4020      {NULL, NULL, NULL,   NULL, NULL,   NULL, NULL, NULL,
4021 	  AJFALSE, AJFALSE, 0, NULL, NULL,    NULL}
4022 };
4023 
4024 
4025 
4026 
4027 /* @datastatic AcdPValid ******************************************************
4028 **
4029 ** ACD valid input structure. For each ACD type, stores functions
4030 ** that reports on valid input and expected values
4031 **
4032 ** @alias AcdSValid
4033 ** @alias AcdOValid
4034 **
4035 ** @attr Name [const char*] ACD type name
4036 ** @attr Valid [void function]  Function to report valid values in general
4037 ** @attr Expect [void function] Function to report expected values
4038 **                              for this definition
4039 ** @@
4040 ******************************************************************************/
4041 
4042 typedef struct AcdSValid
4043 {
4044     const char* Name;
4045     void (*Valid) (const AcdPAcd thys, AjBool table, AjPStr* str);
4046     void (*Expect) (const AcdPAcd thys, AjBool table, AjPStr* str);
4047 } AcdOValid;
4048 
4049 #define AcdPValid AcdOValid*
4050 
4051 
4052 
4053 
4054 /* @funclist acdValue *********************************************************
4055 **
4056 ** ACD type help processing, includes functions to describe valid
4057 ** values and expected values in -help output and -acdtable output
4058 **
4059 ******************************************************************************/
4060 
4061 AcdOValid acdValue[] =
4062 {
4063     {"align",     acdHelpValidAlign,    acdHelpExpectOut},
4064     {"codon",     acdHelpValidCodon,    acdHelpExpectCodon},
4065     {"datafile",  acdHelpValidData,     acdHelpExpectData},
4066     {"dirlist",   acdHelpValidDirlist,  acdHelpExpectDirlist},
4067     {"featout",   acdHelpValidFeatout,  acdHelpExpectFeatout},
4068     {"features",  acdHelpValidFeatures, acdHelpExpectFeatures},
4069     {"filelist",  acdHelpValidFilelist, acdHelpExpectFilelist},
4070     {"float",     acdHelpValidFloat,    acdHelpExpectFloat},
4071     {"graph",     acdHelpValidGraph,    acdHelpExpectGraph},
4072     {"infile",    acdHelpValidIn,       acdHelpExpectIn},
4073     {"integer",   acdHelpValidInt,      acdHelpExpectInt},
4074     {"list",      acdHelpValidList,     NULL},
4075     {"matrix",    acdHelpValidMatrix,   acdHelpExpectMatrix},
4076     {"matrixf",   acdHelpValidMatrix,   acdHelpExpectMatrix},
4077     {"outfile",   acdHelpValidOut,      acdHelpExpectOut},
4078     {"outobo",    acdHelpValidOut,      acdHelpExpectOut},
4079     {"outresource", acdHelpValidOut,    acdHelpExpectOut},
4080     {"regexp",    acdHelpValidRegexp,   acdHelpExpectRegexp},
4081     {"report",    acdHelpValidReport,   acdHelpExpectOut},
4082     {"select",    acdHelpValidSelect,   NULL},
4083     {"seqall",    acdHelpValidSeq,      acdHelpExpectSeq},
4084     {"seqset",    acdHelpValidSeq,      acdHelpExpectSeq},
4085     {"seqsetall", acdHelpValidSeq,      acdHelpExpectSeq},
4086     {"sequence",  acdHelpValidSeq,      acdHelpExpectSeq},
4087     {"seqout",    acdHelpValidSeqout,   acdHelpExpectSeqout},
4088     {"seqoutall", acdHelpValidSeqout,   acdHelpExpectSeqout},
4089     {"seqoutset", acdHelpValidSeqout,   acdHelpExpectSeqout},
4090     {"string",    acdHelpValidString,   acdHelpExpectString},
4091     {"range",     acdHelpValidRange,    acdHelpExpectRange},
4092     {"xygraph",   acdHelpValidGraph,    acdHelpExpectGraph},
4093     {NULL,        NULL, NULL}
4094 };
4095 
4096 
4097 static const char* acdResource[] =
4098 {
4099     "genetic code",
4100     NULL
4101 };
4102 
4103 
4104 /*** command line retrieval routines ***/
4105 
4106 
4107 
4108 
4109 /* @section initialisation ****************************************************
4110 **
4111 ** Initialises everything needed for ACD processing.
4112 **
4113 ** @fdata [none]
4114 **
4115 ** @nam3rule  Init    Initialise internals
4116 **
4117 ** @argrule   Init    pgm [const char*] Program name
4118 ** @argrule   Init    argc [ajint] Number of command line arguments
4119 ** @argrule   Init    argv [char* const[]] Command line arguments
4120 ** @argrule   P    package [const char*] Package name (empty for default name)
4121 ** @argrule   V    packversion [const char*] Package version (empty for default)
4122 **
4123 ** @valrule   *  [void]
4124 ** @fcategory misc
4125 **
4126 ******************************************************************************/
4127 
4128 
4129 
4130 
4131 /* @func ajAcdInit ************************************************************
4132 **
4133 ** Initialises everything. Reads an ACD (AJAX Command Definition) file
4134 ** prompts the user for any missing information, reads all sequences
4135 ** and other input into local structures which applications can request.
4136 **
4137 ** @param [r] pgm [const char*] Application name, used as the name
4138 **                              of the ACD file
4139 ** @param [r] argc [ajint] Number of arguments provided on the command line,
4140 **        usually passed as-is by the calling application.
4141 ** @param [r] argv [char* const[]] Actual arguments as an array of text.
4142 ** @return [void]
4143 **
4144 ** @release 1.0.0
4145 ** @@
4146 ******************************************************************************/
4147 
ajAcdInit(const char * pgm,ajint argc,char * const argv[])4148 void ajAcdInit(const char *pgm, ajint argc, char * const argv[])
4149 {
4150     ajAcdInitPV(pgm, argc, argv, "", "");
4151 
4152     return;
4153 }
4154 
4155 
4156 
4157 
4158 /* @func ajAcdInitPV **********************************************************
4159 **
4160 ** Initialises everything. Reads an ACD (AJAX Command Definition) file
4161 ** prompts the user for any missing information, reads all sequences
4162 ** and other input into local structures which applications can request.
4163 **
4164 ** @param [r] pgm [const char*] Application name, used as the name
4165 **                              of the ACD file
4166 ** @param [r] argc [ajint] Number of arguments provided on the command line,
4167 **        usually passed as-is by the calling application.
4168 ** @param [r] argv [char* const[]] Actual arguments as an array of text.
4169 ** @param [r] package [const char*] Package name, used to find the ACD file
4170 ** @param [r] packversion [const char*] Package version
4171 ** @return [void]
4172 **
4173 ** @release 6.2.0
4174 ** @@
4175 ******************************************************************************/
4176 
ajAcdInitPV(const char * pgm,ajint argc,char * const argv[],const char * package,const char * packversion)4177 void ajAcdInitPV(const char *pgm, ajint argc, char * const argv[],
4178                  const char *package, const char *packversion)
4179 {
4180     static AjPFile acdFile = NULL;
4181     static AjPStr acdLine = NULL;
4182     static AjPStr acdRoot = NULL;
4183     static AjPStr acdRootInst = NULL;
4184     static AjPStr acdPack = NULL;
4185     static AjPStr acdPackRoot = NULL;
4186     static AjPStr acdPackRootName = NULL;
4187     static AjPStr acdUtilRoot = NULL;
4188     AjPStr applversion = NULL;
4189     AjPStr versionstr = NULL;
4190     AjPStr comment = NULL;
4191     AjPStrTok tokenhandle = NULL;
4192     char white[] = " \t\n\r";
4193     AjPList acdListWords = NULL;
4194     AjPList acdListCount = NULL;
4195     AjPStr tmpword = NULL;	    /* words to add to acdListWords */
4196     ajint i;
4197     ajint *k = NULL;
4198     ajint *kc = NULL;
4199     ajuint *kp = NULL;
4200     size_t pos;
4201 
4202     acdProgram = ajStrNewC(pgm);
4203 
4204     acdSecList = ajListstrNew();
4205     acdSecTable = ajTablestrNewCase(50);
4206 
4207     acdLog("testing acdprompts");
4208     if(ajNamGetValueC("acdprompts", &acdTmpStr))
4209     {
4210 	acdLog("acdprompts '%S'", acdTmpStr);
4211 	if(ajStrToInt(acdTmpStr, &i))
4212 	    acdPromptTry = i;
4213 	if(acdPromptTry < 1) acdPromptTry = 1;
4214 	acdLog("acdPromptTry %d", acdPromptTry);
4215     }
4216 
4217     if(ajNamGetValueC("acdlog", &acdTmpStr))
4218 	ajStrToBool(acdTmpStr, &acdDoLog);
4219 
4220     if(ajNamGetValueC("acdwarnrange", &acdTmpStr))
4221 	ajStrToBool(acdTmpStr, &acdDoWarnRange);
4222 
4223     /* pre-parse the command line for special options */
4224 
4225     acdArgsScan(argc, argv);
4226 
4227     ajDebug("ajAcdInitPV pgm '%s' package '%s'\n", pgm, package);
4228     ajDebug("  version '%S' system '%S'\n",
4229             ajNamValueVersion(),
4230             ajNamValueSystem());
4231 
4232     /* open the command definition file */
4233 
4234     if(*package)
4235         ajStrAssignC(&acdPackName, package);
4236 
4237     if(*packversion)
4238         ajStrAssignC(&acdPackVersion, packversion);
4239 
4240     ajStrAssignS(&acdPack, ajNamValuePackage());
4241     ajStrAssignS(&acdRootInst, ajNamValueInstalldir());
4242     ajDirnameFix(&acdRootInst);
4243 
4244     if(ajNamGetValueC("acdroot", &acdRoot))
4245     {				       /* _acdroot variable defined */
4246 	ajDirnameFix(&acdRoot);
4247 	ajFmtPrintS(&acdFName, "%S%s.acd", acdRoot, pgm);
4248 	acdLog("Trying acdfile '%S' (acdroot)\n", acdFName);
4249 	acdFile = ajFileNewInNameS(acdFName);
4250     }
4251     else if(*package)
4252     {					/* separate package */
4253 	/*	ajFmtPrintS(&acdFName, "%Sshare/%S/acd/%s.acd",
4254 		acdRootInst, acdPack, pgm);*/
4255 	ajFmtPrintS(&acdFName, "%Sshare/EMBOSS/acd/%s.acd",
4256 		    acdRootInst, pgm);
4257 	acdLog("Trying acdfile '%S' (package '%s' installed)\n",
4258 	       acdFName, package);
4259 	acdFile = ajFileNewInNameS(acdFName);
4260 	if(!acdFile)
4261 	{
4262 	    acdLog("acdfile '%S' not opened\n", acdFName);
4263 	    ajStrAssignC(&acdPack, package); /* package name for acdInitPV */
4264 	    ajStrFmtLower(&acdPack);
4265 
4266 	    ajStrAssignS(&acdPackRootName, acdPack);
4267 	    ajStrAppendC(&acdPackRootName, "acdroot");
4268 	    if(ajNamGetValueS(acdPackRootName, &acdPackRoot))
4269 	    {
4270 		ajDirnameFix(&acdPackRoot);
4271 		ajFmtPrintS(&acdFName, "%S%s.acd", acdPackRoot, pgm);
4272 		acdLog("Trying acdfile '%S' (package %sacdroot)\n",
4273 		       acdFName, package);
4274 	    }
4275 	    else
4276 	    {
4277 		ajStrAssignS(&acdPackRoot, ajNamValueRootdir());
4278 		ajDirnameUp(&acdPackRoot);
4279 		ajFmtPrintS(&acdFName, "%Sembassy/%S/emboss_acd/%s.acd",
4280 			    acdPackRoot, acdPack, pgm);
4281 		acdLog("Trying acdfile '%S' (package %s source)\n",
4282 		       acdFName, package);
4283 	    }
4284 	    acdFile = ajFileNewInNameS(acdFName);
4285 	}
4286     }
4287     else
4288     {					/* main package */
4289 	ajFmtPrintS(&acdFName, "%Sshare/%S/acd/%s.acd",
4290 		    acdRootInst, acdPack, pgm);
4291 	acdLog("Trying acdfile '%S' (installed)\n", acdFName);
4292 	acdFile = ajFileNewInNameS(acdFName);
4293 	if(!acdFile)
4294 	{
4295 	    acdLog("acdfile '%S' not opened\n", acdFName);
4296 	    ajStrAssignC(&acdPack, "emboss");
4297 
4298 	    if(ajNamGetValueC("acdutilroot", &acdUtilRoot))
4299 	    {
4300 		ajDirnameFix(&acdUtilRoot);
4301 		ajFmtPrintS(&acdFName, "%S%s.acd", acdUtilRoot, pgm);
4302 		acdLog("Trying acdfile '%S' (acdutilroot)\n", acdFName);
4303 		acdFile = ajFileNewInNameS(acdFName);
4304 	    }
4305 	}
4306 	if(!acdFile)
4307 	{
4308 	    acdLog("acdfile '%S' not opened\n", acdFName);
4309 	    ajStrAssignS(&acdRoot, ajNamValueRootdir());
4310 	    ajDirnameFix(&acdRoot);
4311 	    ajFmtPrintS(&acdFName, "%Sacd/%s.acd", acdRoot, pgm);
4312 	    acdLog("Trying acdfile '%S' (original main source)\n", acdFName);
4313 	    acdFile = ajFileNewInNameS(acdFName);
4314 	    if(!acdFile)
4315 	    {
4316 		acdLog("acdfile '%S' not opened\n", acdFName);
4317 	    }
4318 	}
4319     }
4320 
4321 
4322     if(!acdFile)			/* test by nofile.acd */
4323 	acdError("ACD file not opened\n");
4324 
4325     /* read the whole file into a string [change to use a list later] */
4326 
4327     acdListWords = ajListstrNew();
4328     acdListCount = ajListNew();
4329 
4330     acdListComments = ajListstrNew();
4331     acdListCommentsCount = ajListNew();
4332     acdListCommentsColumn = ajListNew();
4333 
4334     while(ajReadlineTrim(acdFile, &acdLine))
4335     {
4336 	AJNEW0(k);
4337 	*k = (ajuint) ajListGetLength(acdListWords);
4338 	ajListPushAppend(acdListCount, k);
4339 	if(ajStrCutCommentsRestpos(&acdLine, &comment, &pos))
4340 	{
4341 	    tokenhandle = ajStrTokenNewC(acdLine, white);
4342 
4343 	    while(ajStrTokenNextParse(tokenhandle, &tmpword))
4344 	    {
4345 		if(ajStrGetLen(tmpword)) /* nothing before first whitespace */
4346 		{
4347 		    ajListstrPushAppend(acdListWords, tmpword);
4348 		    tmpword = NULL;
4349 		}
4350 		else
4351 		{
4352 		    ajStrDel(&tmpword);
4353 		}
4354 	    }
4355 	    ajStrTokenDel(&tokenhandle);
4356 	    ajStrDel(&tmpword); 	/* empty token at the end */
4357 	}
4358 
4359 	if (ajStrGetLen(comment))
4360         {
4361 	    ajListstrPushAppend(acdListComments, comment);
4362 	    comment = NULL;
4363 	    AJNEW(kc);
4364 	    *kc = (ajuint) ajListGetLength(acdListWords);
4365 	    ajListPushAppend(acdListCommentsCount, kc);
4366 	    kc = NULL;
4367 	    AJNEW(kp);
4368 	    *kp = pos;
4369 	    ajListPushAppend(acdListCommentsColumn, kp);
4370 	    kp = NULL;
4371 	}
4372     }
4373     ajFileClose(&acdFile);
4374     ajStrDel(&acdLine);
4375 
4376     AJNEW0(k);
4377     *k = (ajuint) ajListGetLength(acdListWords);
4378     ajListPushAppend(acdListCount, k);
4379 
4380     acdCodeInit();
4381     acdKnowntypeInit();
4382 
4383     /* Parse the input to set the initial definitions */
4384 
4385     acdParse(acdListWords, acdListCount);
4386 
4387     ajListstrFreeData(&acdListWords);
4388     ajListFreeData(&acdListCount);
4389 
4390     if(acdDoVersion)
4391     {
4392         ajFmtPrintS(&versionstr, "EMBOSS:%s", VERSION);
4393 
4394         if(ajStrGetLen(versionstr) < 14)
4395             ajStrAppendC(&versionstr, ".0");
4396 
4397         if(ajStrGetLen(acdPackVersion))
4398             ajFmtPrintAppS(&versionstr, " %S:%S", acdPackName, acdPackVersion);
4399 
4400         acdAttrResolve(acdApplAcd, "versionnumber", &applversion);
4401 
4402         if(ajStrGetLen(applversion))
4403         {
4404             ajFmtPrintAppS(&versionstr, " %s:%S", pgm, applversion);
4405             ajStrDel(&applversion);
4406         }
4407 
4408         ajUserDumpS(versionstr);
4409         ajStrDel(&versionstr);
4410         ajExit();
4411     }
4412 
4413     if(acdDoPretty || acdDoValid)
4414 	ajExit();
4415 
4416     /* Fill in incomplete information like parameter numbers */
4417 
4418     acdProcess();
4419 
4420     AJCNEW0(acdParamSet, acdNParam+1);
4421 
4422     /* report on what we have so far */
4423 
4424     acdListReport("Definitions in ACD file");
4425 
4426     /* parse the command line and update the values */
4427 
4428     acdArgsParse(argc, argv);
4429 
4430     /* report on what we have so far */
4431 
4432     acdListReport("Results of parsing command line arguments");
4433 
4434     /* set the true values and prompt for missing standard values */
4435 
4436     if(acdDoTable || acdDoXsd || acdDoGalaxy)
4437 	acdHelp();
4438 
4439     acdSetAll();
4440 
4441     /* report on what we have now */
4442 
4443     acdListReport("Final results after setting values and prompting the user");
4444 
4445     /* all done */
4446 
4447     ajStrDel(&acdRoot);
4448     ajStrDel(&acdRootInst);
4449     ajStrDel(&acdPack);
4450     ajStrDel(&acdPackRoot);
4451     ajStrDel(&acdPackRootName);
4452     ajStrDel(&acdFName);
4453     ajStrDel(&comment);
4454 
4455     return;
4456 }
4457 
4458 
4459 
4460 
4461 /*===========================================================================*/
4462 /*========================= ACD File Parsing ================================*/
4463 /*===========================================================================*/
4464 
4465 
4466 
4467 
4468 /* @funcstatic acdStage *******************************************************
4469 **
4470 ** Tests next token to set the next parsing stage.
4471 **
4472 ** @param [r] token [const AjPStr] Current token
4473 ** @return [AcdEStage] Stage enumerated code
4474 **
4475 ** @release 1.0.0
4476 ** @@
4477 ******************************************************************************/
4478 
acdStage(const AjPStr token)4479 static AcdEStage acdStage(const AjPStr token)
4480 {
4481     ajint i;
4482     ajint ifound=0;
4483     AcdEStage j=BAD_STAGE;
4484 
4485     AjPStr ambigList = NULL;
4486 
4487     ambigList = ajStrNew();
4488 
4489     if(!ajStrGetLen(token))
4490 	return BAD_STAGE;
4491 
4492     i = QUAL_STAGE + 1;
4493     while(acdKeywords[i].Name)		/* ACD keywords */
4494     {
4495 	if(ajStrMatchC(token, acdKeywords[i].Name))
4496 	    return acdKeywords[i].Stage;
4497 	if(ajCharPrefixS(acdKeywords[i].Name, token))
4498 	{
4499 	    ifound++;
4500 	    j = acdKeywords[i].Stage;
4501 	    acdAmbigAppC(&ambigList, acdKeywords[i].Name);
4502 	}
4503 	i++;
4504     }
4505 
4506     i =  0;
4507     while(acdType[i].Name)		/* ACD types as qualifiers */
4508     {
4509 	if(ajStrMatchC(token, acdType[i].Name))
4510 	    return QUAL_STAGE;
4511 	if(ajCharPrefixS(acdType[i].Name, token))
4512 	{
4513 	    ifound++;
4514 	    j = QUAL_STAGE;
4515 	    acdAmbigAppC(&ambigList, acdType[i].Name);
4516 	}
4517 	i++;
4518     }
4519 
4520     if(ifound == 1)
4521     {
4522 	if (acdDoValid)
4523 	    acdWarn("Abbreviated stage '%S' (%S)", token, ambigList);
4524 	return j;
4525     }
4526 
4527 
4528     if(ifound > 1)
4529     {					/* test ambigtype.acd */
4530 	acdError("ambiguous acd type %S (%S)", token, ambigList);
4531 	ajStrDel(&ambigList);
4532     }
4533 
4534     ajStrDel(&ambigList);
4535 
4536     return BAD_STAGE;
4537 }
4538 
4539 
4540 
4541 
4542 /* @funcstatic acdParse *******************************************************
4543 **
4544 ** Parse the command line definition and build data structures from it.
4545 **
4546 ** @param [u] listwords [AjPList] List of words (as strings)
4547 **                      from ACD file. List empty on completion
4548 ** @param [u] listcount [AjPList] List of word count before each line.
4549 **                      List empty on completion
4550 ** @return [void]
4551 ** @see acdNewAppl
4552 ** @see acdNewQual
4553 ** @see acdNewVar
4554 **
4555 ** @release 1.0.0
4556 ** @@
4557 ******************************************************************************/
4558 
acdParse(AjPList listwords,AjPList listcount)4559 static void acdParse(AjPList listwords, AjPList listcount)
4560 {
4561     AjPStr acdStrType  = NULL;
4562     AjPStr acdStrAlias = NULL;
4563     AjPStr acdStrValue = NULL;
4564     AjPStr secname  = NULL;
4565     ajint linecount = 0;
4566     ajint lineword  = 0;
4567     ajint *iword    = NULL;
4568     ajint *icword    = NULL;
4569     ajint *icpos    = NULL;
4570     AjPStr cmtstr = NULL;
4571     AjPTime today = NULL;
4572 
4573     /* initialise the global line number counter to zero */
4574     acdLineNum = 0;
4575 
4576     if(acdDoValid)
4577     {
4578         if(ajNamGetValueC("edam", &acdEdamPath))
4579         {
4580             acdEdamFile = ajFileNewInNameS(acdEdamPath);
4581             if(acdEdamFile)
4582                 acdEdam = ajObodataParseObofile(acdEdamFile, "none");
4583         }
4584     }
4585 
4586     while(ajListGetLength(acdListCommentsCount) && !acdCmtWord)
4587     {
4588 	ajListPeek(acdListCommentsCount, (void**) &icword);
4589 	acdCmtWord = *icword;
4590 	if(!acdCmtWord)
4591 	{
4592 	    ajStrDel(&cmtstr);
4593 	    ajListPop(acdListCommentsCount, (void**) &icword);
4594 	    ajListPop(acdListCommentsColumn, (void**) &icpos);
4595 	    ajListstrPop(acdListComments, &cmtstr);
4596 	    acdPrettyComment(cmtstr);
4597 	    AJFREE(icword);
4598 	    AJFREE(icpos);
4599 	}
4600     }
4601 
4602     if(ajStrGetLen(cmtstr))
4603     {
4604 	acdPretty("\n");
4605 	ajStrDel(&cmtstr);
4606     }
4607 
4608     while(ajListGetLength(listcount) && (!lineword))
4609     {
4610 	ajListPeek(listcount, (void**) &iword);
4611 
4612 	if(*iword)
4613 	    lineword = *iword;
4614 	else
4615 	{
4616 	    ajListPop(listcount, (void**) &iword);
4617 	    linecount++;
4618 	    acdLineNum = linecount - 1;
4619 	    AJFREE(iword);
4620 	}
4621     }
4622     lineword = 0;
4623     acdWordNum = 0;
4624 
4625     while(ajListGetLength(listwords))
4626     {
4627  	acdWordNextName(listwords, &acdStrType);
4628 
4629 	while(ajListGetLength(listcount) && (lineword < acdWordNum))
4630 	{
4631 	    ajListPop(listcount, (void**) &iword);
4632 	    lineword = *iword;
4633 	    linecount++;
4634 	    acdLineNum = linecount - 1;
4635 	    AJFREE(iword);
4636 	}
4637 
4638 	acdCurrentStage = acdStage(acdStrType);
4639 	if(acdWordNum == 1)
4640 	    if(acdCurrentStage != APPL_STAGE) /* test noappl.acd */
4641 		acdError("Application definition required at start");
4642 
4643 	switch(acdCurrentStage)
4644 	{
4645 	case APPL_STAGE:
4646 	    if(acdWordNum != 1)
4647 		acdError("Application definition allowed only at start");
4648 
4649 	    /* application: then the appl name */
4650 	    acdParseName(listwords, &acdStrName);
4651 	    if (!ajStrMatchS(acdStrName, acdProgram))
4652 		acdError("Application name '%S' does not match filename '%S'",
4653 			 acdStrName, acdProgram);
4654 
4655 	    acdNewCurr = acdNewAppl(acdStrName);
4656             acdApplAcd = acdNewCurr;
4657 
4658 	    acdWordNum++;		/* add one for '[' */
4659 
4660 	    acdPretty("%s: %S [\n",
4661 		      acdKeywords[acdCurrentStage].Name, acdStrName);
4662 
4663 	    acdWordNum--;		/* not yet parsed '[' */
4664 
4665 	    acdParseAttributes(acdNewCurr, listwords);
4666 
4667             acdAttrToBool(acdNewCurr, "wrapper", ajFalse, &acdWrapper);
4668 
4669 	    acdValidAppl(acdNewCurr);
4670 
4671 	    /* automatic $(today) variable */
4672 	    ajStrAssignC(&acdStrName, "today");
4673 	    today = ajTimeNewToday();
4674 	    ajFmtPrintS(&acdStrValue, "%D", today);
4675 	    ajTimeDel(&today);
4676 	    acdNewCurr = acdNewVar(acdStrName);
4677 	    acdSetVarDef(acdNewCurr, acdStrValue);
4678 	    break;
4679 
4680 	    /* type: qualname alias[ attr: value ]
4681 	     **
4682 	     ** The alias name is optional (defaults to the qualifier name)
4683 	     ** The [] are required so the token can be detected.  Attributes
4684 	     ** are defined for each "type", as are associated
4685 	     ** qualifiers. There is no distinction between them here.  The
4686 	     ** difference is that the qualifier values are defaults which
4687 	     ** can be overridden on the command line
4688 	     */
4689 
4690 	case QUAL_STAGE:
4691 	    acdParseAlpha(listwords, &acdStrName);
4692 
4693 	    if(acdNotLeftB(listwords))
4694 	    {				/* test badalias.acd */
4695 		if(!acdWordNextLower(listwords, &acdStrAlias) ||
4696 		   !ajStrIsAlpha(acdStrAlias))
4697 		    acdError("Bad syntax qualifier alias name '%S'",
4698 			     acdStrAlias);
4699 	    }
4700 	    else	/* we have an alternate name before the '[' */
4701 		ajStrAssignS(&acdStrAlias, acdStrName);
4702 
4703 	    acdNewCurr = acdNewQual(acdStrName, acdStrAlias, &acdStrType);
4704 
4705 	    acdWordNum++;		/* add one for '[' */
4706 
4707 	    if(!ajStrMatchS(acdStrName, acdStrAlias))
4708 		acdPretty("\n%S: %S %S [\n", acdStrType,
4709 			  acdStrName, acdStrAlias);
4710 	    else
4711 		acdPretty("\n%S: %S [\n", acdStrType,
4712 			  acdStrName);
4713 
4714 	    acdWordNum--;		/* not yet parsed '[' */
4715 
4716 	    acdParseAttributes(acdNewCurr, listwords);
4717 
4718 	    acdValidQual(acdNewCurr);
4719 
4720 	    break;
4721 
4722 	case SEC_STAGE:
4723 	    /* section: name [ attrlist ] */
4724 	    acdParseName(listwords, &acdStrName);
4725 
4726 	    acdNewCurr = acdNewSec(acdStrName);
4727 
4728 	    acdWordNum++;		/* add one for '[' */
4729 
4730 	    acdPretty("\n%s: %S [\n",
4731 		      acdKeywords[acdCurrentStage].Name, acdStrName);
4732 
4733 	    acdWordNum--;		/* not yet parsed '[' */
4734 
4735 	    acdParseAttributes(acdNewCurr, listwords);
4736 
4737 	    acdValidSection(acdNewCurr);
4738 
4739 	    acdPrettyShift();
4740 
4741 	    break;
4742 
4743 	case ENDSEC_STAGE:
4744 	    /* endsection: name */
4745 	    /* remove from list of current sections */
4746 	    acdParseName(listwords, &acdStrName);
4747 	    acdNewCurr = acdNewEndsec(acdStrName);
4748 	    acdValidSection(acdNewCurr);
4749 	    acdPrettyUnShift();
4750 	    acdPretty("\n%s: %S\n",
4751 		      acdKeywords[acdCurrentStage].Name, acdStrName);
4752 	    break;
4753 
4754 	    /* catch-all for failed parsing */
4755 
4756 	case VAR_STAGE:
4757 	    /* then the variable name and the value */
4758 	    acdParseName(listwords, &acdStrName);
4759 	    ajStrAssignS(&acdStrValue, acdParseValue(listwords));
4760 	    acdNewCurr = acdNewVar(acdStrName);
4761 	    acdSetVarDef(acdNewCurr, acdStrValue);
4762 	    acdPretty("\n%s: %S \"%S\"\n",
4763 		      acdKeywords[acdCurrentStage].Name,
4764 		      acdStrName, acdStrValue);
4765 	    break;
4766 
4767 	case REL_STAGE:
4768 	    /* relation: name [ attrlist ] */
4769 	    acdParseName(listwords, &acdStrName);
4770 
4771 	    acdNewCurr = acdNewRel(acdStrName);
4772 
4773 	    acdWordNum++;		/* add one for '[' */
4774 
4775 	    acdPretty("\n%s: %S [\n",
4776 		      acdKeywords[acdCurrentStage].Name, acdStrName);
4777 
4778 	    acdWordNum--;		/* not yet parsed '[' */
4779 
4780 	    acdParseAttributes(acdNewCurr, listwords);
4781 
4782 	    acdValidRelation(acdNewCurr);
4783 
4784 	    acdPrettyShift();
4785 
4786 	    break;
4787 
4788 	case BAD_STAGE:			/* test badstage.acd */
4789 	default:		     /* Fatal - should never happen */
4790 	    acdError("Unrecognized token '%S'\n", acdStrType);
4791 	    break;
4792 	}
4793     }
4794     acdLog("-- All Done --\n");
4795 
4796     acdLog("-- All Done : acdSecList length %d\n",
4797 	   ajListstrGetLength(acdSecList));
4798 
4799     acdLineNum = linecount;
4800 
4801     if(ajListstrGetLength(acdSecList)) /* fatal error, unclosed section(s) */
4802     {
4803 	while(ajListstrPop(acdSecList, &secname))
4804 	{
4805 	    ajDebug("Section '%S' has no endsection\n", secname);
4806 	    ajErr("Section '%S' has no endsection", secname); /* fails below */
4807 	    ajStrDel(&secname);
4808 	}
4809 	acdLog("Unclosed sections in ACD file\n");
4810 	acdError("Unclosed sections in ACD file"); /* test noendsec.acd */
4811     }
4812 
4813     acdPrettyClose();
4814 
4815     ajStrDel(&acdStrName); /* the global string ... no longer needed */
4816 
4817     ajStrDel(&acdStrAlias);
4818     ajStrDel(&acdStrType);
4819     ajStrDel(&acdStrValue);
4820     ajListstrFreeData(&acdSecList);
4821 
4822     acdLineNum = 0;
4823 
4824     while(ajListGetLength(listcount))
4825     {
4826 	ajListPop(listcount, (void**) &iword);
4827 	AJFREE(iword);
4828     }
4829 
4830     return;
4831 }
4832 
4833 
4834 
4835 
4836 /* @funcstatic acdParseValue **************************************************
4837 **
4838 ** Uses ajStrTok to complete a (possibly) quoted value.
4839 ** Note that ajStrTok has a stored internal copy of the text string
4840 ** which is set up at the start of acdParse and is being used here.
4841 **
4842 ** Quotes can be single or double.
4843 **
4844 ** The early versions also allowed any kind of parentheses,
4845 ** depending on the first character of the next token examined.
4846 ** This is now obsolete, to simplify the syntax and to allow
4847 ** future reuse of parentheses.
4848 **
4849 ** @param [u] listwords [AjPList] List of strings for each word
4850 **                                      to be parsed
4851 ** @return [AjPStr] String containing next value from list
4852 **
4853 ** @release 1.0.0
4854 ** @@
4855 ******************************************************************************/
4856 
4857 
acdParseValue(AjPList listwords)4858 static AjPStr acdParseValue(AjPList listwords)
4859 {
4860     AjPStr strp=NULL;
4861     char  endq[]=" ";
4862     ajint iquote;
4863     char *cq;
4864     AjBool done = ajFalse;
4865 
4866     const char *quotes = "\"'";
4867     const char *endquotes = "\"'";
4868 
4869     acdParseQuotes = ajFalse;
4870 
4871     if(!acdWordNext(listwords, &strp))	/* test: novalue.acd */
4872 	acdErrorAcd(acdNewCurr,
4873 		    "Unexpected end of file, attribute value not found\n");
4874 
4875     cq = strchr(quotes, ajStrGetCharFirst(strp));
4876 
4877     if(!cq)				/* no quotes, simple return */
4878     {
4879 	ajStrAssignS(&acdParseReturn, strp);
4880 	ajStrDel(&strp);
4881 	return acdParseReturn;
4882     }
4883 
4884     acdParseQuotes = ajTrue;
4885 
4886     /* quote found: parse up to closing quote then strip white space */
4887 
4888     iquote = cq - quotes;
4889     endq[0] = endquotes[iquote];
4890 
4891     ajStrCutStart(&strp, 1);
4892     ajStrDel(&acdParseReturn);
4893 
4894     while(!done)
4895     {
4896 	if(ajStrSuffixC(strp, endq))
4897 	{			       /* check for trailing quotes */
4898 	    ajStrCutEnd(&strp, 1);
4899 	    done = ajTrue;
4900 	}
4901 
4902 	if(ajStrGetLen(strp))
4903 	{
4904 	    if(ajStrGetLen(acdParseReturn))
4905 	    {
4906 		ajStrAppendC(&acdParseReturn, " ");
4907 		ajStrAppendS(&acdParseReturn, strp);
4908 	    }
4909 	    else
4910 		ajStrAssignS(&acdParseReturn, strp);
4911 	}
4912 	if(!done)
4913 	    if(!acdWordNext(listwords, &strp)) /* test noquote.acd */
4914 		acdErrorAcd(acdNewCurr,
4915 			    "Unexpected end of file, no closing quote\n");
4916     }
4917 
4918     ajStrDel(&strp);
4919     return acdParseReturn;
4920 }
4921 
4922 
4923 
4924 
4925 /* @funcstatic acdWordNext ****************************************************
4926 **
4927 ** Returns the next word from a list
4928 **
4929 ** @param [u] listwords [AjPList] List of words parsed from ACD file
4930 ** @param [w] pword [AjPStr*] Next word from the list
4931 ** @return [AjBool] ajTrue on success
4932 **
4933 ** @release 2.7.0
4934 ** @@
4935 ******************************************************************************/
4936 
acdWordNext(AjPList listwords,AjPStr * pword)4937 static AjBool acdWordNext(AjPList listwords, AjPStr* pword)
4938 {
4939     ajStrDel(pword);
4940 
4941     if(ajListstrPop(listwords, pword))
4942     {
4943 	acdWordNum++;
4944 	return ajTrue;
4945     }
4946 
4947     ajStrAssignClear(pword);
4948     return ajFalse;
4949 }
4950 
4951 
4952 
4953 
4954 /* @funcstatic acdWordNextLower ***********************************************
4955 **
4956 ** Returns the next word from a list, in lower case.
4957 **
4958 ** @param [u] listwords [AjPList] List of words parsed from ACD file
4959 ** @param [w] pword [AjPStr*] Next word from the list
4960 ** @return [AjBool] ajTrue on success
4961 **
4962 ** @release 2.7.0
4963 ** @@
4964 ******************************************************************************/
4965 
acdWordNextLower(AjPList listwords,AjPStr * pword)4966 static AjBool acdWordNextLower(AjPList listwords, AjPStr* pword)
4967 {
4968     if(acdWordNext(listwords, pword))
4969     {
4970 	if(!ajStrIsLower(*pword))
4971 	{
4972 	    acdWarn("Automatically converting '%S' to lower case", *pword);
4973 	    ajStrFmtLower(pword);
4974 	}
4975 	return ajTrue;
4976     }
4977 
4978     return ajFalse;
4979 }
4980 
4981 
4982 
4983 
4984 /* @funcstatic acdWordNextName ************************************************
4985 **
4986 ** Returns the next word from a list, in lower case
4987 **
4988 ** This must be an ACD name (type or attribute) alphabetic only,
4989 ** with a trailing ':'
4990 **
4991 ** @param [u] listwords [AjPList] List of words parsed from ACD file
4992 ** @param [w] pword [AjPStr*] Next word from the list
4993 ** @return [AjBool] ajTrue on success
4994 **
4995 ** @release 2.7.0
4996 ** @@
4997 ******************************************************************************/
4998 
acdWordNextName(AjPList listwords,AjPStr * pword)4999 static AjBool acdWordNextName(AjPList listwords, AjPStr* pword)
5000 {
5001     if(acdWordNext(listwords, pword))
5002     {
5003 	if(ajStrGetCharLast(*pword) != ':')
5004 	{
5005 	    if(ajStrGetCharFirst(*pword) == ':')/* test nocolon.acd */
5006 		acdError("Found ':' at start of word '%S'", *pword);
5007 	    else if(ajStrFindAnyK(*pword, ':') > 0)
5008 		acdError("Expected space missing after ':' in '%S'", *pword);
5009 	    else
5010 		acdError("Expected ':' not found after '%S'", *pword);
5011 	    return ajFalse;
5012 	}
5013 	ajStrCutEnd(pword, 1);
5014 	if(!ajStrIsAlpha(*pword))
5015 	    return ajFalse;
5016 	ajStrFmtLower(pword);
5017 	return ajTrue;
5018     }
5019 
5020     return ajFalse;
5021 }
5022 
5023 
5024 
5025 
5026 /* @funcstatic acdParseName ***************************************************
5027 **
5028 ** Returns the next word from a list, in lower case.
5029 **
5030 ** This must be an ACD name (alphanumeric allowed as this is not used
5031 ** for qualifier names)
5032 **
5033 ** @param [u] listwords [AjPList] List of words parsed from ACD file
5034 ** @param [w] pword [AjPStr*] Next word from the list
5035 ** @return [void]
5036 **
5037 ** @release 2.7.0
5038 ** @@
5039 ******************************************************************************/
5040 
acdParseName(AjPList listwords,AjPStr * pword)5041 static void acdParseName(AjPList listwords, AjPStr* pword)
5042 {
5043     if(acdWordNextLower(listwords, pword))
5044 	if(ajStrIsAlnum(*pword))
5045 	    return;
5046 
5047     /* test noapplname.acd badapplname.acd */
5048     acdError("Bad or missing %s name '%S'",
5049 	     acdKeywords[acdCurrentStage].Name, *pword);
5050 
5051     return;
5052 }
5053 
5054 
5055 
5056 
5057 /* @funcstatic acdParseAlpha **************************************************
5058 **
5059 ** Returns the next word from a list, in lower case.
5060 **
5061 ** This must be an alphabetic word, no numbers or underscores allowed.
5062 **
5063 ** @param [u] listwords [AjPList] List of words parsed from ACD file
5064 ** @param [w] pword [AjPStr*] Next word from the list
5065 ** @return [void]
5066 **
5067 ** @release 2.7.0
5068 ** @@
5069 ******************************************************************************/
5070 
acdParseAlpha(AjPList listwords,AjPStr * pword)5071 static void acdParseAlpha(AjPList listwords, AjPStr* pword)
5072 {
5073     if(acdWordNextLower(listwords, pword))
5074 	if(ajStrIsAlpha(*pword))
5075 	    return;
5076 
5077     /* test noqualname.acd badqualname.acd */
5078     acdError("Bad or missing %s alphabetic name '%S'",
5079 	     acdKeywords[acdCurrentStage].Name, *pword);
5080 
5081     return;
5082 }
5083 
5084 
5085 
5086 
5087 /* @funcstatic acdNotLeftB ****************************************************
5088 **
5089 ** Tests the start of the next word in the list for '[' at the start
5090 **
5091 ** Does not remove the '['
5092 **
5093 ** @param [r] listwords [const AjPList] List of words parsed from ACD file
5094 ** @return [AjBool] ajTrue if start of string does not match '['
5095 **
5096 ** @release 2.7.0
5097 ** @@
5098 ******************************************************************************/
5099 
acdNotLeftB(const AjPList listwords)5100 static AjBool acdNotLeftB(const AjPList listwords)
5101 {
5102     char ch;
5103     AjPStr pstr = NULL;
5104 
5105     if(!ajListstrPeek(listwords, &pstr))
5106 	return ajFalse;
5107 
5108     ch = ajStrGetCharFirst(pstr);
5109 
5110     if(ch == '[')
5111 	return ajFalse;
5112 
5113     /* do not delete pstr - we only peeked */
5114 
5115     return ajTrue;
5116 }
5117 
5118 
5119 
5120 
5121 /* @funcstatic acdIsLeftB *****************************************************
5122 **
5123 ** Tests the start of the next word in the list for '[' at the start
5124 **
5125 ** @param [u] listwords [AjPList] List of words parsed from ACD file
5126 ** @return [AjBool] ajTrue if start of string matches '['
5127 **
5128 ** @release 1.0.0
5129 ** @@
5130 ******************************************************************************/
5131 
acdIsLeftB(AjPList listwords)5132 static AjBool acdIsLeftB(AjPList listwords)
5133 {
5134     char ch;
5135     AjPStr teststr = NULL;
5136     AjPStr pstr = NULL;
5137 
5138     if(!ajListstrPeek(listwords, &teststr))
5139 	return ajFalse;
5140 
5141     ch = ajStrGetCharFirst(teststr);
5142 
5143     if(ch == '[')
5144     {
5145 	ajStrCutStart(&teststr, 1);	/* trim the leading '[' in the list */
5146 	if(!ajStrGetLen(teststr))
5147 	{		    /* only the '[' so remove from the list */
5148 	    acdWordNext(listwords, &pstr); /*  must succeed - Peeked */
5149 	    ajStrDel(&pstr);	     /* empty - ignored - so delete */
5150 	    teststr = NULL;
5151 	}
5152 	return ajTrue;
5153     }
5154     /* do not delete teststr - it was only peeked  - deleted as pstr */
5155 
5156     return ajFalse;
5157 }
5158 
5159 
5160 
5161 
5162 /* @funcstatic acdIsRightB ****************************************************
5163 **
5164 ** Tests for ']' to look for ascent to a higher level of parsing.
5165 **
5166 ** Tests the end of the current string
5167 ** If that fails, tests the start of the next word in the list.
5168 **
5169 ** Afterwards, the value of pstr is the last word with any ']' removed
5170 **
5171 ** @param [w] pstr [AjPStr*] String which has a trailing ']' removed if found
5172 ** @param [u] listwords [AjPList] List of remaining words to be parsed
5173 ** @return [AjBool] ajTrue if end of string matches ']'
5174 **
5175 ** @release 1.0.0
5176 ** @@
5177 ******************************************************************************/
5178 
acdIsRightB(AjPStr * pstr,AjPList listwords)5179 static AjBool acdIsRightB(AjPStr* pstr, AjPList listwords)
5180 {
5181     AjPStr teststr = NULL;
5182     char ch;
5183 
5184     if(*pstr && !acdParseQuotes)
5185     {
5186 	ch = ajStrGetCharLast(*pstr);
5187 
5188 	if(ch == ']')	    /* test input pstr value for ']' at end */
5189 	{
5190 	    ajStrCutEnd(pstr, 1);
5191 	    return ajTrue;
5192 	}
5193     }
5194 
5195     /* go on to the next word in the list */
5196 
5197     if(!ajListstrPeek(listwords, &teststr)) /* leftend.acd valend.acd */
5198 	acdErrorAcd(acdNewCurr, "End of file looking for ']'");
5199 
5200     ch = ajStrGetCharFirst(teststr);
5201 
5202     if(ch == ']')		       /* next word starts with ']' */
5203     {
5204 	ajStrCutStart(&teststr, 1);	     /* trim the word - in the list */
5205 	if(!ajStrGetLen(teststr))		/*  only "]" so delete it */
5206 	{
5207 	    acdWordNext(listwords, &acdTmpStr); /* works - used ajListstrPeek */
5208 	    teststr = NULL;
5209 	}
5210 	return ajTrue;
5211     }
5212 
5213     return ajFalse;
5214 }
5215 
5216 
5217 
5218 
5219 /* @funcstatic acdParseAttributes *********************************************
5220 **
5221 ** Parse the attribute list for an ACD type
5222 **
5223 ** @param [r] acd [const AcdPAcd] Acd object
5224 ** @param [u] listwords [AjPList] List of parsed words
5225 ** @return [void]
5226 **
5227 ** @release 2.7.0
5228 ** @@
5229 ******************************************************************************/
5230 
acdParseAttributes(const AcdPAcd acd,AjPList listwords)5231 static void acdParseAttributes(const AcdPAcd acd, AjPList listwords)
5232 {
5233     AjPStr strAttr = NULL;
5234     AjPStr strValue = NULL;
5235     AjPStr strFixValue = NULL;
5236     AjBool done=ajFalse;
5237     ajint i=0;
5238 
5239     if(!acdIsLeftB(listwords)) /* test noleftappl.acd noleftsec.acd */
5240 	/* noleftq.acd */
5241 	acdErrorAcd(acdNewCurr, "Failed to find '[' for %s %S\n",
5242 		    acdKeywords[acdCurrentStage].Name, acdStrName);
5243 
5244     acdPrettyShift();
5245 
5246     done = acdIsRightB(&strAttr, listwords); /* could be [ ] */
5247 
5248     /* continue parsing until we reach a true closing ']' character */
5249 
5250     while(!done)
5251     {
5252 	if(!acdWordNextName(listwords, &strAttr)) /* test: noattname.acd */
5253 	    acdErrorAcd(acdNewCurr, "Bad or missing attribute name '%S'",
5254 			strAttr);
5255 
5256 	for (i=0;acdAttrAlias[i].OldName;i++)
5257 	    if (ajStrMatchC(strAttr, acdAttrAlias[i].OldName))
5258 	    {
5259 		ajStrAssignC(&strAttr, acdAttrAlias[i].NewName);
5260 		break;
5261 	    }
5262 
5263 	ajStrAssignS(&strValue, acdParseValue(listwords));
5264 	done = acdIsRightB(&strValue, listwords); /* will this be last pair? */
5265 
5266 	ajStrAssignS(&strFixValue, strValue);
5267 	acdTextFormat(&strFixValue);
5268 	if(acdCurrentStage == QUAL_STAGE)
5269 	    acdSet(acd, &strAttr, strFixValue);
5270 	else
5271 	    acdSetKey(acd, &strAttr, strFixValue);
5272 
5273 	if(done)
5274 	    acdWordNum--;
5275 
5276 	acdPrettyWrap(ajStrGetLen(strAttr)+3, "%S: \"%S\"",
5277 		      strAttr, strValue);
5278 	if(done)
5279 	    acdWordNum++;
5280     }
5281 
5282     acdPrettyUnShift();
5283     acdPretty("]\n");
5284 
5285     ajStrDel(&strAttr);
5286     ajStrDel(&strValue);
5287     ajStrDel(&strFixValue);
5288 
5289     return;
5290 }
5291 
5292 
5293 
5294 
5295 /* @funcstatic acdNewAppl *****************************************************
5296 **
5297 ** Constructor front end for an application ACD object.
5298 **
5299 ** @param [r] name [const AjPStr] Token name to be used by applications
5300 ** @return [AcdPAcd] ACD application object for name.
5301 **
5302 ** @release 1.0.0
5303 ** @@
5304 ******************************************************************************/
5305 
acdNewAppl(const AjPStr name)5306 static AcdPAcd acdNewAppl(const AjPStr name)
5307 {
5308     AcdPAcd acd;
5309     AcdPAcd qacd;
5310     AcdPAcd saveqacd = NULL;
5311     AcdPQual quals;
5312     AjPStr qname = NULL;
5313     AjPStr qtype = NULL;
5314     static ajint firstcall = 1;
5315     static ajint ikey;
5316     ajint i;
5317 
5318     if(firstcall)
5319     {
5320 	ikey = acdFindKeyC("application");
5321 	firstcall = 0;
5322     }
5323 
5324     i = 0;
5325     quals = acdQualAppl;
5326 
5327     if(quals)
5328     {
5329 	while(quals[i].Name)
5330 	{
5331 	    ajStrAssignC(&qname, quals[i].Name);
5332 	    ajStrAssignC(&qtype, quals[i].Type);
5333 	    /*   qacd = acdNewQual(qname, qname, &qtype);*/
5334 	    qacd = acdNewQualQual(qname, &qtype);
5335 	    if(*quals[i].Default)
5336 		acdSetDefC(qacd, quals[i].Default);
5337 
5338 	    if(!i)
5339 		saveqacd = qacd; /* save the location of the first one */
5340 	    i++;
5341 	}
5342     }
5343 
5344     acd = acdNewAcdKey(name, name, ikey);
5345     acd->Level = ACD_APPL;
5346     if(saveqacd)
5347         acd->AssocQuals = saveqacd;
5348 
5349     ajStrDel(&qname);
5350     ajStrDel(&qtype);
5351 
5352     return acd;
5353 }
5354 
5355 
5356 
5357 
5358 /* @funcstatic acdNewVar ******************************************************
5359 **
5360 ** Constructor front end for a variable ACD object.
5361 **
5362 ** @param [r] name [const AjPStr] Token name to be used by applications
5363 ** @return [AcdPAcd] ACD variable object for name.
5364 **
5365 ** @release 1.0.0
5366 ** @@
5367 ******************************************************************************/
5368 
acdNewVar(const AjPStr name)5369 static AcdPAcd acdNewVar(const AjPStr name)
5370 {
5371     AcdPAcd acd;
5372     static ajint firstcall = 1;
5373     static ajint ikey;
5374 
5375     if(firstcall)
5376     {
5377 	ikey = acdFindKeyC("variable");
5378 	firstcall = 0;
5379     }
5380 
5381     acd = acdNewAcdKey(name, name, ikey);
5382     acd->Level = ACD_VAR;
5383 
5384     return acd;
5385 }
5386 
5387 
5388 
5389 
5390 /* @funcstatic acdNewRel ******************************************************
5391 **
5392 ** Constructor front end for a relation ACD object.
5393 **
5394 ** @param [r] name [const AjPStr] Token name to be used by applications
5395 ** @return [AcdPAcd] ACD variable object for name.
5396 **
5397 ** @release 2.9.0
5398 ** @@
5399 ******************************************************************************/
5400 
acdNewRel(const AjPStr name)5401 static AcdPAcd acdNewRel(const AjPStr name)
5402 {
5403     AcdPAcd acd;
5404     static ajint firstcall = 1;
5405     static ajint ikey;
5406 
5407     if(firstcall)
5408     {
5409 	ikey = acdFindKeyC("relation");
5410 	firstcall = 0;
5411     }
5412 
5413     acdLog("acdNewRel '%S'\n", name);
5414 
5415     acd = acdNewAcdKey(name, name, ikey);
5416     acd->Level = ACD_RELATION;
5417 
5418     return acd;
5419 }
5420 
5421 
5422 
5423 
5424 /* @funcstatic acdNewSec ******************************************************
5425 **
5426 ** Constructor front end for a section ACD object.
5427 **
5428 ** @param [r] name [const AjPStr] Token name to be used by applications
5429 ** @return [AcdPAcd] ACD variable object for name.
5430 **
5431 ** @release 2.0.0
5432 ** @@
5433 ******************************************************************************/
5434 
acdNewSec(const AjPStr name)5435 static AcdPAcd acdNewSec(const AjPStr name)
5436 {
5437     AcdPAcd acd;
5438     static ajint firstcall = 1;
5439     static ajint ikey;
5440     AjPStr secname=NULL;
5441     AjPStr secfull=NULL;
5442     AjPStr secfullvalue=NULL;
5443 
5444     if(firstcall)
5445     {
5446 	ikey = acdFindKeyC("section");
5447 	firstcall = 0;
5448     }
5449 
5450     acdLog("acdNewSec '%S' acdSecList length %d\n",
5451 	   name, ajListstrGetLength(acdSecList));
5452 
5453     acd = acdNewAcdKey(name, name, ikey);
5454     acd->Level = ACD_SEC;
5455 
5456     ajStrAssignS(&secname, name);
5457     ajListstrPush(acdSecList, secname);
5458 
5459     acdValidSectionFull(&secfull);
5460     ajStrAssignS(&secfullvalue, name);
5461     acdLog("Full section '%S'\n", secfull);
5462 
5463     if (ajTablePut(acdSecTable, secfull, secfullvalue))
5464 	acdError("Duplicate section '%S'", name);
5465 
5466     acdLog("acdNewSec acdSecList push '%S' new length %d\n",
5467 	   secname, ajListstrGetLength(acdSecList));
5468 
5469     return acd;
5470 }
5471 
5472 
5473 
5474 
5475 /* @funcstatic acdNewEndsec ***************************************************
5476 **
5477 ** Constructor front end for an end of section ACD object.
5478 **
5479 ** @param [r] name [const AjPStr] Token name to be used by applications
5480 ** @return [AcdPAcd] ACD variable object for name.
5481 **
5482 ** @release 2.0.0
5483 ** @@
5484 ******************************************************************************/
5485 
acdNewEndsec(const AjPStr name)5486 static AcdPAcd acdNewEndsec(const AjPStr name)
5487 {
5488     AcdPAcd acd;
5489     static ajint firstcall = 1;
5490     static ajint ikey;
5491     AjPStr secname=NULL;
5492 
5493     if(firstcall)
5494     {
5495 	ikey = acdFindKeyC("endsection");
5496 	firstcall = 0;
5497     }
5498 
5499     acdLog("acdNewEndsec '%S' acdSecList length %d\n",
5500 	   name, ajListstrGetLength(acdSecList));
5501 
5502     if(!ajListstrGetLength(acdSecList))	/* test endsecextra.acd */
5503     {
5504 	acdLog("Bad endsection '%S', not in a section\n", name);
5505 	acdError("Bad endsection '%S', not in a section", name);
5506     }
5507     else
5508     {
5509 	ajListstrPop(acdSecList, &secname);
5510 	acdLog("Pop from acdSecList '%S' new length %d\n",
5511 	       secname, ajListstrGetLength(acdSecList));
5512 
5513 	if(!ajStrMatchS(name, secname))	/* test badendsec.acd */
5514 	{
5515 	    acdLog("Bad endsection '%S', current section is '%S\n'",
5516 		   name, secname);
5517 	    acdError("Bad endsection '%S', current section is '%S'",
5518 		     name, secname);
5519 	}
5520 	ajStrDel(&secname);
5521     }
5522 
5523     acd = acdNewAcdKey(name, name, ikey);
5524     acd->Level = ACD_ENDSEC;
5525 
5526     return acd;
5527 }
5528 
5529 
5530 
5531 
5532 /* @funcstatic acdNewQual *****************************************************
5533 **
5534 ** Constructor front end for a qualifier ACD object.
5535 **
5536 ** @param [r] name [const AjPStr] Token name to be used by applications
5537 ** @param [r] token [const AjPStr] Qualifier name to be used on command line
5538 ** @param [u] type [AjPStr*] Type of value to be defined. Expanded to full
5539 **                           type name.
5540 ** @return [AcdPAcd] ACD parameter object for name.
5541 **
5542 ** @release 1.0.0
5543 ** @@
5544 ******************************************************************************/
5545 
acdNewQual(const AjPStr name,const AjPStr token,AjPStr * type)5546 static AcdPAcd acdNewQual(const AjPStr name, const AjPStr token,
5547 			  AjPStr* type)
5548 {
5549     AcdPAcd acd;
5550     AcdPAcd qacd;
5551     AcdPAcd vacd;
5552     AcdPAcd saveqacd = NULL;
5553     AcdPQual quals;
5554     AjPStr protName = NULL;
5555     AjPStr qname = NULL;
5556     AjPStr qtype = NULL;
5557     ajint itype;
5558     ajint i;
5559 
5560     itype = acdFindType(*type);
5561     ajStrAssignC(type, acdType[itype].Name);
5562 
5563     /* do any associated qualifiers first so they are already complete
5564        when we come to the parameter later in processing */
5565 
5566     i = 0;
5567     quals = acdType[itype].Quals; /* any associated qualifiers for itype?  */
5568     if(quals)
5569 	while(quals[i].Name)
5570 	{
5571 	    ajStrAssignC(&acdQNameTmp, quals[i].Name);
5572 	    ajStrAssignC(&acdQTypeTmp, quals[i].Type);
5573 	    qacd = acdNewQualQual(acdQNameTmp, &acdQTypeTmp);
5574 	    if(*quals[i].Default)
5575 		acdSetDefC(qacd, quals[i].Default);
5576 	    if(!i)
5577 		saveqacd = qacd; /* save the location of the first one */
5578 	    i++;
5579 	}
5580 
5581 
5582     /*
5583      **  now set up the new parameter, and link in the list of qualifiers
5584      ** (if any) from earlier
5585      */
5586 
5587     acdTestUnknown(name, token);
5588     acd = acdNewAcd(name, token, itype);
5589     acd->Level = ACD_QUAL;
5590 
5591     if(saveqacd)
5592 	acd->AssocQuals = saveqacd;
5593 
5594     ajStrDel(&qname);
5595     ajStrDel(&qtype);
5596 
5597     /*
5598     ** For the first sequence, set the sequence type variable
5599     */
5600 
5601     if(!ajStrGetLen(acdVarAcdProtein))
5602 	if((acdType[itype].Attr == acdAttrSeq) ||
5603 	   (acdType[itype].Attr == acdAttrSeqall) ||
5604 	   (acdType[itype].Attr == acdAttrSeqset) ||
5605 	   (acdType[itype].Attr == acdAttrSeqsetall) ||
5606 	   (acdType[itype].Attr == acdAttrFeatures))
5607 	{
5608 	    ajStrAssignC(&protName, "acdprotein");
5609 	    ajFmtPrintS(&acdVarAcdProtein, "$(%S.protein)", name);
5610 	    vacd = acdNewVar(protName);
5611 	    acdSetVarDef(vacd, acdVarAcdProtein);
5612 	    ajDebug("Set acdprotein value '%S'\n", acdVarAcdProtein);
5613 	    ajStrDel(&protName);
5614 	}
5615 
5616     ajStrDel(&protName);
5617     return acd;
5618 }
5619 
5620 
5621 
5622 
5623 /* @funcstatic acdNewQualQual *************************************************
5624 **
5625 ** Constructor front end for an associated qualifier ACD object.
5626 **
5627 ** @param [r] name [const AjPStr] Qualifier name to be used on command line
5628 ** @param [u] type [AjPStr*] Type of value to be defined. Expanded to full
5629 **                           type name.
5630 ** @return [AcdPAcd] ACD parameter object for name.
5631 **
5632 ** @release 1.0.0
5633 ** @@
5634 ******************************************************************************/
5635 
acdNewQualQual(const AjPStr name,AjPStr * type)5636 static AcdPAcd acdNewQualQual(const AjPStr name, AjPStr* type)
5637 {
5638     AcdPAcd acd;
5639     ajint itype;
5640 
5641     itype = acdFindType(*type);
5642     ajStrAssignC(type, acdType[itype].Name);
5643 
5644     acdTestAssocUnknown(name);
5645     acd = acdNewAcd(name, name, itype);
5646     acd->Level = ACD_QUAL;
5647     acd->Assoc = ajTrue;
5648 
5649     return acd;
5650 }
5651 
5652 
5653 
5654 
5655 /* @funcstatic acdNewAcd ******************************************************
5656 **
5657 ** General constructor for a new ACD qualifier object. Initialises all values
5658 ** in the ACD structure as appropriate.
5659 **
5660 ** @param [r] name [const AjPStr] Token name to be used by applications
5661 ** @param [r] token [const AjPStr] Qualifier name to be used on command line
5662 ** @param [r] itype [ajint] Integer type of value to be defined
5663 **        as defined in acdFindType
5664 ** @return [AcdPAcd] ACD parameter object for name.
5665 **
5666 ** @release 1.0.0
5667 ** @@
5668 ******************************************************************************/
5669 
acdNewAcd(const AjPStr name,const AjPStr token,ajint itype)5670 static AcdPAcd acdNewAcd(const AjPStr name, const AjPStr token, ajint itype)
5671 {
5672     ajint i;
5673 
5674     if(acdListLast)
5675 	acdListLast = AJNEW0(acdListLast->Next);
5676     else
5677 	acdListLast = AJNEW0(acdList);
5678 
5679     acdListLast->LineNum = acdLineNum;
5680     ajStrAssignS(&acdListLast->Name, name);
5681     ajStrAssignS(&acdListLast->Token, token);
5682     acdListLast->Type = itype;
5683     ++(*acdType[itype].UseCount);
5684     ++(*acdType[itype].UseClassCount);
5685 
5686     /* we do NAttr and AttrStr explicitly for clarity, */
5687     /* though they are 0 and NULL from the AJNEW0 */
5688 
5689     switch(acdCurrentStage)
5690     {
5691     case QUAL_STAGE:
5692 	acdListLast->NAttr = acdAttrCount(itype);
5693 	break;
5694     default:
5695 	acdListLast->NAttr = 0;
5696 	break;
5697     }
5698 
5699     if(acdListLast->NAttr)
5700     {
5701 	acdListLast->AttrStr = AJCALLOC(acdListLast->NAttr, sizeof(AjPStr));
5702 	for(i = 0; i < acdListLast->NAttr; i++)
5703 	    acdListLast->AttrStr[i] = ajStrNew();
5704     }
5705     else
5706 	acdListLast->AttrStr = NULL;
5707 
5708     acdListLast->DefStr = AJCALLOC(nDefAttr, sizeof(AjPStr));
5709     for(i = 0; i < nDefAttr; i++)
5710 	acdListLast->DefStr[i] = ajStrNew();
5711 
5712     acdListLast->Defined = ajFalse;
5713     acdListLast->Assoc = ajFalse;
5714     acdListLast->ValStr = NULL;
5715 
5716     return acdListLast;
5717 }
5718 
5719 
5720 
5721 
5722 /* @funcstatic acdNewAcdKey ***************************************************
5723 **
5724 ** General constructor for a new ACD general object. Initialises all values
5725 ** in the ACD structure as appropriate.
5726 **
5727 ** @param [r] name [const AjPStr] Token name to be used by applications
5728 ** @param [r] token [const AjPStr] Qualifier name to be used on command line
5729 ** @param [r] ikey [ajint] Integer type of value to be defined
5730 **        as defined in acdFindKey
5731 ** @return [AcdPAcd] ACD parameter object for name.
5732 **
5733 ** @release 1.0.0
5734 ** @@
5735 ******************************************************************************/
5736 
acdNewAcdKey(const AjPStr name,const AjPStr token,ajint ikey)5737 static AcdPAcd acdNewAcdKey(const AjPStr name, const AjPStr token, ajint ikey)
5738 {
5739     ajint i;
5740 
5741     if(acdListLast)
5742 	acdListLast = AJNEW0(acdListLast->Next);
5743     else
5744 	acdListLast = AJNEW0(acdList);
5745 
5746     acdListLast->Next = NULL;
5747     acdListLast->LineNum = acdLineNum;
5748 
5749     ajStrAssignS(&acdListLast->Name, name);
5750     ajStrAssignS(&acdListLast->Token, token);
5751     acdListLast->PNum = 0;
5752     acdListLast->Level = ACD_APPL;
5753     acdListLast->Type = ikey;
5754 
5755     switch(acdCurrentStage)
5756     {
5757     case APPL_STAGE:
5758 	acdListLast->NAttr = acdAttrKeyCount(ikey);
5759 	break;
5760     case VAR_STAGE:
5761 	acdListLast->NAttr = acdAttrKeyCount(ikey);
5762 	break;
5763     case SEC_STAGE:
5764 	acdListLast->NAttr = acdAttrKeyCount(ikey);
5765 	break;
5766     default:
5767 	acdListLast->NAttr = 0;
5768 	break;
5769     }
5770 
5771     if(acdListLast->NAttr)
5772     {
5773 	acdListLast->AttrStr = AJCALLOC(acdListLast->NAttr, sizeof(AjPStr));
5774 	for(i = 0; i < acdListLast->NAttr; i++)
5775 	    acdListLast->AttrStr[i] = ajStrNew();
5776     }
5777     else
5778 	acdListLast->AttrStr = NULL;
5779 
5780     acdListLast->DefStr = NULL;
5781 
5782     acdListLast->SAttr = 0;
5783     acdListLast->SetAttr = NULL;
5784     acdListLast->SetStr = NULL;
5785 
5786     acdListLast->Defined = ajFalse;
5787     acdListLast->Assoc = ajFalse;
5788     acdListLast->AssocQuals = NULL;
5789     acdListLast->ValStr = NULL;
5790     acdListLast->Value = NULL;
5791 
5792     return acdListLast;
5793 }
5794 
5795 
5796 
5797 
5798 /* @funcstatic acdDel *********************************************************
5799 **
5800 ** General destructor for any ACD object.
5801 **
5802 ** @param [d] Pacd [AcdPAcd*] Acd object
5803 ** @return [void]
5804 **
5805 ** @release 4.0.0
5806 ** @@
5807 ******************************************************************************/
5808 
acdDel(AcdPAcd * Pacd)5809 static void acdDel(AcdPAcd *Pacd)
5810 {
5811     AcdPAcd pa = *Pacd;
5812     ajint i;
5813 
5814     if(pa->AttrStr)
5815     {
5816 	for(i = 0; i < pa->NAttr; i++)
5817 	    ajStrDel(&pa->AttrStr[i]);
5818 	AJFREE(pa->AttrStr);
5819     }
5820 
5821     if(pa->DefStr)
5822     {
5823 	for(i = 0; i < nDefAttr; i++)
5824 	    ajStrDel(&pa->DefStr[i]);
5825 	AJFREE(pa->DefStr);
5826     }
5827 
5828     if(pa->SetStr)
5829     {
5830 	for(i = 0; i < pa->SAttr; i++)
5831 	    ajStrDel(&pa->SetStr[i]);
5832 	AJFREE(pa->SetStr);
5833     }
5834 
5835 /* for variables and relations, clear the value */
5836 
5837     /*if(pa->Level ==ACD_VAR || pa->Level == ACD_RELATION )
5838 	ajStrDel(&pa->Value);
5839     else if(!pa->PassByRef)*/
5840 
5841     if(pa->Assoc && ajCharMatchC(acdType[pa->Type].Name,"string"))
5842     {
5843 	ajStrDel((AjPStr*)&pa->Value);
5844     }
5845     else if(pa->Level == ACD_QUAL || pa->Level == ACD_PARAM)
5846     {
5847 	if(!acdType[pa->Type].PassByRef)
5848 	{
5849 	    AJFREE(pa->Value);
5850 	}
5851 	else if(pa->RefPassed != REF_ALL) /* pass-by-ref but never passed */
5852 	{
5853 	    if(pa->RefPassed == REF_NONE)
5854 	    {
5855 		(*acdType[pa->Type].TypeDel)(&pa->Value);
5856 	    }
5857 	    else
5858 	    {
5859 		AJFREE(pa->Value);
5860 	    }
5861 	}
5862     }
5863 
5864 
5865     ajStrDel(&pa->Name);
5866     ajStrDel(&pa->Token);
5867     ajStrDel(&pa->StdPrompt);
5868     ajStrDel(&pa->OrigStr);
5869     ajStrDel(&pa->ValStr);
5870 
5871     AJFREE(*Pacd);
5872 
5873     return;
5874 }
5875 
5876 
5877 
5878 
5879 /* @funcstatic acdTestUnknown *************************************************
5880 **
5881 ** Makes sure that a name, token and pnum do not match any
5882 ** current ACD object.
5883 **
5884 ** Aborts the program with a fatal error in case of problems.
5885 **
5886 ** @param [r] name [const AjPStr] Token name to be used by applications
5887 ** @param [r] alias [const AjPStr] Qualifier name to be used on command line
5888 ** @return [void]
5889 **
5890 ** @release 1.0.0
5891 ** @@
5892 ******************************************************************************/
5893 
acdTestUnknown(const AjPStr name,const AjPStr alias)5894 static void acdTestUnknown(const AjPStr name, const AjPStr alias)
5895 {
5896     AcdPAcd pa;
5897 
5898     pa = acdFindAcdTest(name, alias);
5899 
5900     if(!pa)
5901       return;
5902 
5903     if(ajStrMatchS(name, alias))
5904       acdErrorAcd(pa, "Name '%S' not unique at line %d\n",
5905 		  name, acdLineNum);
5906     else
5907       acdErrorAcd(pa,
5908 		  "Name/Alias '%S'/'%S' not unique at line %d\n",
5909 		  name, alias, acdLineNum);
5910     return;
5911 }
5912 
5913 
5914 
5915 
5916 /* @funcstatic acdCountType ***************************************************
5917 **
5918 ** Counts number of qualifiers with a given type.
5919 **
5920 ** @param [r] type [const char*] ACD type
5921 ** @return [ajint] Number of qualifiers of this type
5922 **
5923 ** @release 4.0.0
5924 ** @@
5925 ******************************************************************************/
5926 
acdCountType(const char * type)5927 static ajint acdCountType(const char* type)
5928 {
5929     ajint ret = 0;
5930     AcdPAcd pa;
5931     ajint itype = 0;
5932 
5933     itype = acdFindTypeC(type);
5934 
5935     for(pa=acdList; pa; pa=pa->Next)
5936     {
5937 	if(pa->Type == itype) ret++;
5938     }
5939 
5940     return ret;
5941 }
5942 
5943 
5944 
5945 
5946 /* @funcstatic acdTestAssocUnknown ********************************************
5947 **
5948 ** Makes sure that a name does not match any known ACD object name or token
5949 ** for all associated qualifiers.
5950 **
5951 ** Aborts the program with a fatal error in case of problems.
5952 **
5953 ** @param [r] name [const AjPStr] Name or token name
5954 ** @return [void]
5955 **
5956 ** @release 2.7.0
5957 ** @@
5958 ******************************************************************************/
5959 
acdTestAssocUnknown(const AjPStr name)5960 static void acdTestAssocUnknown(const AjPStr name)
5961 {
5962     AcdPAcd pa;
5963 
5964     for(pa=acdList; pa; pa=pa->Next)
5965     {
5966 	if(acdIsStype(pa))
5967             continue;
5968 
5969 	if(!pa->Assoc &&(ajStrMatchS(pa->Name, name) ||
5970 			 ajStrMatchS(pa->Token, name)))
5971 	{
5972 	    if(ajStrMatchS(pa->Name, pa->Token)) /* test: dupassoc.acd */
5973 		acdErrorAcd(pa,
5974 			    "Associated qualifier '%S' clashes with '%S' "
5975 			    "in ACD file\n",
5976 			    name, pa->Name);
5977 	    else
5978 		acdErrorAcd(pa,		/* test: dupassoc2.acd */
5979 			    "Associated qualifier '%S' clashes with '%S'/'%S' "
5980 			    "in ACD file\n",
5981 			    name, pa->Name, pa->Token);
5982 	    break;
5983 	}
5984     }
5985 
5986     return;
5987 }
5988 
5989 
5990 
5991 
5992 /* @funcstatic acdFindAcd *****************************************************
5993 **
5994 ** Locates an ACD object by name, token and parameter number.
5995 **
5996 ** @param [r] name [const AjPStr] Token name to be used by applications
5997 ** @param [r] token [const AjPStr] Qualifier name to be used on command line
5998 ** @return [AcdPAcd] ACD object or NULL if not found
5999 **
6000 ** @release 1.0.0
6001 ** @@
6002 ******************************************************************************/
6003 
acdFindAcd(const AjPStr name,const AjPStr token)6004 static AcdPAcd acdFindAcd(const AjPStr name, const AjPStr token)
6005 {
6006     AcdPAcd pa;
6007     AjBool sametoken = ajFalse;
6008 
6009     sametoken = ajStrMatchS(name, token);
6010 
6011     acdLog("acdFindAcd ('%S', '%S', %d)\n", name, token);
6012 
6013     for(pa=acdList; pa; pa=pa->Next)
6014     {
6015       if(acdIsStype(pa))
6016 	continue;
6017 
6018       if(ajStrMatchS(pa->Name, name))
6019       {
6020 	acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6021 	return pa;
6022       }
6023 
6024       if(ajStrMatchS(pa->Token, name))
6025       {
6026 	acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6027 	return pa;
6028       }
6029 
6030       if(!sametoken)
6031 	continue;
6032 
6033       if(ajStrMatchS(pa->Name, token))
6034       {
6035 	acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6036 	return pa;
6037       }
6038 
6039       if(ajStrMatchS(pa->Token, token))
6040       {
6041 	acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6042 	return pa;
6043       }
6044     }
6045 
6046     return NULL;
6047 }
6048 
6049 
6050 
6051 
6052 /* @funcstatic acdFindAcdTest *************************************************
6053 **
6054 ** Locates an ACD object by name, and (if different) by token.
6055 **
6056 ** Tests for unique 6 character prefix and issues a warning if
6057 ** a clash is found with any already defined qualifier.
6058 **
6059 ** All other tests are the same as in acdFindAcd
6060 **
6061 ** @param [r] name [const AjPStr] Token name to be used by applications
6062 ** @param [r] token [const AjPStr] Qualifier name to be used on command line
6063 ** @return [AcdPAcd] ACD object or NULL if not found
6064 **
6065 ** @release 6.1.0
6066 ** @@
6067 ******************************************************************************/
6068 
acdFindAcdTest(const AjPStr name,const AjPStr token)6069 static AcdPAcd acdFindAcdTest(const AjPStr name, const AjPStr token)
6070 {
6071     AcdPAcd savepa = NULL;
6072     AcdPAcd pa;
6073     AjBool usetoken = ajFalse;
6074 
6075     ajuint minunique=7;
6076 
6077     ajStrAssignSubS(&acdPrefName, name, 0, minunique-1);
6078 
6079     usetoken = !ajStrMatchS(name, token);
6080 
6081     if(usetoken)
6082     {
6083         ajStrAssignSubS(&acdPrefToken, token, 0, minunique-1);
6084         acdLog("acdFindAcdTest ('%S' ['%S'], '%S' ['%S'])\n",
6085                name, acdPrefName, token, acdPrefToken);
6086     }
6087     else
6088     {
6089         acdLog("acdFindAcdTest ('%S' ['%S'])\n",
6090                name, acdPrefName);
6091     }
6092 
6093     for(pa=acdList; pa; pa=pa->Next)
6094     {
6095         if(acdIsStype(pa))
6096         {
6097             if(ajStrMatchS(pa->Name, name))
6098                 acdWarn("Qualifier '%S' matches known section '%S'",
6099                         name, pa->Name);
6100             continue;
6101         }
6102 
6103         if(acdIsAtype(pa))
6104         {
6105             if(ajStrMatchS(pa->Name, name))
6106                 acdWarn("Qualifier '%S' matches application name '%S'",
6107                         name, pa->Name);
6108             continue;
6109         }
6110 
6111         if(acdIsVtype(pa))
6112         {
6113             if(ajStrMatchS(pa->Name, name))
6114                 acdWarn("Qualifier '%S' matches variable name '%S'",
6115                         name, pa->Name);
6116             continue;
6117         }
6118 
6119         if(ajStrMatchS(pa->Name, name))
6120         {
6121             acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6122             savepa = pa;
6123         }
6124         else if(ajStrPrefixS(pa->Name, acdPrefName))
6125         {
6126             if(!acdWrapper)
6127                 acdWarn("Qualifier '%S' matches start of known '%S'",
6128                         name, pa->Name);
6129         }
6130         else if(ajStrPrefixS(acdPrefName, pa->Name))
6131         {
6132             if(!acdWrapper)
6133                 acdWarn("Known qualifier '%S' matches start of '%S'",
6134                         pa->Name, name);
6135         }
6136 
6137 
6138         if(!ajStrMatchS(pa->Token, pa->Name)) /* qualifier has a token */
6139         {
6140             if(ajStrMatchS(pa->Token, name))
6141             {
6142                 acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6143                 savepa = pa;
6144             }
6145             else if(ajStrPrefixS(pa->Token, acdPrefName))
6146             {
6147                 if(!acdWrapper)
6148                     acdWarn("Qualifier '%S' matches start of known token '%S'",
6149                             name, pa->Token);
6150             }
6151         }
6152 
6153         if(!usetoken)
6154             continue;
6155 
6156         if(ajStrMatchS(pa->Name, token))
6157         {
6158             acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6159             savepa = pa;
6160         }
6161         else if(ajStrPrefixS(acdPrefToken, pa->Name))
6162         {
6163             if(!acdWrapper)
6164                 acdWarn("Qualifier token '%S' matches start of known '%S'",
6165                         token, pa->Name);
6166         }
6167         else if(ajStrPrefixS(pa->Name, acdPrefToken))
6168         {
6169             if(!acdWrapper)
6170                 acdWarn("Known qualifier '%S' matches start of token '%S'",
6171                         pa->Name, token);
6172         }
6173 
6174         if(!ajStrMatchS(pa->Token, pa->Name)) /* qualifier has a token */
6175         {
6176             if(ajStrMatchS(pa->Token, token))
6177             {
6178                 acdLog("..found '%S' %d\n", pa->Name, pa->PNum);
6179                 savepa = pa;
6180             }
6181             else if(ajStrPrefixS(pa->Token, acdPrefToken))
6182             {
6183                 if(!acdWrapper)
6184                     acdWarn("Qualifier token '%S' matches start of "
6185                             "known token '%S'",
6186                             token, pa->Token);
6187             }
6188         }
6189     }
6190 
6191     return savepa;
6192 }
6193 
6194 
6195 
6196 
6197 /* @funcstatic acdFindAssoc ***************************************************
6198 **
6199 ** Locates an ACD object for an associated qualifier by name.
6200 **
6201 ** Aborts the program with a fatal error in case of problems.
6202 **
6203 ** Used in defining ACD objects and in processing the commandline.
6204 **
6205 ** @param [r] thys [const AcdPAcd] ACD object for the parameter
6206 ** @param [r] name [const AjPStr] Token name to be used by applications
6207 ** @param [r] noname [const AjPStr] Alternative token name (e.g. qualifier
6208 **            with "no" prefix removed)
6209 ** @return [AcdPAcd] ACD object for the selected qualifier
6210 **
6211 ** @release 1.0.0
6212 ** @@
6213 ******************************************************************************/
6214 
acdFindAssoc(const AcdPAcd thys,const AjPStr name,const AjPStr noname)6215 static AcdPAcd acdFindAssoc(const AcdPAcd thys, const AjPStr name,
6216 			    const AjPStr noname)
6217 {
6218     AcdPAcd pa;
6219     ajint ifound=0;
6220     AcdPAcd ret=NULL;
6221     AjPStr ambigList = NULL;
6222 
6223     ambigList = ajStrNew();
6224 
6225     for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next)
6226 	if(ajStrPrefixS(pa->Name, name) ||
6227 	   ajStrPrefixS(pa->Name, noname))
6228 	{
6229 	    if(ajStrMatchS(pa->Name, name) ||
6230 	       ajStrMatchS(pa->Name, noname))
6231 		return pa;
6232 	    ifound++;
6233 	    ret = pa;
6234 	    acdAmbigApp(&ambigList, pa->Name);
6235 	}
6236 
6237 
6238 
6239     if(ifound == 1)
6240     {
6241 	if (acdDoValid)
6242 	    acdWarn("Abbreviated associated qualifier '%S' (%S)",
6243 		    name, ambigList);
6244 	ajStrDel(&ambigList);
6245 	return ret;
6246     }
6247 
6248     if(ifound > 1)
6249     {
6250 	ajWarn("Ambiguous name/token '%S' (%S)", name, ambigList);
6251 	acdErrorAcd(thys,		/* ambigdefattr.acd */
6252 		    "Attribute or qualifier '%S' ambiguous (%S)\n",
6253 		    name, ambigList);
6254 	ajStrDel(&ambigList);
6255     }
6256 
6257     ajStrDel(&ambigList);
6258 
6259     return NULL;
6260 }
6261 
6262 
6263 
6264 
6265 /* @funcstatic acdTestAssoc ***************************************************
6266 **
6267 ** Locates an ACD object for an associated qualifier by name.
6268 **
6269 ** Only tests silently for a possible qualifier.
6270 **
6271 ** If this fails, we check properly later.
6272 **
6273 ** Used in defining ACD objects and in processing the commandline.
6274 **
6275 ** @param [r] thys [const AcdPAcd] ACD object for the parameter
6276 ** @param [r] name [const AjPStr] Token name to be used by applications
6277 ** @param [r] noname [const AjPStr] Alternative token name (e.g. qualifier
6278 **            with "no" prefix removed)
6279 ** @return [AcdPAcd] ACD object for the selected qualifier
6280 **
6281 ** @release 1.0.0
6282 ** @@
6283 ******************************************************************************/
6284 
acdTestAssoc(const AcdPAcd thys,const AjPStr name,const AjPStr noname)6285 static AcdPAcd acdTestAssoc(const AcdPAcd thys, const AjPStr name,
6286 			    const AjPStr noname)
6287 {
6288     AcdPAcd pa;
6289     ajint ifound=0;
6290     AcdPAcd ret=NULL;
6291     AjPStr ambigList = NULL;
6292 
6293     ambigList = ajStrNew();
6294 
6295     for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next)
6296 	if(ajStrPrefixS(pa->Name, name) ||
6297 	   ajStrPrefixS(pa->Name, noname))
6298 	{
6299 	    if(ajStrMatchS(pa->Name, name) ||
6300 	       ajStrMatchS(pa->Name, noname))
6301 	    {
6302 		ajStrDel(&ambigList);
6303 		return pa;
6304 	    }
6305 	    ifound++;
6306 	    ret = pa;
6307 	}
6308 
6309     if(ifound == 1)
6310     {
6311 	if (acdDoValid)
6312 	    acdWarn("Abbreviated associated qualifier '%S' (%S)",
6313 		    name, ambigList);
6314 	ajStrDel(&ambigList);
6315 	return ret;
6316     }
6317 
6318     ajStrDel(&ambigList);
6319 
6320     return NULL;
6321 }
6322 
6323 
6324 
6325 
6326 /* @funcstatic acdTestQualC ***************************************************
6327 **
6328 ** Tests whether "name" is a valid qualifier name.
6329 ** To be valid, it must begin with "-" or '/'.
6330 ** If not, it can be taken as a value for the previous qualifier
6331 **
6332 ** Used after a boolean option to check for a possible value
6333 **
6334 ** Should run silently - if not valid, we will test it next anyway
6335 **
6336 ** @param [r] name [const char*] Qualifier name
6337 ** @return [AjBool] ajTrue if
6338 **
6339 ** @release 1.0.0
6340 ** @@
6341 ******************************************************************************/
6342 
acdTestQualC(const char * name)6343 static AjBool acdTestQualC(const char *name)
6344 {
6345     static AjPStr  qstr = NULL;
6346     static AjPStr  qnostr = NULL;
6347     static AjPStr  qmaster = NULL;
6348     AcdPAcd pa;
6349     AcdPAcd qa;
6350     AcdPAcd savepa=NULL;
6351     ajint qnum = 0;
6352     ajlong i;
6353     ajint ifound=0;
6354     AjPStr ambigList = NULL;
6355 
6356     acdLog("acdTestQualC '%s'\n", name);
6357 
6358     if(*name != '-' && *name != '/' && !strstr(name, "="))
6359 	return ajFalse;		/* not a qualifier name             */
6360 
6361     ambigList = ajStrNew();
6362 
6363     ajStrAssignC(&qstr, name+1);   /* lose the - or / prefix           */
6364 
6365     i = ajStrFindC(qstr, "=");	/* qualifier with value             */
6366 
6367     if(i > 0)
6368 	ajStrKeepRange(&qstr, 0, i-1); /* strip any value and keep testing */
6369 
6370     if(ajStrPrefixC(qstr, "no")) /* check for -no qualifiers          */
6371 	ajStrAssignSubS(&qnostr, qstr, 2, -1);
6372     else
6373 	ajStrAssignClear(&qnostr);
6374 
6375     acdQualParse(&qstr, &qnostr, &qmaster, &qnum);
6376 
6377     if(ajStrGetLen(qmaster))      /* master specified as -qstr_qmaster */
6378     {
6379 	for(pa=acdList; pa; pa=pa->Next)
6380 	{
6381 	    if(acdIsStype(pa)) continue;
6382 	    if(ajStrMatchS(pa->Name, qmaster))
6383 	    {
6384 		acdLog("  *master matched* '%S'\n", pa->Name);
6385 		qa = acdTestAssoc(pa, qstr, qnostr);
6386 		ajStrDel(&ambigList);
6387 		if(qa)
6388 		    return ajTrue;
6389 		else
6390 		    return ajFalse;
6391 	    }
6392 	}
6393 
6394 	if(ajStrPrefixS(pa->Name, qstr))
6395 	{
6396 	    ifound++;
6397 	    savepa = pa;
6398 	    acdAmbigApp(&ambigList, pa->Name);
6399 	}
6400 	acdLog("   ifound: %d\n", ifound);
6401 
6402 	if(ifound == 1)
6403 	{
6404 	    qa = acdTestAssoc(savepa, qstr, qnostr);
6405 	    ajStrDel(&ambigList);
6406 	    ajStrDel(&qstr);
6407 	    ajStrDel(&qnostr);
6408 	    ajStrDel(&qmaster);
6409 	    if(qa)
6410 		return ajTrue;
6411 	    else
6412 		return ajFalse;
6413 	}
6414 
6415 	if(ifound > 1)		/* master should be checked earlier */
6416 	{
6417 	    /* ajWarn("Ambiguous associated qualifier '%s' (%S)",
6418 	       name, ambigList);
6419 	       ajStrDel(&ambigList); */
6420 	    ajStrDel(&ambigList);
6421 	    ajStrDel(&qstr);
6422 	    ajStrDel(&qnostr);
6423 	    ajStrDel(&qmaster);
6424 	    return ajFalse;
6425 	}
6426     }
6427     else			       /* just qualifier name -qstr */
6428     {
6429 	for(pa=acdList; pa; pa=pa->Next)
6430 	{
6431 	    if(acdIsStype(pa))
6432                 continue;
6433 
6434 	    if(ajStrMatchS(pa->Name, qstr))
6435 	    {
6436 		acdLog("   *matched* '%S'\n", pa->Name);
6437 		ajStrDel(&ambigList);
6438 		ajStrDel(&qstr);
6439 		ajStrDel(&qnostr);
6440 		ajStrDel(&qmaster);
6441 		return ajTrue;
6442 	    }
6443 
6444 	    if(ajStrPrefixS(pa->Name, qstr))
6445 	    {
6446 		ifound++;
6447 		acdAmbigApp(&ambigList, pa->Name);
6448 	    }
6449 	}
6450 
6451 	acdLog("   ifound: %d\n", ifound);
6452 
6453 	if(ifound == 1)
6454 	{
6455 	    ajStrDel(&ambigList);
6456 	    ajStrDel(&qstr);
6457 	    ajStrDel(&qnostr);
6458 	    ajStrDel(&qmaster);
6459 	    return ajTrue;
6460 	}
6461 
6462 	if(ifound > 1)
6463 	{
6464 	    /* ajWarn("Ambiguous qualifier '%s' (%S)", name, ambigList);
6465 	       ajStrDel(&ambigList); */
6466 	    ajStrDel(&ambigList);
6467 	    ajStrDel(&qstr);
6468 	    ajStrDel(&qnostr);
6469 	    ajStrDel(&qmaster);
6470 	    return ajFalse;
6471 	}
6472     }
6473 
6474     ajStrDel(&ambigList);
6475     ajStrDel(&qstr);
6476     ajStrDel(&qnostr);
6477     ajStrDel(&qmaster);
6478 
6479     return ajFalse;
6480 }
6481 
6482 
6483 
6484 
6485 /* @funcstatic acdFindType ****************************************************
6486 **
6487 ** Looks for a Type by name, and returns the number in acdType
6488 **
6489 ** @param [r] type [const AjPStr] String containing the type name
6490 ** @return [ajint] Integer representing the type (if know). Can be
6491 **         used as position in the acdType array.
6492 ** @error If not found, the return value points to the maximum position in
6493 **        acdType which is set to NULL throughout.
6494 **
6495 ** @release 1.0.0
6496 ** @@
6497 ******************************************************************************/
6498 
acdFindType(const AjPStr type)6499 static ajint acdFindType(const AjPStr type)
6500 {
6501     ajint i;
6502     ajint ifound = 0;
6503     ajint j = 0;
6504     AjPStr ambigList = NULL;
6505 
6506     ambigList = ajStrNew();
6507 
6508     for(i=0; acdType[i].Name; i++)
6509     {
6510 	if(ajStrMatchC(type, acdType[i].Name))
6511 	{
6512 	    ajStrDel(&ambigList);
6513 	    return i;
6514 	}
6515 
6516 	if(ajCharPrefixS(acdType[i].Name, type))
6517 	{
6518 	    ifound++;
6519 	    j = i;
6520 	    acdAmbigAppC(&ambigList, acdType[i].Name);
6521 	}
6522     }
6523 
6524     if(ifound > 1)
6525     {			      /* warn now with the list, fail below */
6526 	ajWarn("ambiguous type %S (%S)", type, ambigList);
6527     }
6528 
6529     if(ifound != 1)	       /* Fatal: but covered by other tests */
6530 	acdError("unknown type: '%S'\n", type);
6531 
6532     ajStrDel(&ambigList);
6533 
6534     return j;
6535 }
6536 
6537 
6538 
6539 
6540 /* @funcstatic acdFindTypeC ***************************************************
6541 **
6542 ** Looks for a Type by name, and returns the number in acdType
6543 **
6544 ** @param [r] type [const char*] Text string containing the type name
6545 ** @return [ajint] Integer representing the type (if known). Can be
6546 **         used as position in the acdType array.
6547 ** @error If not found, the return value points to the maximum position in
6548 **        acdType which is set to NULL throughout.
6549 **
6550 ** @release 1.0.0
6551 ** @@
6552 ******************************************************************************/
6553 
acdFindTypeC(const char * type)6554 static ajint acdFindTypeC(const char* type)
6555 {
6556     ajint i;
6557     ajint ifound=0;
6558     ajint j=-1;
6559     ajint ilen = strlen(type);
6560     AjPStr ambigList = NULL;
6561 
6562     ambigList = ajStrNew();
6563 
6564     for(i=0; acdType[i].Name; i++)
6565     {
6566 	if(!strcmp(type, acdType[i].Name))
6567 	{
6568 	    ajStrDel(&ambigList);
6569 	    return i;
6570 	}
6571 
6572 	if(!strncmp(acdType[i].Name, type, ilen))
6573 	{
6574 	    ifound++;
6575 	    j = i;
6576 	    acdAmbigAppC(&ambigList, acdType[i].Name);
6577 	}
6578     }
6579 
6580     if(ifound > 1)
6581     {			      /* warn now with the list, fail below */
6582 	ajWarn("ambiguous type %s (%S)", type, ambigList);
6583 	ajStrDel(&ambigList);
6584     }
6585 
6586     if(ifound != 1)	       /* Fatal: but covered by other tests */
6587 	acdError("unknown type: '%s'\n", type);
6588 
6589     ajStrDel(&ambigList);
6590 
6591     return j;
6592 }
6593 
6594 
6595 
6596 
6597 /* @funcstatic acdFindKeyC ****************************************************
6598 **
6599 ** Looks for a Keyword by name, and returns the number in acdKeywords
6600 ***
6601 ** @param [r] key [const char*] Text string containing the keyword name
6602 ** @return [ajint] Integer representing the keyword (if known). Can be
6603 **         used as position in the acdKeywords array.
6604 ** @error If not found, the return value points to the maximum position in
6605 **        acdKeywords which is set to NULL throughout.
6606 **
6607 ** @release 1.0.0
6608 ** @@
6609 ******************************************************************************/
6610 
acdFindKeyC(const char * key)6611 static ajint acdFindKeyC(const char* key)
6612 {
6613     ajint i;
6614     ajint ifound=0;
6615     ajint j=0;
6616     ajint ilen = strlen(key);
6617     AjPStr ambigList = NULL;
6618 
6619     ajStrAssignClear(&ambigList);
6620 
6621     for(i=QUAL_STAGE+1; acdKeywords[i].Name; i++)
6622     {
6623 	if(!strcmp(key, acdKeywords[i].Name))
6624 	{
6625 	    ajStrDel(&ambigList);
6626 	    return i;
6627 	}
6628 
6629 	if(strncmp(acdKeywords[i].Name, key, ilen))
6630 	{
6631 	    ifound++;
6632 	    j = i;
6633 	    acdAmbigAppC(&ambigList, acdKeywords[i].Name);
6634 	}
6635     }
6636 
6637     if(ifound > 1)
6638     {
6639 	ajWarn("ambiguous keyword %s (%S)", key, ambigList);
6640     }
6641 
6642     if(ifound != 1)		/* Fatal: but strings are hard coded */
6643 	acdError("unknown keyword: '%s'\n", key);
6644 
6645     ajStrDel(&ambigList);
6646 
6647     return j;
6648 }
6649 
6650 
6651 
6652 
6653 /*===========================================================================*/
6654 /*======================== Talking to the User ==============================*/
6655 /*===========================================================================*/
6656 
6657 
6658 
6659 
6660 /* @funcstatic acdReplyInitC **************************************************
6661 **
6662 ** Builds a default value for the reply first time around. Uses a default
6663 ** specially set in the ACD, or (if none) uses the default string passed in
6664 ** parameter "defval" and also sets this as the default in the ACD.
6665 **
6666 ** @param [r] thys [const AcdPAcd] ACD object for current item.
6667 ** @param [r] defval [const char*] Default value, as a C string
6668 ** @param [w] reply [AjPStr*] String containing default reply
6669 ** @return [AjBool] ajTrue if a value in the ACD was used.
6670 **
6671 ** @release 6.1.0
6672 ** @@
6673 ******************************************************************************/
6674 
acdReplyInitC(const AcdPAcd thys,const char * defval,AjPStr * reply)6675 static AjBool acdReplyInitC(const AcdPAcd thys, const char *defval,
6676                             AjPStr* reply)
6677 {
6678     AjPStr def;
6679 
6680     if(thys->DefStr)
6681     {
6682 	def = thys->DefStr[DEF_DEFAULT];
6683 	acdLog("acdReplyInitC '%S' : '%S'\n", thys->Name, def);
6684 
6685 	if(ajStrGetLen(def) || thys->Defined)
6686 	{
6687 	    ajStrAssignS(reply, def);
6688 	    acdVarResolve(reply);
6689 	    return ajTrue;
6690 	}
6691     }
6692 
6693     ajStrAssignC(reply, defval);
6694     ajStrAssignC(&thys->DefStr[DEF_DEFAULT], defval);
6695 
6696     return ajFalse;
6697 }
6698 
6699 
6700 
6701 
6702 /* @funcstatic acdReplyInitS **************************************************
6703 **
6704 ** Builds a default value for the reply first time around. Uses a default
6705 ** specially set in the ACD, or (if none) uses the default string passed in
6706 ** parameter "defval" and also sets this as the default in the ACD.
6707 **
6708 ** @param [r] thys [const AcdPAcd] ACD object for current item.
6709 ** @param [r] defval [const AjPStr] Default value, as a string object
6710 ** @param [w] reply [AjPStr*] String containing default reply
6711 ** @return [AjBool] ajTrue if a value in the ACD was used.
6712 **
6713 ** @release 6.1.0
6714 ** @@
6715 ******************************************************************************/
6716 
acdReplyInitS(const AcdPAcd thys,const AjPStr defval,AjPStr * reply)6717 static AjBool acdReplyInitS(const AcdPAcd thys, const AjPStr defval,
6718                             AjPStr* reply)
6719 {
6720     AjPStr def;
6721 
6722     if(thys->DefStr)
6723     {
6724 	def = thys->DefStr[DEF_DEFAULT];
6725 	acdLog("acdReplyInitS '%S' : '%S'\n", thys->Name, def);
6726 
6727 	if(ajStrGetLen(def) || thys->Defined)
6728 	{
6729 	    ajStrAssignS(reply, def);
6730 	    acdVarResolve(reply);
6731 	    return ajTrue;
6732 	}
6733     }
6734 
6735     ajStrAssignS(reply, defval);
6736     ajStrAssignS(&thys->DefStr[DEF_DEFAULT], defval);
6737 
6738     return ajFalse;
6739 }
6740 
6741 
6742 
6743 
6744 /* @funcstatic acdDefinedEmpty ************************************************
6745 **
6746 ** Tests for a defined ACD value of an empty string
6747 **
6748 ** @param [r] thys [const AcdPAcd] ACD object for current item.
6749 ** @return [AjBool] ajTrue if a value in the ACD was used but is empty
6750 **
6751 ** @release 2.9.0
6752 ** @@
6753 ******************************************************************************/
6754 
acdDefinedEmpty(const AcdPAcd thys)6755 static AjBool acdDefinedEmpty (const AcdPAcd thys)
6756 {
6757     AjPStr def;
6758 
6759     if(thys->DefStr)
6760     {
6761 	def = thys->DefStr[DEF_DEFAULT];
6762 	if(thys->Defined && !thys->UserSetNull && !ajStrGetLen(def))
6763 	    return ajTrue;
6764     }
6765 
6766     return ajFalse;
6767 }
6768 
6769 
6770 
6771 
6772 /* @funcstatic acdUserGet *****************************************************
6773 **
6774 ** Given an ACD containing a defined prompt, a help string,
6775 ** or a default (string) value, prompts
6776 ** the user for a string value and returns it.
6777 **
6778 ** If prompt is set, it is used. Otherwise, info can be used.
6779 ** If neither are defined, the item name and type are used to make a
6780 ** meaningful prompt.
6781 **
6782 ** The default value is offered if it is set.
6783 **
6784 ** The user response is returned in "reply"
6785 **
6786 ** If -auto is in effect, fails if there is no value.
6787 **
6788 ** @param [u] thys [AcdPAcd] ACD object for current item.
6789 ** @param [w] reply [AjPStr*] The user response, or
6790 **        the default value if accepted.
6791 ** @return [AjBool] ajTrue if reply contains any text.
6792 **
6793 ** @release 1.0.0
6794 ** @@
6795 ******************************************************************************/
6796 
acdUserGet(AcdPAcd thys,AjPStr * reply)6797 static AjBool acdUserGet(AcdPAcd thys, AjPStr* reply)
6798 {
6799     AjBool ret = ajFalse;
6800 
6801     AjPStr prompt;
6802     AjPStr info;
6803     AjPStr code;
6804     AjPStr help;
6805 
6806 
6807     acdLog("acdUserGet '%S' reply '%S'\n", thys->Name, *reply);
6808 
6809     if(thys->DefStr && !acdAuto)
6810     {
6811 	prompt = thys->DefStr[DEF_PROMPT];
6812 	info = thys->DefStr[DEF_INFO];
6813 	code = thys->DefStr[DEF_CODE];
6814 	help = thys->DefStr[DEF_HELP];
6815 
6816 	ajStrAssignS(&acdUserReplyDef, *reply);
6817 
6818 	if(ajStrGetLen(code))
6819 	    acdCodeGet(code, &acdUserMsg);
6820 	else if(ajStrGetLen(prompt))
6821 	    ajStrAssignS(&acdUserMsg, prompt);
6822 	else if(ajStrGetLen(info))
6823 	    ajStrAssignS(&acdUserMsg, info);
6824 	else if(ajStrGetLen(thys->StdPrompt))
6825 	    ajStrAssignS(&acdUserMsg, thys->StdPrompt);
6826 	else if(ajStrGetLen(help))
6827 	    ajStrAssignS(&acdUserMsg, help);
6828 	else
6829 	{
6830 	    if(!acdCodeDef(thys, &acdUserMsg))
6831 	    {
6832 		ajStrAssignResC(&acdUserMsg, 512, "");
6833 		ajFmtPrintS(&acdUserMsg, "-%S : enter %s value",
6834 			    thys->Name, acdType[thys->Type].Name);
6835 	    }
6836 	}
6837 
6838 	acdVarResolve(&acdUserMsg);
6839 
6840 	acdLog("acdUserGet '%S' replydef '%S' msg '%S'\n",
6841 	       thys->Name, acdUserReplyDef, acdUserMsg);
6842 
6843 	if(ajStrGetLen(acdUserReplyDef))
6844 	    ret = ajUserGet(reply, "%S [%S]: ", acdUserMsg, acdUserReplyDef);
6845 	else
6846 	    ret = ajUserGet(reply, "%S: ", acdUserMsg);
6847 
6848 	if(!ret)
6849 	    ajStrAssignS(reply, acdUserReplyDef);
6850 
6851 	if(ret)
6852 	  thys->UserDefined = ajTrue;
6853 
6854 	acdUserSavereply(thys, NULL, ret, *reply);
6855     }
6856 
6857     if(ajStrGetLen(*reply))
6858 	ret = ajTrue;
6859 
6860     ajStrDelStatic(&acdUserMsg);
6861     ajStrDelStatic(&acdUserReplyDef);
6862 
6863     return ret;
6864 }
6865 
6866 
6867 
6868 
6869 /* @funcstatic acdUserGetPrompt ***********************************************
6870 **
6871 ** Given a defined prompt, prompts
6872 ** the user for a string value and returns it.
6873 **
6874 ** The default value is offered if it is set.
6875 **
6876 ** The user response is returned in "reply"
6877 **
6878 ** If -auto is in effect, fails if there is no value.
6879 **
6880 ** @param [r] thys [const AcdPAcd] ACD object for current item
6881 ** @param [r] assocqual [const char*] Associated qualifier
6882 ** @param [r] prompt [const char*] prompt string
6883 ** @param [w] reply [AjPStr*] The user response, or
6884 **        the default value if accepted.
6885 ** @return [AjBool] ajTrue if reply contains any text.
6886 **
6887 ** @release 1.0.0
6888 ** @@
6889 ******************************************************************************/
6890 
acdUserGetPrompt(const AcdPAcd thys,const char * assocqual,const char * prompt,AjPStr * reply)6891 static AjBool acdUserGetPrompt(const AcdPAcd thys, const char* assocqual,
6892 			       const char* prompt, AjPStr* reply)
6893 {
6894     AjBool ret = ajFalse;
6895 
6896     if(!acdAuto)
6897     {
6898 	ajStrAssignS(&acdUserReplyDef, *reply);
6899 
6900 	if(ajStrGetLen(acdUserReplyDef))
6901 	    ret = ajUserGet(reply, "    %s [%S]: ", prompt, acdUserReplyDef);
6902 	else
6903 	    ret = ajUserGet(reply, "    %s: ", prompt);
6904 
6905 	if(!ret)
6906 	    ajStrAssignS(reply, acdUserReplyDef);
6907 	acdUserSavereply(thys, assocqual, ret, *reply);
6908     }
6909 
6910     if(ajStrGetLen(*reply))
6911 	ret = ajTrue;
6912 
6913 
6914     ajStrDelStatic(&acdUserReplyDef);
6915 
6916     return ret;
6917 }
6918 
6919 
6920 
6921 
6922 /* @funcstatic acdUserSavereply ***********************************************
6923 **
6924 ** Save the reply from prompting the user
6925 **
6926 ** @param [r] thys [const AcdPAcd] ACD object for current item.
6927 ** @param [r] assocqual [const char*] Associated qualifier
6928 ** @param [r] userset [AjBool] Reply set by user
6929 ** @param [r] reply [const AjPStr] Reply string
6930 ** @return [void]
6931 **
6932 ** @release 4.0.0
6933 ******************************************************************************/
6934 
acdUserSavereply(const AcdPAcd thys,const char * assocqual,AjBool userset,const AjPStr reply)6935 static void acdUserSavereply(const AcdPAcd thys, const char* assocqual,
6936 			     AjBool userset, const AjPStr reply)
6937 {
6938     AjPStr qualname = NULL;
6939 
6940     if(assocqual)
6941     {
6942 	ajStrAssignC(&qualname, assocqual);
6943 	ajStrAppendK(&qualname, '_');
6944 	ajStrAppendS(&qualname, thys->Name);
6945     }
6946     else
6947 	ajStrAssignS(&qualname, thys->Name);
6948 
6949     if(ajStrMatchS(acdInputName, qualname))
6950 	ajStrTruncateLen(&acdInputSave, acdInputLen);
6951     else
6952     {
6953 	ajStrAssignS(&acdInputName, qualname);
6954 	acdInputLen = ajStrGetLen(acdInputSave);
6955     }
6956 
6957     if(userset)
6958     {
6959 	if(acdInputLen)
6960 	    ajStrAppendK(&acdInputSave, '\n');
6961 
6962 	ajStrAppendK(&acdInputSave, '-');
6963 	ajStrAppendS(&acdInputSave, qualname);
6964 	ajStrAppendK(&acdInputSave, ' ');
6965 	if(ajStrIsWord(reply) && (ajStrFindAnyC(reply, "*?[]{}|!&^") < 0))
6966 	    ajStrAppendS(&acdInputSave, reply);
6967 	else
6968 	{
6969 	    ajStrAppendK(&acdInputSave, '\"');
6970 	    ajStrAppendS(&acdInputSave, reply);
6971 	    ajStrAppendK(&acdInputSave, '\"');
6972 	}
6973     }
6974 
6975     ajStrDel(&qualname);
6976 
6977     return;
6978 }
6979 
6980 
6981 
6982 
6983 /* @funcstatic acdBadRetry ****************************************************
6984 **
6985 ** Writes a message to stderr, and kills the application.
6986 **
6987 ** @param [r] thys [const AcdPAcd] ACD object.
6988 ** @return [void]
6989 **
6990 ** @release 1.0.0
6991 ** @@
6992 ******************************************************************************/
6993 
acdBadRetry(const AcdPAcd thys)6994 static void acdBadRetry(const AcdPAcd thys)
6995 {
6996     /* test acdc-retry */
6997     ajDie("%S terminated: Bad value for '-%S' and no more retries",
6998 	  acdProgram, thys->Name);
6999 }
7000 
7001 
7002 
7003 
7004 /* @funcstatic acdBadVal ******************************************************
7005 **
7006 ** Writes a message to stderr, returns only if this is a standard value
7007 ** and we are prompting for values.
7008 **
7009 ** @param [r] thys [const AcdPAcd] ACD object
7010 ** @param [r] required [AjBool] If true, prompting for the value
7011 **                              was possible.
7012 ** @param [r] fmt [const char*] Format with ajFmt extensions
7013 ** @param [v] [...] Optional arguments
7014 ** @return [void]
7015 **
7016 ** @release 1.0.0
7017 ** @@
7018 ******************************************************************************/
7019 
acdBadVal(const AcdPAcd thys,AjBool required,const char * fmt,...)7020 static void acdBadVal(const AcdPAcd thys, AjBool required,
7021 		      const char *fmt, ...)
7022 {
7023     va_list args;
7024     static AjPStr msg = NULL;
7025 
7026     /*
7027      ** replaced line below with following 2 to make msg more obvious to
7028      ** the user
7029      **/
7030 
7031     acdLog("Failure for option '%S'\n",thys->Name);
7032     ajFmtPrintS(&msg, "%s", fmt);
7033 
7034     va_start(args, fmt) ;
7035     ajVErr(ajStrGetPtr(msg), args);
7036     va_end(args) ;
7037 
7038     if(!required && !acdAuto)		/* test acdc-badadvanced */
7039 	ajDie("%S terminated: Bad value for '-%S' and no prompt",
7040 	      acdProgram, thys->Name);
7041 
7042     if(acdAuto)				/* test acdc-badauto */
7043 	ajDie("%S terminated: Bad value for '-%S' with -auto defined",
7044 	      acdProgram, thys->Name);
7045 
7046     return;
7047 }
7048 
7049 
7050 
7051 
7052 /* @section return ************************************************************
7053 **
7054 ** Returns values to the calling program.
7055 **
7056 ** @fdata [none]
7057 **
7058 ** @nam3rule  Get    Get value
7059 ** @nam4rule  GetAlign    ACD alignment datatype
7060 ** @nam4rule  GetArray    ACD array datatype
7061 ** @nam4rule  GetAssembly   ACD assembly datatype
7062 ** @nam4rule  GetBoolean  ACD boolean datatype
7063 ** @nam4rule  GetCodon    ACD codon usage datatype
7064 ** @nam4rule  GetCpdb    ACD clean PDB data datatype
7065 ** @nam4rule  GetDatafile    ACD datafile datatype
7066 ** @nam4rule  GetDirectory    ACD directory datatype
7067 ** @nam4rule  GetDirlist    ACD directory list datatype
7068 ** @nam4rule  GetDiscretestates   ACD discrete states datatype
7069 ** @nam4rule  GetDistances    ACD distances datatype
7070 ** @nam4rule  GetFeatout    ACD features output datatype
7071 ** @nam4rule  GetFeatures   ACD features datatype
7072 ** @nam4rule  GetFeaturesall   ACD features stream datatype
7073 ** @nam4rule  GetFilelist   ACD file list datatype
7074 ** @nam4rule  GetFloat    ACD floating point number datatype
7075 ** @nam4rule  GetFrequencies    ACD frequencies datatype
7076 ** @nam4rule  GetGraph    ACD graphical output datatype
7077 ** @nam4rule  GetGraphxy   ACD XY plot graphical output datatype
7078 ** @nam4rule  GetInfile    ACD input file datatype
7079 ** @nam4rule  GetInt    ACD integer number datatype
7080 ** @nam4rule  GetList    ACD list menu items datatype
7081 ** @nam4rule  GetMatrix    ACD integer comparison matrix datatype
7082 ** @nam4rule  GetMatrixf    ACD floating point comparison matrix datatype
7083 ** @nam4rule  GetObo   ACD obo term datatype
7084 ** @nam4rule  GetOboall   ACD obo term stream datatype
7085 ** @nam4rule  GetOutassembly   ACD assembly output datatype
7086 ** @nam4rule  GetOutcodon    ACD codon usage output datatype
7087 ** @nam4rule  GetOutcpdb    ACD clean PDB output datatype
7088 ** @nam4rule  GetOutdata    ACD output datafile datatype
7089 ** @nam4rule  GetOutdir    ACD output directory datatype
7090 ** @nam4rule  GetOutdiscrete    ACD discrete states output datatype
7091 ** @nam4rule  GetOutdistance    ACD distance output datatype
7092 ** @nam4rule  GetOutfile   ACD output file datatype
7093 ** @nam4rule  GetOutfreq   ACD frequency output datatype
7094 ** @nam4rule  GetOutmatrix   ACD integer comparison matrix output datatype
7095 ** @nam4rule  GetOutmatrixf  ACD floating point comparison matrix output
7096 **                           datatype
7097 ** @nam4rule  GetOutobo   ACD OBO ontology term output datatype
7098 ** @nam4rule  GetOutproperties   ACD properties output datatype
7099 ** @nam4rule  GetOutrefseq   ACD reference sequence output datatype
7100 ** @nam4rule  GetOutresource   ACD data resource output datatype
7101 ** @nam4rule  GetOutscop   ACD SCOP output datatype
7102 ** @nam4rule  GetOuttaxon  ACD taxon output datatype
7103 ** @nam4rule  GetOuttext  ACD text output datatype
7104 ** @nam4rule  GetOuttree   ACD tree output datatype
7105 ** @nam4rule  GetOuturl  ACD URL output datatype
7106 ** @nam4rule  GetOutvariation  ACD variation output datatype
7107 ** @nam4rule  GetOutxml   ACD xml output datatype
7108 ** @nam4rule  GetPattern   ACD prosite pattern datatype
7109 ** @nam4rule  GetProperties   ACD properties datatype
7110 ** @nam4rule  GetRange   ACD position ranges datatype
7111 ** @nam4rule  GetRefseq   ACD reference sequence datatype
7112 ** @nam4rule  GetRegexp    ACD regular expression datatype
7113 ** @nam4rule  GetReport   ACD report output datatype
7114 ** @nam4rule  GetResource   ACD data resource datatype
7115 ** @nam4rule  GetResourceall   ACD data resource stream datatype
7116 ** @nam4rule  GetScop   ACD SCOP data file datatype
7117 ** @nam4rule  GetSelect   ACD selection menu items datatype
7118 ** @nam4rule  GetSeq   ACD sequence input datatype
7119 ** @nam4rule  GetSeqall   ACD sequence stream input datatype
7120 ** @nam4rule  GetSeqout   ACD sequence output datatype
7121 ** @nam4rule  GetSeqoutall   ACD sequence stream output datatype
7122 ** @nam4rule  GetSeqoutset   ACD sequence set output datatype
7123 ** @nam4rule  GetSeqset   ACD sequence set input datatype
7124 ** @nam4rule  GetSeqsetall   ACD sequence sets datatype
7125 ** @nam4rule  GetString   ACD string datatype
7126 ** @nam4rule  GetTaxon   ACD taxon datatype
7127 ** @nam4rule  GetTaxonall   ACD taxon stream datatype
7128 ** @nam4rule  GetText   ACD text datatype
7129 ** @nam4rule  GetTextall   ACD text stream datatype
7130 ** @nam4rule  GetToggle   ACD boolean toggle datatype
7131 ** @nam4rule  GetTree   ACD phylogenetic tree datatype
7132 ** @nam4rule  GetUrl   ACD url datatype
7133 ** @nam4rule  GetUrlall   ACD url stream datatype
7134 ** @nam4rule  GetVariation   ACD variation datatype
7135 ** @nam4rule  GetVariationall   ACD variation stream datatype
7136 ** @nam4rule  GetXml   ACD xml datatype
7137 ** @nam4rule  GetXmlall   ACD xml stream datatype
7138 ** @nam4rule  GetValue   ACD datatype string value
7139 ** @nam5rule  GetValueDefault   ACD datatype default value
7140 ** @nam5rule  Name    Name of ACD datatype value
7141 ** @nam5rule  Single  First in array of ACD datatype values
7142 ** @nam3rule  Getpath  Return path for a program defined as external
7143 ** @nam3rule  Is    Test value
7144 ** @nam4rule  IsUserdefined    Test value is defined by the user
7145 ** @suffix C Character string data
7146 ** @suffix S String object data
7147 **
7148 ** @suffix Double Return double precision
7149 ** @suffix Long   Return long integer
7150 **
7151 ** @argrule   Get    token [const char*] Token name
7152 ** @argrule   C      token [const char*] Token name
7153 ** @argrule   S   strtoken [const AjPStr] Token name
7154 ** @argrule   Num    token [const char*] Token name
7155 **
7156 ** @valrule   Align            [AjPAlign]
7157 ** @valrule   Array            [AjPFloat]
7158 ** @valrule   Assembly         [AjPAssemload]
7159 ** @valrule   Boolean          [AjBool]
7160 ** @valrule   Codon            [AjPCod]
7161 ** @valrule   Cpdb             [AjPFile]
7162 ** @valrule   Datafile         [AjPFile]
7163 ** @valrule   Directory        [AjPDir]
7164 ** @valrule   Dirlist          [AjPList]
7165 ** @valrule   Discretestates   [AjPPhyloState*]
7166 ** @valrule   *DiscretestatesSingle  [AjPPhyloState]
7167 ** @valrule   Distances        [AjPPhyloDist*]
7168 ** @valrule   *DistancesSingle [AjPPhyloDist]
7169 ** @valrule   Featout          [AjPFeattabOut]
7170 ** @valrule   Features         [AjPFeattable]
7171 ** @valrule   Featuresall      [AjPFeattaball]
7172 ** @valrule   Filelist         [AjPList]
7173 ** @valrule   Float            [float]
7174 ** @valrule   *FloatDouble     [double]
7175 ** @valrule   Frequencies      [AjPPhyloFreq]
7176 ** @valrule   Graph            [AjPGraph]
7177 ** @valrule   Graphxy          [AjPGraph]
7178 ** @valrule   Infile           [AjPFile]
7179 ** @valrule   Int              [ajint]
7180 ** @valrule   *IntLong         [ajlong]
7181 ** @valrule   List             [AjPStr*]
7182 ** @valrule   *ListSingle      [AjPStr]
7183 ** @valrule   Matrix           [AjPMatrix]
7184 ** @valrule   Matrixf          [AjPMatrixf]
7185 ** @valrule   Obo              [AjPObo]
7186 ** @valrule   Oboall           [AjPOboall]
7187 ** @valrule   Outassembly      [AjPOutfile]
7188 ** @valrule   Outcodon         [AjPOutfile]
7189 ** @valrule   Outcpdb          [AjPOutfile]
7190 ** @valrule   Outdata          [AjPOutfile]
7191 ** @valrule   Outdir           [AjPDirout]
7192 ** @valrule   Outdiscrete      [AjPOutfile]
7193 ** @valrule   Outdistance      [AjPOutfile]
7194 ** @valrule   Outfile          [AjPFile]
7195 ** @valrule   *OutfileName     [AjPStr]
7196 ** @valrule   Outfreq          [AjPOutfile]
7197 ** @valrule   Outmatrix        [AjPOutfile]
7198 ** @valrule   Outmatrixf       [AjPOutfile]
7199 ** @valrule   Outobo           [AjPOutfile]
7200 ** @valrule   Outproperties    [AjPOutfile]
7201 ** @valrule   Outrefseq        [AjPOutfile]
7202 ** @valrule   Outresource      [AjPOutfile]
7203 ** @valrule   Outscop          [AjPOutfile]
7204 ** @valrule   Outtaxon         [AjPOutfile]
7205 ** @valrule   Outtext          [AjPOutfile]
7206 ** @valrule   Outtree          [AjPOutfile]
7207 ** @valrule   Outurl           [AjPOutfile]
7208 ** @valrule   Outvariation     [AjPOutfile]
7209 ** @valrule   Outxml           [AjPOutfile]
7210 ** @valrule   Pattern          [AjPPatlistSeq]
7211 ** @valrule   Properties       [AjPPhyloProp]
7212 ** @valrule   Range            [AjPRange]
7213 ** @valrule   Refseq           [AjPRefseq]
7214 ** @valrule   Regexp           [AjPPatlistRegex]
7215 ** @valrule   *RegexpSingle    [AjPRegexp]
7216 ** @valrule   Report           [AjPReport]
7217 ** @valrule   Resource         [AjPResource]
7218 ** @valrule   Resourceall      [AjPResourceall]
7219 ** @valrule   Scop             [AjPFile]
7220 ** @valrule   Select           [AjPStr*]
7221 ** @valrule   *SelectSingle    [AjPStr]
7222 ** @valrule   Seq              [AjPSeq]
7223 ** @valrule   Seqall           [AjPSeqall]
7224 ** @valrule   Seqout           [AjPSeqout]
7225 ** @valrule   Seqoutall        [AjPSeqout]
7226 ** @valrule   Seqoutset        [AjPSeqout]
7227 ** @valrule   Seqset           [AjPSeqset]
7228 ** @valrule   Seqsetall        [AjPSeqset*]
7229 ** @valrule   *SeqsetallSingle [AjPSeqset]
7230 ** @valrule   String           [AjPStr]
7231 ** @valrule   Taxon            [AjPTax]
7232 ** @valrule   Taxonall         [AjPTaxall]
7233 ** @valrule   Text             [AjPText]
7234 ** @valrule   Textall          [AjPTextall]
7235 ** @valrule   Toggle           [AjBool]
7236 ** @valrule   Tree             [AjPPhyloTree*]
7237 ** @valrule   *TreeSingle      [AjPPhyloTree]
7238 ** @valrule   Url              [AjPUrl]
7239 ** @valrule   Urlall           [AjPUrlall]
7240 ** @valrule   Variation        [AjPVarload]
7241 ** @valrule   Variationall     [AjPVarall]
7242 ** @valrule   Xml              [AjPXml]
7243 ** @valrule   Xmlall           [AjPXmlall]
7244 ** @valrule   Value            [const AjPStr]
7245 ** @valrule   *Name            [AjPStr]
7246 ** @valrule   Getpath          [const AjPStr]
7247 ** @valrule   Is               [AjBool]
7248 ** @fcategory misc
7249 **
7250 ******************************************************************************/
7251 
7252 
7253 
7254 
7255 /* @funcstatic acdSetXxxx *****************************************************
7256 **
7257 ** Dummy function to handle prompting and validation for an ACD item type.
7258 ** A similar routine is needed for any new item type. See the other acdSet
7259 ** functions for ideas on what to include.
7260 **
7261 ** This functions knows all the attributes, defaults, associated qualifiers
7262 ** and validation rules for type Xxxx. If any attributes (etc) are added,
7263 ** this is where the processing will be done.
7264 **
7265 ** The final value (of type Xxxx) is set in thys as Value
7266 ** and a string equivalent for easy printing is set in thys as Valstr
7267 **
7268 ** The function does not need to return a value. It either succeeds in filling
7269 ** in all values, or aborts with a suitable error messages.
7270 **
7271 ** @param [u] thys [AcdPAcd] ACD for current item (which is
7272 **        always of type Xxxx)
7273 ** @return [void]
7274 **
7275 ** @release 1.0.0
7276 ** @@
7277 ******************************************************************************/
7278 
acdSetXxxx(AcdPAcd thys)7279 static void acdSetXxxx(AcdPAcd thys)
7280 {
7281     AjPStr val;
7282 
7283     AjBool required = ajFalse;
7284     AjBool ok       = ajFalse;
7285     ajint itry;
7286 
7287     /*
7288      ** create storage for val if needed, e.g. with AJNEW0(val)
7289      */
7290 
7291     val = NULL;				/* set a default value */
7292 
7293     required = acdIsRequired(thys);
7294     acdReplyInitC(thys, "", &acdReply);
7295 
7296     for(itry=acdPromptTry; itry && !ok; itry--)
7297     {
7298 	if(required)			/* need to prompt? */
7299 	    acdUserGet(thys, &acdReply);
7300 
7301 	ok = ajTrue;			/* test the value somehow */
7302     }
7303 
7304     if(!ok)
7305 	acdBadRetry(thys);
7306 
7307     ajStrAssignS(&val, acdReply);	/* use the validated reply */
7308     thys->Value = val;			/* set the value           */
7309     ajStrAssignS(&thys->ValStr, val);	/* set the string value    */
7310 
7311     return;
7312 }
7313 
7314 
7315 
7316 
7317 /* @funcstatic acdSetAppl *****************************************************
7318 **
7319 ** Makes sure all application ACD item values have been set.
7320 **
7321 ** Called when an "appl" type ACD item is checked. Should not be called
7322 ** for any other item. The "appl" item may not be the first, as there
7323 ** are some 'standard' qualifiers set in advance for debugging, help and
7324 ** so on.
7325 **
7326 ** At present there is nothing to prompt for here, though there could
7327 ** be, for example, a report of what the program does which would appear
7328 ** before any user prompts.
7329 **
7330 ** @param [u] thys [AcdPAcd] ACD for the application item.
7331 ** @return [void]
7332 **
7333 ** @release 1.0.0
7334 ** @@
7335 ******************************************************************************/
7336 
acdSetAppl(AcdPAcd thys)7337 static void acdSetAppl(AcdPAcd thys)
7338 {
7339     AjPStr appldoc = NULL;
7340     AjPStr applobsolete = NULL;
7341     AjPStr applexternal = NULL;
7342     AjPStrTok handle = NULL;
7343     AjPStr token = NULL;
7344     AjPStr message = NULL;
7345     AjPStr appname = NULL;      /* saved to table */
7346     AjPStr appfullname = NULL;  /* saved to table */
7347 
7348     acdAttrResolve(thys, "documentation", &appldoc);
7349     acdAttrResolve(thys, "obsolete", &applobsolete);
7350     acdAttrResolve(thys, "external", &applexternal);
7351 
7352     acdAppldoc = ajStrNewS(appldoc);
7353 
7354     if(!acdExternalTable)
7355         acdExternalTable = ajTablestrNewCase(50);
7356 
7357     if(!acdAuto && ajStrGetLen(appldoc))
7358     {
7359 	ajStrFmtWrap(&appldoc, 75);
7360 	ajUserDumpS(appldoc);
7361     }
7362 
7363     ajStrAssignS(&thys->ValStr, thys->Name);
7364 
7365     if(ajStrGetLen(applobsolete))
7366     {
7367         acdWarnObsolete(applobsolete);
7368     }
7369 
7370     if(ajStrGetLen(applexternal))
7371     {
7372         ajStrTokenAssignC(&handle, applexternal, "|");
7373 
7374         while(ajStrTokenNextParse(handle, &token))
7375         {
7376             ajStrExtractFirst(token, &message, &appname);
7377             ajStrAssignS(&appfullname, appname);
7378 
7379             if(!ajSysFileWhich(&appfullname))
7380             {
7381                 ajStrFmtWrapLeft(&message, 70, 5, 0);
7382                 ajDie("%S uses external program '%S' "
7383                       "which is not in the PATH or defined as %S_%US\n%S",
7384                       acdProgram, appname,
7385                       ajNamValuePackage(), appname, message);
7386             }
7387 
7388             ajTablePut(acdExternalTable, appname, appfullname);
7389             appname = NULL;
7390             appfullname = NULL;
7391         }
7392 
7393     }
7394 
7395     ajStrDel(&appldoc);
7396     ajStrDel(&applobsolete);
7397     ajStrDel(&applexternal);
7398     ajStrDel(&message);
7399     ajStrDel(&token);
7400 
7401     ajStrTokenDel(&handle);
7402 
7403     return;
7404 }
7405 
7406 
7407 
7408 
7409 /* @funcstatic acdSetEndsec ***************************************************
7410 **
7411 ** Ends the current ACD section
7412 **
7413 ** Called when an "endsection" type ACD item is checked. Should not be called
7414 ** for any other item.
7415 **
7416 ** At present there is nothing to prompt for here, though there could
7417 ** be, for example, a blank line at the end of a section where
7418 ** something was prompted for.
7419 **
7420 ** @param [u] thys [AcdPAcd] ACD for the endsection item.
7421 ** @return [void]
7422 **
7423 ** @release 2.0.0
7424 ** @@
7425 ******************************************************************************/
7426 
acdSetEndsec(AcdPAcd thys)7427 static void acdSetEndsec(AcdPAcd thys)
7428 {
7429     if(thys->DefStr)
7430 	ajStrAssignS(&thys->ValStr, thys->DefStr[DEF_DEFAULT]);
7431 
7432     acdVarResolve(&thys->ValStr);
7433 
7434     return;
7435 }
7436 
7437 
7438 
7439 
7440 /* @funcstatic acdSetSec ******************************************************
7441 **
7442 ** Starts a new ACD section.
7443 **
7444 ** Called when a "section" type ACD item is checked. Should not be called
7445 ** for any other item.
7446 **
7447 ** At present there is nothing to prompt for here, though there could
7448 ** be, for example, a prompt issued before the first prompt for the section.
7449 ** This would be stored (the 'info' attribute) and used in the standard
7450 ** prompting functions.
7451 **
7452 ** @param [u] thys [AcdPAcd] ACD for the section item.
7453 ** @return [void]
7454 **
7455 ** @release 2.0.0
7456 ** @@
7457 ******************************************************************************/
7458 
acdSetSec(AcdPAcd thys)7459 static void acdSetSec(AcdPAcd thys)
7460 {
7461     ajint border   = 1;
7462     AjPStr comment = NULL;
7463     AjPStr folder  = NULL;
7464     AjPStr info    = NULL;
7465     AjPStr side    = NULL;
7466     AjPStr type    = NULL;
7467 
7468     const char* sideVal[] = {"top", "bottom", "left", "right", NULL};
7469     const char* typeVal[] = {"frame", "page", NULL};
7470 
7471     if(acdAttrToStr(thys, "type", "", &type))
7472 	if(!acdVocabCheck(type, typeVal))
7473 	    acdErrorAcd(thys,
7474 			"section %S, bad attribute value type: %S",
7475 			thys->Name, type);
7476 
7477     if(acdAttrToInt(thys, "border", 1, &border))
7478     {
7479 	if(!ajStrMatchCaseC(type, "frame"))
7480 	    ajWarn("section %S, border only used by type: frame",
7481 		   thys->Name);
7482 
7483 	if(border < 1)
7484 	{
7485 	    acdAttrToStr(thys, "border", "", &acdTmpStr);
7486 	    acdErrorAcd(thys,
7487 			"section %S, bad attribute value type: %S",
7488 			acdTmpStr);
7489 	}
7490     }
7491 
7492     acdAttrToStr(thys, "comment", "", &comment);
7493 
7494     if(acdAttrToStr(thys, "folder", "", &folder))
7495     {
7496 	if(!ajStrMatchCaseC(type, "page"))
7497 	    ajWarn("section %S, folder only used by type: page",
7498 		   thys->Name);
7499     }
7500 
7501     acdAttrToStr(thys, "information", "", &info);
7502 
7503     if(acdAttrToStr(thys, "side", "", &side))
7504     {
7505 	if(!acdVocabCheck(side, sideVal))
7506 	    acdErrorAcd(thys,
7507 			"section %S, bad attribute value side: %S",
7508 			thys->Name, side);
7509 
7510 	if(!ajStrMatchCaseC(type, "frame"))
7511 	    ajWarn("section %S, side only used by type: frame",
7512 		   thys->Name);
7513     }
7514 
7515     ajStrDel(&comment);
7516     ajStrDel(&folder);
7517     ajStrDel(&info);
7518     ajStrDel(&side);
7519     ajStrDel(&type);
7520 
7521     return;
7522 }
7523 
7524 
7525 
7526 
7527 /* @funcstatic acdSetVar ******************************************************
7528 **
7529 ** Defines an ACD variable.
7530 **
7531 ** Called when a "variable" type ACD item is checked. Should not be called
7532 ** for any other item.
7533 **
7534 ** At present there is nothing to prompt for here, though there could
7535 ** be, for example, a report of what the program does which would appear
7536 ** before any user prompts.
7537 **
7538 ** @param [u] thys [AcdPAcd] ACD for the application item.
7539 ** @return [void]
7540 **
7541 ** @release 1.0.0
7542 ** @@
7543 ******************************************************************************/
7544 
acdSetVar(AcdPAcd thys)7545 static void acdSetVar(AcdPAcd thys)
7546 {
7547     if(thys->DefStr)
7548 	ajStrAssignS(&thys->ValStr, thys->DefStr[DEF_DEFAULT]);
7549 
7550     acdVarResolve(&thys->ValStr);
7551 
7552     return;
7553 }
7554 
7555 
7556 
7557 
7558 /* @func ajAcdGetAlign ********************************************************
7559 **
7560 ** Returns an item of type Align as defined in a named ACD item.
7561 ** Called by the application after all ACD values have been set,
7562 ** and simply returns what the ACD item already has.
7563 **
7564 ** @param [r] token [const char*] Text token name
7565 ** @return [AjPAlign] Alignment output object. Already opened
7566 **                      by ajAlignOpent so this just returns the object
7567 ** @cre failure to find an item with the right name and type aborts.
7568 **
7569 ** @release 2.1.0
7570 ** @@
7571 ******************************************************************************/
7572 
ajAcdGetAlign(const char * token)7573 AjPAlign ajAcdGetAlign(const char *token)
7574 {
7575     return acdGetValueRef(token, "align");
7576 }
7577 
7578 
7579 
7580 
7581 /* @funcstatic acdSetAlign ****************************************************
7582 **
7583 ** Using the definition in the ACD file, and any values for the
7584 ** item or its associated qualifiers provided on the command line,
7585 ** prompts the user if necessary (and possible) and
7586 ** sets the actual value for an ACD alignment output item.
7587 **
7588 ** Understands all attributes and associated qualifiers for this item type.
7589 **
7590 ** The default value (if no other available) is a null string, which
7591 ** is invalid.
7592 **
7593 ** Associated qualifier "-aformat"
7594 ** is applied when writing the sequences.
7595 **
7596 ** @param [u] thys [AcdPAcd] ACD item.
7597 ** @return [void]
7598 ** @see ajSeqRead
7599 **
7600 ** @release 2.1.0
7601 ** @@
7602 ******************************************************************************/
7603 
acdSetAlign(AcdPAcd thys)7604 static void acdSetAlign(AcdPAcd thys)
7605 {
7606     AjPAlign val = NULL;
7607 
7608     AjBool required = ajFalse;
7609     AjBool ok       = ajFalse;
7610 
7611     ajint itry;
7612     AjBool nullok;
7613     AjBool nulldefault;
7614 
7615     AjPStr name      = NULL;
7616     AjPStr ext       = NULL;
7617     AjPStr fmt       = NULL;
7618     AjPStr dir       = NULL;
7619 
7620     val = NULL;
7621 
7622 
7623     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
7624     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
7625 
7626     acdGetValueAssoc(thys, "aformat", &fmt);
7627     acdGetValueAssoc(thys, "aextension", &ext);
7628     acdGetValueAssoc(thys, "aname", &name);
7629     acdGetValueAssoc(thys, "adirectory", &dir);
7630 
7631     acdOutDirectory(&dir);
7632     required = acdIsRequired(thys);
7633 
7634     if(nullok && nulldefault)
7635     {
7636 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
7637 	    acdOutFilename(&acdReplyDef, name, ext);
7638 	else				/* leave empty */
7639 	    acdReplyInitC(thys, "", &acdReplyDef);
7640     }
7641     else
7642     {
7643 	acdOutFilename(&acdTmpOutFName, name, ext);
7644 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
7645     }
7646 
7647     acdPromptAlign(thys);
7648     ajStrDel(&name);
7649     ajStrDel(&ext);
7650 
7651     for(itry=acdPromptTry; itry && !ok; itry--)
7652     {
7653 	ok = ajTrue;	   /* accept the default if nothing changes */
7654 
7655 	ajStrAssignS(&acdReply, acdReplyDef);
7656 
7657 	if(required)
7658 	    acdUserGet(thys, &acdReply);
7659 
7660 	if(ajStrGetLen(acdReply))
7661 	{
7662 	    val = ajAlignNew();
7663 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
7664 	    acdAttrToStr(thys, "type", "", &val->Type);
7665 	    acdAttrToInt(thys, "minseqs", 0, &val->Nmin);
7666 	    acdAttrToInt(thys, "maxseqs", 0, &val->Nmax);
7667 	    acdAttrToBool(thys, "multiple", ajFalse, &val->Multi);
7668 	    acdQualToInt(thys, "awidth", 50, &val->Width, &acdTmpStr);
7669 	    acdQualToBool(thys, "aglobal", ajFalse,
7670 			  &val->Global, &acdTmpStr);
7671 	    acdQualToBool(thys, "aaccshow", ajFalse,
7672 			  &val->Showacc, &acdTmpStr);
7673 	    acdQualToBool(thys, "adesshow", ajFalse,
7674 			  &val->Showdes, &acdTmpStr);
7675 	    acdQualToBool(thys, "ausashow", ajFalse,
7676 			  &val->Showusa, &acdTmpStr);
7677 	    if(!ajAlignValid(val))
7678 	    {					/* test acdc-alignbadformat */
7679 		ajDie("Alignment option -%S: Validation failed",
7680 		      thys->Name);
7681 	    }
7682 
7683 	    ajStrAssignS(&acdOutFullFName, acdReply);
7684 	    ajFilenameReplacePathS(&acdOutFullFName, dir);
7685 	    ok = ajAlignOpen(val, acdOutFullFName);
7686 
7687 	    if(!ok)
7688 	    {
7689 		acdBadVal(thys, required,
7690 			  "Unable to open alignment file '%S'",
7691 			  acdOutFullFName);
7692 		ajAlignDel(&val);
7693 	    }
7694 	}
7695 	else
7696 	    if(!nullok)
7697 	    {
7698 		acdBadVal(thys, required,
7699 			  "Alignment file is required");
7700 		ok = ajFalse;
7701 	    }
7702     }
7703 
7704     if(!ok)
7705 	acdBadRetry(thys);
7706 
7707     thys->Value = val;
7708     ajStrAssignS(&thys->ValStr, acdOutFullFName);
7709 
7710     ajStrDel(&fmt);
7711     ajStrDel(&dir);
7712 
7713     return;
7714 }
7715 
7716 
7717 
7718 
7719 /* @func ajAcdGetArray ********************************************************
7720 **
7721 ** Returns an item of type array as defined in a named ACD item. Called by the
7722 ** application after all ACD values have been set, and simply returns
7723 ** what the ACD item already has.
7724 **
7725 ** @param [r] token [const char*] Text token name
7726 ** @return [AjPFloat] Floating point array object
7727 ** @cre failure to find an item with the right name and type aborts.
7728 **
7729 ** @release 1.0.0
7730 ** @@
7731 ******************************************************************************/
7732 
ajAcdGetArray(const char * token)7733 AjPFloat ajAcdGetArray(const char *token)
7734 {
7735     return acdGetValueRef(token, "array");
7736 }
7737 
7738 
7739 
7740 
7741 /* @funcstatic acdSetArray ****************************************************
7742 **
7743 ** Using the definition in the ACD file, and any values for the
7744 ** item or its associated qualifiers provided on the command line,
7745 ** prompts the user if necessary (and possible) and
7746 ** sets the actual value for an ACD floating point array item.
7747 **
7748 ** Understands all attributes and associated qualifiers for this item type.
7749 **
7750 ** The default value (if no other available) is "0.0" with a size of 1.
7751 **
7752 ** Min and max limits, if set, are applied without comment.
7753 ** Precision is provided for logging purposes but otherwise not (yet) used.
7754 **
7755 ** @param [u] thys [AcdPAcd] ACD item.
7756 ** @return [void]
7757 ** @see ajStrToFloat
7758 **
7759 ** @release 1.0.0
7760 ** @@
7761 ******************************************************************************/
7762 
acdSetArray(AcdPAcd thys)7763 static void acdSetArray(AcdPAcd thys)
7764 {
7765     AjPFloat val;
7766 
7767     AjBool required = ajFalse;
7768     AjBool ok       = ajFalse;
7769 
7770     ajint itry;
7771     AjBool warnrange;
7772     AjBool failrange;
7773     AjBool sumtest;
7774     AjBool truemin;
7775 
7776     float vfmin;
7777     float vfmax;
7778     ajint precision;
7779     ajuint size;
7780     float sum;
7781     float tolerance;
7782     float fdef;
7783     float ftol;
7784     float ftot;
7785     AjPStr deflist = NULL;
7786     ajuint i;
7787     float* array;
7788     AjPStr failmsg = NULL;
7789 
7790     acdRangeTestCalc(thys);
7791 
7792     acdAttrToFloat(thys, "minimum", -FLT_MAX, &vfmin);
7793     acdLog("minimum: %e\n", vfmin);
7794 
7795     acdAttrToFloat(thys, "maximum", FLT_MAX, &vfmax);
7796     acdLog("maximum: %e\n", vfmax);
7797 
7798     acdAttrToFloat(thys, "sum", (float)1.0, &sum);
7799     acdLog("sum: %e\n", sum);
7800 
7801     acdAttrToFloat(thys, "tolerance", (float)0.01, &tolerance);
7802     acdLog("tolerance: %e\n", tolerance);
7803 
7804     acdAttrToInt(thys, "precision", 3, &precision);
7805     acdLog("precision: %d\n", precision);
7806 
7807     acdAttrToBool(thys, "failrange", ajTrue, &failrange);
7808     acdLog("failrange: %B\n", failrange);
7809 
7810     if(failrange && (vfmin > vfmax))
7811     {
7812         acdAttrResolve(thys, "rangemessage", &failmsg);
7813         if(ajStrGetLen(failmsg))
7814             acdErrorAcd(thys, "Invalid range: %S", failmsg);
7815         else
7816             acdErrorAcd(thys,
7817                         "Invalid range: "
7818                         "minimum value %.3f more than maximum %.3f",
7819                         vfmin, vfmax);
7820     }
7821 
7822     acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange);
7823     acdLog("warnrange: %B\n", warnrange);
7824     acdAttrToBool(thys, "sumtest", ajTrue, &sumtest);
7825     acdLog("sumtest: %B\n", sumtest);
7826     acdAttrToBool(thys, "trueminimum", ajFalse, &truemin);
7827     acdLog("trueminimum: %B\n", truemin);
7828 
7829     acdAttrToUint(thys, "size", 1, &size);
7830     acdLog("size: %d\n", size);
7831     if(size < 1)
7832 	acdErrorAcd(thys, "Array attribute size: %d less than 1", size);
7833 
7834     fdef = sum / ((float) size);
7835 
7836     for(i=0; i < size; i++)
7837     {
7838 	if(i)
7839 	    ajStrAppendK(&deflist, ' ');
7840 	ajFmtPrintAppS(&deflist, "%.*f", precision, fdef);
7841     }
7842 
7843     val = ajFloatNewRes(size);	   /* create storage for the result */
7844 
7845     required = acdIsRequired(thys);
7846     acdReplyInitS(thys, deflist, &acdReplyDef);
7847 
7848     for(itry=acdPromptTry; itry && !ok; itry--)
7849     {
7850 	ajStrAssignS(&acdReply, acdReplyDef);
7851 
7852 	if(required)
7853 	    acdUserGet(thys, &acdReply);
7854 
7855 	ok = ajFloatParse(acdReply, &val);
7856 
7857 	if(ok && ajFloatLen(val) != size)
7858 	{
7859 	    ajErr("Bad array value, expected %d values, found %d",
7860 		  size, ajFloatLen(val));
7861 	    ok = ajFalse;
7862 	}
7863 
7864 	if(!ok)
7865 	    acdBadVal(thys, required,
7866 		      "Invalid array value '%S', please try again",
7867 		      acdReply);
7868 
7869 	array = ajFloatFloat(val);
7870 	ftot = 0.0;
7871 
7872 	for(i=0; i< size; i++)
7873 	{
7874 		if(!truemin && array[i] < vfmin)
7875 	    {				/* reset within limits */
7876 		if(warnrange)
7877 		    ajWarn("floating point value [%d] out of range %.*f "
7878 			   "less than (reset to) %.*f",
7879 			   i+1, precision, array[i], precision, vfmin);
7880 		array[i] = vfmin;
7881 	    }
7882 
7883 	    if(array[i] > vfmax)
7884 	    {
7885 		if(warnrange)
7886 		    ajWarn("floating point value [%d] out of range %.*f "
7887 			   "more than (reset to) %.*f",
7888 			   i+1, precision, array[i], precision, vfmax);
7889 		array[i] = vfmax;
7890 	    }
7891 
7892 		if(truemin && array[i] < vfmin)
7893 	    {				/* reset within limits */
7894 		if(warnrange)
7895 		    ajWarn("floating point value [%d] out of range %.*f "
7896 			   "less than (reset to) %.*f",
7897 			   i+1, precision, array[i], precision, vfmin);
7898 		array[i] = vfmin;
7899 	    }
7900 
7901 	    ftot += array[i];
7902 	}
7903 
7904 	ftol = (float) fabs(ftot -sum);
7905 
7906 	if(sumtest && ftol > tolerance)
7907 	{
7908 	    ajWarn("Bad total %.*f, required total is %.*f with "
7909 		   "tolerance %.*f",
7910 		   precision, ftot, precision, sum,precision, tolerance);
7911 	    acdBadVal(thys, required,
7912 		      "Invalid array value '%S', please try again",
7913 		      acdReply);
7914 	    ok = ajFalse;
7915 	}
7916     }
7917 
7918     if(!ok)
7919 	acdBadRetry(thys);
7920 
7921     thys->Value = val;
7922     ajFloatStr(val, precision, &thys->ValStr);
7923 
7924     ajStrDel(&deflist);
7925 
7926     return;
7927 }
7928 
7929 
7930 
7931 
7932 /* @func ajAcdGetAssembly *****************************************************
7933 **
7934 ** Returns an item of type assembly as defined in a named ACD item.
7935 ** Called by the application after all ACD values have been set,
7936 ** and simply returns what the ACD item already has.
7937 **
7938 ** @param [r] token [const char*] Text token name
7939 **
7940 ** @return [AjPAssemload] Assembly object
7941 **
7942 ** @cre failure to find an item with the right name and type aborts.
7943 **
7944 ** @release 6.5.0
7945 ** @@
7946 ******************************************************************************/
7947 
ajAcdGetAssembly(const char * token)7948 AjPAssemload ajAcdGetAssembly(const char *token)
7949 {
7950     AjPAssemload val = acdGetValueRef(token, "assembly");
7951 
7952     return val;
7953 }
7954 
7955 
7956 
7957 
7958 /* @funcstatic acdSetAssembly *************************************************
7959 **
7960 ** Using the definition in the ACD file, and any values for the
7961 ** item or its associated qualifiers provided on the command line,
7962 ** prompts the user if necessary (and possible) and
7963 ** sets the actual value for an ACD assembly input
7964 **
7965 ** Understands all attributes and associated qualifiers for this item type.
7966 **
7967 ** @param [u] thys [AcdPAcd] ACD item.
7968 ** @return [void]
7969 **
7970 ** @release 6.5.0
7971 ** @@
7972 ******************************************************************************/
7973 
acdSetAssembly(AcdPAcd thys)7974 static void acdSetAssembly(AcdPAcd thys)
7975 {
7976     AjPAssemload val;
7977 
7978     AjBool required = ajFalse;
7979     AjBool ok       = ajFalse;
7980     AjBool nullok   = ajFalse;
7981     ajint itry;
7982 
7983     AjPStr infname = NULL;
7984 
7985     val = ajAssemloadNew();        /* set the default value */
7986 
7987     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
7988 
7989     acdInFilename(&infname);
7990     required = acdIsRequired(thys);
7991     acdReplyInitS(thys, infname, &acdReplyDef);
7992     ajStrDel(&infname);
7993 
7994     acdAttrToBool(thys, "entry", ajFalse, &val->Assemin->Input->Text);
7995 
7996     acdGetValueAssoc(thys, "cbegin", &acdTmpStr);
7997     ajStrToInt(acdTmpStr, &val->Assemin->cbegin);
7998 
7999     acdGetValueAssoc(thys, "cend", &acdTmpStr);
8000     ajStrToInt(acdTmpStr, &val->Assemin->cend);
8001 
8002     for(itry=acdPromptTry; itry && !ok; itry--)
8003     {
8004 	ok = ajTrue;	   /* accept the default if nothing changes */
8005 
8006 	ajStrAssignS(&acdReply, acdReplyDef);
8007 
8008 	if(required)
8009 	    acdUserGet(thys, &acdReply);
8010 
8011 	if(!ajStrGetLen(acdReply) && nullok)
8012         {
8013             ajAssemloadDel(&val);
8014 	    break;
8015 	}
8016 
8017 	ajAsseminQryS(val->Assemin, acdReply);
8018 
8019 	acdGetValueAssoc(thys, "iformat", &val->Assemin->Input->Formatstr);
8020 	acdGetValueAssoc(thys, "iquery", &val->Assemin->Input->QryFields);
8021 	acdQualToLong(thys, "ioffset", 0L, &val->Assemin->Input->Fpos,
8022                       &acdTmpStr);
8023 
8024         ok = ajAsseminLoad(val->Assemin, val->Assem);
8025     }
8026 
8027     if(!ok)
8028 	acdBadRetry(thys);
8029 
8030     acdInFileSave(acdReply, ajAssemGetId(val->Assem), ajTrue);
8031 
8032     thys->Value = val;
8033     ajStrAssignS(&thys->ValStr, acdReply);
8034 
8035     return;
8036 }
8037 
8038 
8039 
8040 
8041 /* @func ajAcdGetBoolean ******************************************************
8042 **
8043 ** Returns an item of type Bool as defined in a named ACD item. Called by the
8044 ** application after all ACD values have been set, and simply returns
8045 ** what the ACD item already has.
8046 **
8047 ** @param [r] token [const char*] Text token name
8048 ** @return [AjBool] Boolean value from ACD item
8049 ** @cre failure to find an item with the right name and type aborts.
8050 **
8051 ** @release 6.0.0
8052 ** @@
8053 ******************************************************************************/
8054 
ajAcdGetBoolean(const char * token)8055 AjBool ajAcdGetBoolean(const char *token)
8056 {
8057     AjBool* val;
8058 
8059     val = acdGetValue(token, "boolean");
8060     return *val;
8061 }
8062 
8063 
8064 
8065 
8066 /* @funcstatic acdSetBoolean **************************************************
8067 **
8068 ** Using the definition in the ACD file, and any values for the
8069 ** item or its associated qualifiers provided on the command line,
8070 ** prompts the user if necessary (and possible) and
8071 ** sets the actual value for an ACD boolean item.
8072 **
8073 ** Understands all attributes and associated qualifiers for this item type.
8074 **
8075 ** The default value (if no other available) is "N" for ajFalse.
8076 **
8077 ** @param [u] thys [AcdPAcd] ACD item.
8078 ** @return [void]
8079 ** @see ajStrToBool
8080 **
8081 ** @release 6.0.0
8082 ** @@
8083 ******************************************************************************/
8084 
acdSetBoolean(AcdPAcd thys)8085 static void acdSetBoolean(AcdPAcd thys)
8086 {
8087     AjBool* val;
8088 
8089     AjBool required = ajFalse;
8090     AjBool ok       = ajFalse;
8091 
8092     ajint itry;
8093 
8094     AJNEW0(val);		   /* create storage for the result */
8095 
8096     *val = ajFalse;			/* set the default value */
8097 
8098     required = acdIsRequired(thys);
8099     acdReplyInitC(thys, "N", &acdReplyDef);
8100 
8101     acdLog("acdSetBool -%S def: %S\n", thys->Name, acdReplyDef);
8102 
8103     for(itry=acdPromptTry; itry && !ok; itry--)
8104     {
8105 	ajStrAssignS(&acdReply, acdReplyDef);
8106 
8107 	if(required)
8108 	    acdUserGet(thys, &acdReply);
8109 
8110 	ok = ajStrToBool(acdReply, val);
8111 
8112 	if(!ok)
8113 	    acdBadVal(thys, required, "Invalid Y/N value '%S'", acdReply);
8114     }
8115 
8116     if(!ok)
8117 	acdBadRetry(thys);
8118 
8119     thys->Value = val;
8120     ajFmtPrintS(&thys->ValStr, "%B", *val);
8121 
8122     acdSetQualAppl(thys, *val);		/* check special application
8123 					   booleans */
8124 
8125     acdLog("acdSetBool -%S val: %B\n", thys->Name, *val);
8126 
8127     if(ajStrMatchC(thys->Name, "help"))
8128 	acdHelp();
8129 
8130     return;
8131 }
8132 
8133 
8134 
8135 
8136 /* @func ajAcdGetCodon ********************************************************
8137 **
8138 ** Returns an item of type Codon as defined in a named ACD item.
8139 ** Called by the application after all ACD values have been set,
8140 ** and simply returns what the ACD item already has.
8141 **
8142 ** @param [r] token [const char*] Text token name
8143 ** @return [AjPCod] Codon object.
8144 ** @cre failure to find an item with the right name and type aborts.
8145 **
8146 ** @release 1.0.0
8147 ** @@
8148 ******************************************************************************/
8149 
ajAcdGetCodon(const char * token)8150 AjPCod ajAcdGetCodon(const char *token)
8151 {
8152     return acdGetValueRef(token, "codon");
8153 }
8154 
8155 
8156 
8157 
8158 /* @funcstatic acdSetCodon ****************************************************
8159 **
8160 ** Using the definition in the ACD file, and any values for the
8161 ** item or its associated qualifiers provided on the command line,
8162 ** prompts the user if necessary (and possible) and
8163 ** sets the actual value for an ACD outfile item.
8164 **
8165 ** Understands all attributes and associated qualifiers for this item type.
8166 **
8167 ** @param [u] thys [AcdPAcd] ACD item.
8168 ** @return [void]
8169 **
8170 ** @release 1.0.0
8171 ** @@
8172 ******************************************************************************/
8173 
acdSetCodon(AcdPAcd thys)8174 static void acdSetCodon(AcdPAcd thys)
8175 {
8176     AjPCod val;
8177 
8178     AjPStr name     = NULL;
8179     AjBool required = ajFalse;
8180     AjBool ok       = ajFalse;
8181 
8182     ajint itry;
8183     AjBool nullok;
8184     AjPStr fmt    = NULL;
8185 
8186     val = ajCodNew();			/* set the default value */
8187     acdAttrResolve(thys, "name", &name);
8188 
8189     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
8190     acdLog("nullok: %B\n", nullok);
8191 
8192     if (!acdGetValueAssoc(thys, "format", &fmt))
8193 	ajStrAssignClear(&fmt);
8194 
8195     required = acdIsRequired(thys);
8196     acdReplyInitS(thys, name, &acdReplyDef);
8197     acdPromptCodon(thys);
8198 
8199     for(itry=acdPromptTry; itry && !ok; itry--)
8200     {
8201 	ok = ajTrue;	   /* accept the default if nothing changes */
8202 
8203 	ajStrAssignS(&acdReply, acdReplyDef);
8204 
8205 	if(required)
8206 	    acdUserGet(thys, &acdReply);
8207 
8208 	if(ajStrGetLen(acdReply))
8209 	{
8210 	    if(!ajCodRead(val, acdReply, fmt))
8211 	    {
8212 		acdBadVal(thys, required,
8213 			  "Unable to read codon usage '%S'", acdReply);
8214 		ok = ajFalse;
8215 	    }
8216 	}
8217 	else
8218 	{
8219 	    if(nullok)
8220 	    {
8221 		ajCodDel(&val);
8222 	    }
8223 	    else
8224 	    {
8225 		acdBadVal(thys, required, "Codon file is required");
8226 		ok = ajFalse;
8227 	    }
8228 	}
8229     }
8230 
8231     if(!ok)
8232 	acdBadRetry(thys);
8233 
8234     acdInFileSave(acdReply, NULL, ajFalse);
8235 
8236     thys->Value = val;
8237     ajStrAssignS(&thys->ValStr, acdReply);
8238 
8239     ajStrDel(&name);
8240     ajStrDel(&fmt);
8241 
8242     return;
8243 }
8244 
8245 
8246 
8247 
8248 /* @func ajAcdGetCpdb *********************************************************
8249 **
8250 ** Returns an item of type Cpdb as defined in a named ACD item.
8251 ** Called by the application after all ACD values have been set,
8252 ** and simply returns what the ACD item already has.
8253 **
8254 ** @param [r] token [const char*] Text token name
8255 ** @return [AjPFile] Cpdb input file.
8256 ** @cre failure to find an item with the right name and type aborts.
8257 **
8258 ** @release 1.8.0
8259 ** @@
8260 ******************************************************************************/
8261 
ajAcdGetCpdb(const char * token)8262 AjPFile ajAcdGetCpdb(const char *token)
8263 {
8264     return acdGetValueRef(token, "cpdb");
8265 }
8266 
8267 
8268 
8269 
8270 /* @funcstatic acdSetCpdb *****************************************************
8271 **
8272 ** Using the definition in the ACD file, and any values for the
8273 ** item or its associated qualifiers provided on the command line,
8274 ** prompts the user if necessary (and possible) and
8275 ** sets the actual value for an ACD clean pdb file item.
8276 **
8277 ** Understands all attributes and associated qualifiers for this item type.
8278 **
8279 ** @param [u] thys [AcdPAcd] ACD item.
8280 ** @return [void]
8281 **
8282 ** @release 1.8.0
8283 ** @@
8284 ******************************************************************************/
8285 
acdSetCpdb(AcdPAcd thys)8286 static void acdSetCpdb(AcdPAcd thys)
8287 {
8288     AjPFile val;
8289 
8290     AjPStr name     = NULL;
8291     AjBool required = ajFalse;
8292     AjBool ok       = ajFalse;
8293 
8294     ajint itry;
8295     AjBool nullok;
8296     AjPStr fmt    = NULL;
8297 
8298     val = NULL;				/* set the default value */
8299 
8300     acdAttrResolve(thys, "name", &name);
8301 
8302     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
8303     acdLog("nullok: %B\n", nullok);
8304 
8305     if (!acdGetValueAssoc(thys, "format", &fmt))
8306 	ajStrAssignClear(&fmt);
8307 
8308     required = acdIsRequired(thys);
8309     acdReplyInitS(thys, name, &acdReplyDef);
8310     acdPromptCpdb(thys);
8311 
8312     for(itry=acdPromptTry; itry && !ok; itry--)
8313     {
8314 	ok = ajTrue;	   /* accept the default if nothing changes */
8315 
8316 	ajStrAssignS(&acdReply, acdReplyDef);
8317 
8318 	if(required)
8319 	    acdUserGet(thys, &acdReply);
8320 
8321 	if(ajStrGetLen(acdReply))
8322 	{
8323 	    val = ajFileNewInNameS(acdReply);
8324 
8325 	    if(!val)
8326 	    {
8327 		acdBadVal(thys, required,
8328 			  "Unable to read cleaned PDB data '%S'", acdReply);
8329 		ok = ajFalse;
8330 	    }
8331 	}
8332 	else
8333 	    if(!nullok)
8334 	    {
8335 		acdBadVal(thys, required, "Cleaned PDB data file is required");
8336 		ok = ajFalse;
8337 	    }
8338     }
8339 
8340     if(!ok)
8341 	acdBadRetry(thys);
8342 
8343     thys->Value = val;
8344     ajStrAssignS(&thys->ValStr, acdReply);
8345 
8346     ajStrDel(&name);
8347     ajStrDel(&fmt);
8348 
8349     return;
8350 }
8351 
8352 
8353 
8354 
8355 /* @func ajAcdGetDatafile *****************************************************
8356 **
8357 ** Returns an item of type Datafile as defined in a named ACD item.
8358 ** Called by the application after all ACD values have been set,
8359 ** and simply returns what the ACD item already has.
8360 **
8361 ** @param [r] token [const char*] Text token name
8362 ** @return [AjPFile] File object. The file was already opened by
8363 **         ajDatafileNewInNameS so this just returns the pointer.
8364 ** @cre failure to find an item with the right name and type aborts.
8365 **
8366 ** @release 1.0.0
8367 ** @@
8368 ******************************************************************************/
8369 
ajAcdGetDatafile(const char * token)8370 AjPFile ajAcdGetDatafile(const char *token)
8371 {
8372     return acdGetValueRef(token, "datafile");
8373 }
8374 
8375 
8376 
8377 
8378 /* @funcstatic acdSetDatafile *************************************************
8379 **
8380 ** Using the definition in the ACD file, and any values for the
8381 ** item or its associated qualifiers provided on the command line,
8382 ** prompts the user if necessary (and possible) and
8383 ** sets the actual value for an ACD datafile item.
8384 **
8385 ** Understands all attributes and associated qualifiers for this item type.
8386 **
8387 ** The default value is "programname.dat"
8388 **
8389 ** @param [u] thys [AcdPAcd] ACD item.
8390 ** @return [void]
8391 ** @see ajFileNewOut
8392 **
8393 ** @release 1.0.0
8394 ** @@
8395 ******************************************************************************/
8396 
acdSetDatafile(AcdPAcd thys)8397 static void acdSetDatafile(AcdPAcd thys)
8398 {
8399     AjPFile val;
8400 
8401     AjBool required = ajFalse;
8402     AjBool ok       = ajFalse;
8403 
8404     ajint itry;
8405     AjBool nullok;
8406     AjPStr name = NULL;
8407     AjPStr ext  = NULL;
8408     AjPStr dir  = NULL;
8409 
8410     AjPStr datafname = NULL;
8411 
8412     val = NULL;				/* set the default value */
8413 
8414     acdAttrResolve(thys, "name", &name);
8415     acdAttrResolve(thys, "extension", &ext);
8416     acdAttrResolve(thys, "directory", &dir);
8417 
8418     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
8419     acdLog("nullok: %B\n", nullok);
8420 
8421     acdDataFilename(&datafname, name, ext, nullok);
8422     required = acdIsRequired(thys);
8423     acdReplyInitS(thys, datafname, &acdReplyDef);
8424 /*    acdPromptInfile(thys);*/
8425     ajStrDel(&datafname);
8426     ajStrDel(&name);
8427     ajStrDel(&ext);
8428 
8429     for(itry=acdPromptTry; itry && !ok; itry--)
8430     {
8431 	ok = ajTrue;	   /* accept the default if nothing changes */
8432 
8433 	ajStrAssignS(&acdReply, acdReplyDef);
8434 
8435 	if(required)
8436 	    acdUserGet(thys, &acdReply);
8437 
8438 	if(ajStrGetLen(acdReply))
8439 	{
8440 	    val = ajDatafileNewInNamePathS(acdReply, dir);
8441 
8442 	    if(!val)
8443 	    {
8444 		acdBadVal(thys, required,
8445 			  "Unable to open data file '%S' for input",
8446 			  acdReply);
8447 		ok = ajFalse;
8448 	    }
8449 	}
8450 	else
8451 	    if(!nullok)
8452 	    {
8453 		acdBadVal(thys, required, "Input file is required");
8454 		ok = ajFalse;
8455 	    }
8456     }
8457 
8458     if(!ok)
8459 	acdBadRetry(thys);
8460 
8461     thys->Value = val;
8462     ajStrAssignS(&thys->ValStr, acdReply);
8463 
8464     ajStrDel(&dir);
8465 
8466     return;
8467 }
8468 
8469 
8470 
8471 
8472 /* @func ajAcdGetDirectory ****************************************************
8473 **
8474 ** Returns an item of type AjPDir which has been validated as a
8475 ** directory.
8476 **
8477 ** Optionally can be forced to have a fully qualified path when returned.
8478 **
8479 ** @param [r] token [const char*] Text token name
8480 ** @return [AjPDir] Directory object
8481 ** @cre failure to find an item with the right name and type aborts.
8482 **
8483 ** @release 1.0.0
8484 ** @@
8485 ******************************************************************************/
8486 
ajAcdGetDirectory(const char * token)8487 AjPDir ajAcdGetDirectory(const char *token)
8488 {
8489     return acdGetValueRef(token, "directory");
8490 }
8491 
8492 
8493 
8494 
8495 /* @func ajAcdGetDirectoryName ************************************************
8496 **
8497 ** Returns an item of type AjPStr which has been validated as a
8498 ** directory name
8499 **
8500 ** Optionally can be forced to have a fully qualified path when returned.
8501 **
8502 ** @param [r] token [const char*] Text token name
8503 ** @return [AjPStr] Directory path
8504 ** @cre failure to find an item with the right name and type aborts.
8505 **
8506 ** @release 2.9.0
8507 ** @@
8508 ******************************************************************************/
8509 
ajAcdGetDirectoryName(const char * token)8510 AjPStr ajAcdGetDirectoryName(const char *token)
8511 {
8512     AjPStr ret = NULL;
8513     AjPDir dir;
8514 
8515     dir = acdGetValue(token, "directory");
8516     ret = ajStrNewS(ajDirGetPath(dir));
8517     return ret;
8518 }
8519 
8520 
8521 
8522 
8523 /* @funcstatic acdSetDirectory ************************************************
8524 **
8525 ** Using the definition in the ACD file, and any values for the
8526 ** item or its associated qualifiers provided on the command line,
8527 ** prompts the user if necessary (and possible) and
8528 ** sets the actual value for an ACD directory item.
8529 **
8530 ** Understands all attributes and associated qualifiers for this item type.
8531 **
8532 ** The default value is "." the current directory.
8533 **
8534 ** @param [u] thys [AcdPAcd] ACD item.
8535 ** @return [void]
8536 **
8537 ** @release 1.0.0
8538 ** @@
8539 ******************************************************************************/
8540 
acdSetDirectory(AcdPAcd thys)8541 static void acdSetDirectory(AcdPAcd thys)
8542 {
8543     AjPDir val;
8544 
8545     AjBool required = ajFalse;
8546     AjBool ok       = ajFalse;
8547 
8548     ajint itry;
8549 
8550     AjBool nullok = ajFalse;
8551     AjBool nulldefault = ajFalse;
8552     AjBool dopath = ajFalse;
8553     AjPStr ext = NULL;
8554 
8555     val = NULL;				/* set the default value */
8556 
8557     acdAttrToBool(thys, "fullpath", ajFalse, &dopath);
8558     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
8559     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
8560     acdGetValueAssoc(thys, "extension", &ext);
8561 
8562     required = acdIsRequired(thys);
8563     if(nullok && nulldefault)
8564     {
8565 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
8566 	    acdReplyInitC(thys, ".", &acdReplyDef);
8567 	else				/* leave empty */
8568 	    acdReplyInitC(thys, "", &acdReplyDef);
8569     }
8570     else
8571         acdReplyInitC(thys, ".", &acdReplyDef);
8572 
8573     acdPromptDirectory(thys);
8574 
8575     for(itry=acdPromptTry; itry && !ok; itry--)
8576     {
8577 	ok = ajTrue;	   /* accept the default if nothing changes */
8578 
8579 	ajStrAssignS(&acdReply, acdReplyDef);
8580 
8581 	if(required)
8582 	    acdUserGet(thys, &acdReply);
8583 
8584 	if(ajStrGetLen(acdReply))
8585 	{
8586 	    if(dopath)
8587 		ok = ajDirnameFillPath(&acdReply);
8588 	    else
8589 		ok = ajDirnameFixExists(&acdReply);
8590 
8591 	    if (ok)
8592 	    {
8593 		val = ajDirNewPathExt(acdReply, ext);
8594 		if (!val)
8595 		    ok = ajFalse;
8596 	    }
8597 	    if(!ok)
8598 		acdBadVal(thys, required,
8599 			  "Unable to open directory '%S'",
8600 			  acdReply);
8601 	}
8602 	else
8603 	    if(!nullok)
8604 	    {
8605 		acdBadVal(thys, required,
8606 			  "Directory path is required");
8607 		ok = ajFalse;
8608 	    }
8609     }
8610 
8611     if(!ok)
8612 	acdBadRetry(thys);
8613 
8614     thys->Value = val;
8615     ajStrAssignS(&thys->ValStr, acdReply);
8616 
8617     ajStrDel(&ext);
8618 
8619     return;
8620 }
8621 
8622 
8623 
8624 
8625 /* @func ajAcdGetDirlist ******************************************************
8626 **
8627 ** Returns a list of files in a given directory.
8628 ** Called by the application after all ACD values have been set,
8629 ** and simply returns what the ACD item already has.
8630 **
8631 ** @param [r] token [const char*] Text token name
8632 ** @return [AjPList] List of files.
8633 ** @cre failure to find an item with the right name and type aborts.
8634 **
8635 ** @release 1.9.0
8636 ** @@
8637 ******************************************************************************/
8638 
ajAcdGetDirlist(const char * token)8639 AjPList ajAcdGetDirlist(const char *token)
8640 {
8641     return acdGetValueRef(token, "dirlist");
8642 }
8643 
8644 
8645 
8646 
8647 /* @funcstatic acdSetDirlist **************************************************
8648 **
8649 ** Using the definition in the ACD file, and any values for the
8650 ** item or its associated qualifiers provided on the command line,
8651 ** prompts the user if necessary (and possible) and
8652 ** sets the actual value for an ACD directory item.
8653 **
8654 ** Understands all attributes and associated qualifiers for this item type.
8655 **
8656 ** The default value is "." the current directory.
8657 **
8658 ** @param [u] thys [AcdPAcd] ACD item.
8659 ** @return [void]
8660 **
8661 ** @release 1.9.0
8662 ** @@
8663 ******************************************************************************/
8664 
acdSetDirlist(AcdPAcd thys)8665 static void acdSetDirlist(AcdPAcd thys)
8666 {
8667     AjPList val;
8668     AjPStr  t;
8669     AjPStr  v;
8670     AjBool required = ajFalse;
8671     AjBool ok       = ajFalse;
8672 
8673     ajint itry;
8674 
8675     AjBool nullok = ajFalse;
8676     AjBool dopath;
8677     AjPStr ext = NULL;
8678     ajint n;
8679     ajint i;
8680 
8681     val = NULL;
8682 
8683     acdAttrToBool(thys, "fullpath", ajFalse, &dopath);
8684     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
8685     acdGetValueAssoc(thys, "extension", &ext);
8686 
8687     required = acdIsRequired(thys);
8688     acdReplyInitC(thys, ".", &acdReplyDef);
8689     acdPromptDirlist(thys);
8690 
8691     for(itry=acdPromptTry; itry && !ok; itry--)
8692     {
8693 	ok = ajTrue;	   /* accept the default if nothing changes */
8694 
8695 	ajStrAssignS(&acdReply, acdReplyDef);
8696 
8697 	if(required)
8698 	    acdUserGet(thys, &acdReply);
8699 
8700         if(ajStrGetLen(acdReply))
8701 	{
8702 	    if(dopath)
8703 		ok = ajDirnameFillPath(&acdReply);
8704 	    else
8705 		ok = ajDirnameFixExists(&acdReply);
8706 
8707 	    if(!ok)
8708 		acdBadVal(thys, required,
8709 			  "Unable to open directories '%S' for input",
8710 			  acdReply);
8711 	}
8712 	else
8713 	    if(!nullok)
8714 	    {
8715 		acdBadVal(thys, required,
8716 			  "Input file is required");
8717 		ok = ajFalse;
8718 	    }
8719     }
8720 
8721     if(!ok)
8722 	acdBadRetry(thys);
8723 
8724     val = ajListstrNew();		/* set the default value */
8725     t   = ajStrNewC("*");
8726 
8727     if(MAJSTRGETLEN(ext))
8728     {
8729 	if(ajStrGetCharFirst(ext) != '.')
8730 	    ajStrInsertC(&ext, 0, ".");
8731 
8732 	ajStrAppendS(&t, ext);
8733     }
8734 
8735     ajFilelistAddPathWild(val, acdReply, t);
8736 
8737     /* Sort list so that list of files is system-independent */
8738     ajListSort(val, &ajStrVcmp);
8739 
8740 
8741 
8742     n = (ajuint) ajListGetLength(val);
8743 
8744     ajDebug("acdSetDirlist '%S' listlength %d\n",
8745 	    acdReply, n);
8746 
8747     for(i=0;i<n;++i)
8748     {
8749 	ajFmtPrintS(&t,"");
8750 	ajListPop(val,(void **)&v);
8751 	ajStrAppendS(&t,v);
8752 	ajStrAssignS(&v,t);
8753 	ajListPushAppend(val,(void *)v);
8754     }
8755 
8756     thys->Value = val;
8757     ajStrAssignS(&thys->ValStr, acdReply);
8758 
8759     ajStrDel(&t);
8760     ajStrDel(&ext);
8761 
8762     return;
8763 }
8764 
8765 
8766 
8767 
8768 /* @func ajAcdGetDiscretestates ***********************************************
8769 **
8770 ** Returns an item of type Discrete states as defined in a named ACD item.
8771 ** Called by the application after all ACD values have been set,
8772 ** and simply returns what the ACD item already has.
8773 **
8774 ** @param [r] token [const char*] Text token name
8775 ** @return [AjPPhyloState*] Discrete states object.
8776 **         The string was already set by
8777 **         acdSetDiscretestates so this just returns the pointer.
8778 ** @cre failure to find an item with the right name and type aborts.
8779 **
8780 ** @release 2.8.0
8781 ** @@
8782 ******************************************************************************/
8783 
ajAcdGetDiscretestates(const char * token)8784 AjPPhyloState* ajAcdGetDiscretestates(const char *token)
8785 {
8786     return acdGetValueRef(token, "discretestates");
8787 }
8788 
8789 
8790 
8791 
8792 /* @func ajAcdGetDiscretestatesSingle *****************************************
8793 **
8794 ** Returns an from an array item of type Discrete states as defined in a named
8795 ** ACD item, which is an array of objects terminated by a null value.
8796 ** Called by the application after all ACD values have been set,
8797 ** and simply returns what the ACD item already has.
8798 **
8799 ** @param [r] token [const char*] Text token name
8800 ** @return [AjPPhyloState] Discrete states object. The data was already set by
8801 **         acdSetDiscretestates so this just returns the pointer.
8802 ** @cre failure to find an item with the right name and type aborts.
8803 **
8804 ** @release 4.0.0
8805 ** @@
8806 ******************************************************************************/
8807 
ajAcdGetDiscretestatesSingle(const char * token)8808 AjPPhyloState ajAcdGetDiscretestatesSingle(const char *token)
8809 {
8810     AjPPhyloState* val;
8811     ajint i;
8812 
8813     val = acdGetValueSingle(token, "discretestates");
8814     for(i=0; val[i]; i++)
8815 	continue;
8816 
8817     if(i > 1)
8818 	ajWarn("Single list value %s, but can choose %d values",
8819 	       token, i);
8820 
8821     if(i < 1)
8822 	ajWarn("Single list value %s, no value found: returning NULL value",
8823 	       token);
8824 
8825     return val[0];
8826 }
8827 
8828 
8829 
8830 
8831 /* @funcstatic acdSetDiscretestates *******************************************
8832 **
8833 ** Using the definition in the ACD file, and any values for the
8834 ** item or its associated qualifiers provided on the command line,
8835 ** prompts the user if necessary (and possible) and
8836 ** sets the actual value for an ACD weights file item.
8837 **
8838 ** Understands all attributes and associated qualifiers for this item type.
8839 **
8840 ** The default value (if no other is available) is an empty string.
8841 **
8842 ** Attributes for length and maximum property character are applied with error
8843 ** messages if exceeded.
8844 **
8845 ** @param [u] thys [AcdPAcd] ACD item.
8846 ** @return [void]
8847 **
8848 ** @release 2.8.0
8849 ** @@
8850 ******************************************************************************/
8851 
acdSetDiscretestates(AcdPAcd thys)8852 static void acdSetDiscretestates(AcdPAcd thys)
8853 {
8854     AjPPhyloState* val = NULL;
8855 
8856     AjBool required = ajFalse;
8857     AjBool ok       = ajFalse;
8858 
8859     AjPStr infname  = NULL;
8860     ajint itry;
8861 
8862     AjBool nullok = ajFalse;
8863 
8864     ajint size;
8865     ajint len;
8866     AjPStr statechars = NULL;
8867     ajint i;
8868 
8869     val = NULL;
8870 
8871     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
8872     acdAttrToInt(thys, "size", 1, &size);
8873     acdAttrToInt(thys, "length", 1, &len);
8874     acdAttrToStr(thys, "characters", "", &statechars);
8875 
8876     acdInFilename(&infname);
8877 
8878     required = acdIsRequired(thys);
8879     acdReplyInitS(thys, infname, &acdReplyDef);
8880     acdPromptInfile(thys);
8881     ajStrDel(&infname);
8882 
8883     for(itry=acdPromptTry; itry && !ok; itry--)
8884     {
8885 	ok = ajTrue;	   /* accept the default if nothing changes */
8886 
8887 	ajStrAssignS(&acdReply, acdReplyDef);
8888 
8889 	if(required)
8890 	    acdUserGet(thys, &acdReply);
8891 
8892 	if(ajStrGetLen(acdReply))
8893 	{
8894 	    val = ajPhyloStateRead(acdReply, statechars);
8895 
8896 	    if(!val)
8897 	    {
8898 		acdBadVal(thys, required,
8899 			  "Unable to read discrete states from '%S'",
8900 			  acdReply);
8901 		ok = ajFalse;
8902 	    }
8903 	}
8904 	else
8905 	    if(!nullok)
8906 	    {
8907 		acdBadVal(thys, required,
8908 			  "Input discrete states file is required");
8909 		ok = ajFalse;
8910 	    }
8911     }
8912 
8913     if(!ok)
8914 	acdBadRetry(thys);
8915 
8916     acdInFileSave(acdReply, NULL, ajTrue);
8917 
8918     /* properties have special set attributes */
8919 
8920     thys->SAttr = acdAttrListCount(acdCalcDiscrete);
8921     thys->SetAttr = &acdCalcDiscrete[0];
8922     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
8923 
8924     if(val)
8925     {
8926 	for(i=0;val[i];i++)
8927 	    continue;
8928 	ajStrFromInt(&thys->SetStr[0],val[0]->Len); /* string length */
8929 	ajStrFromInt(&thys->SetStr[1],val[0]->Size); /* string count */
8930 	ajStrFromInt(&thys->SetStr[2],i); /* number of sets */
8931  	ajStrAssignS(&thys->ValStr, acdReply);
8932 	ajDebug("acdSetDiscretestates calc len: %d size: %d sets: %d\n",
8933 		val[0]->Len, val[0]->Size, i);
8934     }
8935     else
8936     {
8937 	ajStrFromInt(&thys->SetStr[0],0); /* string length */
8938 	ajStrFromInt(&thys->SetStr[1],0); /* string count */
8939 	ajStrFromInt(&thys->SetStr[2],0); /* number of sets */
8940 	ajStrAssignClear(&thys->ValStr);
8941     }
8942 
8943     ajStrDel(&statechars);
8944 
8945     thys->Value = val;
8946 
8947     return;
8948 }
8949 
8950 
8951 
8952 
8953 /* @func ajAcdGetDistances ****************************************************
8954 **
8955 ** Returns an item of type Distances as defined in a named ACD item.
8956 ** Called by the application after all ACD values have been set,
8957 ** and simply returns what the ACD item already has.
8958 **
8959 ** @param [r] token [const char*] Text token name
8960 ** @return [AjPPhyloDist*] Distances object. The string was already set by
8961 **         acdSetDistances so this just returns the pointer.
8962 ** @cre failure to find an item with the right name and type aborts.
8963 **
8964 ** @release 2.8.0
8965 ** @@
8966 ******************************************************************************/
8967 
ajAcdGetDistances(const char * token)8968 AjPPhyloDist* ajAcdGetDistances(const char *token)
8969 {
8970     return acdGetValueRef(token, "distances");
8971 }
8972 
8973 
8974 
8975 
8976 /* @func ajAcdGetDistancesSingle **********************************************
8977 **
8978 ** Returns an item of type Distances as defined in a named ACD item.
8979 ** Called by the application after all ACD values have been set,
8980 ** and simply returns what the ACD item already has.
8981 **
8982 ** @param [r] token [const char*] Text token name
8983 ** @return [AjPPhyloDist] Distances object. The string was already set by
8984 **         acdSetDistances so this just returns the pointer.
8985 ** @cre failure to find an item with the right name and type aborts.
8986 **
8987 ** @release 5.0.0
8988 ** @@
8989 ******************************************************************************/
8990 
ajAcdGetDistancesSingle(const char * token)8991 AjPPhyloDist ajAcdGetDistancesSingle(const char *token)
8992 {
8993     AjPPhyloDist *val;
8994     ajint i;
8995 
8996     val = acdGetValueSingle(token, "distances");
8997 
8998     for(i=0; val[i]; i++)
8999 	continue;
9000 
9001     if(i > 1)
9002 	ajWarn("Single list value %s, but can choose %d values",
9003 	       token, i);
9004 
9005     if(i < 1)
9006 	ajWarn("Single list value %s, no value found: returning NULL value",
9007 	       token);
9008 
9009     return val[0];
9010 }
9011 
9012 
9013 
9014 
9015 /* @funcstatic acdSetDistances ************************************************
9016 **
9017 ** Using the definition in the ACD file, and any values for the
9018 ** item or its associated qualifiers provided on the command line,
9019 ** prompts the user if necessary (and possible) and
9020 ** sets the actual value for an ACD weights file item.
9021 **
9022 ** Understands all attributes and associated qualifiers for this item type.
9023 **
9024 ** The default value (if no other is available) is an empty string.
9025 **
9026 ** Attributes for length and maximum property character are applied with error
9027 ** messages if exceeded.
9028 **
9029 ** @param [u] thys [AcdPAcd] ACD item.
9030 ** @return [void]
9031 **
9032 ** @release 2.8.0
9033 ** @@
9034 ******************************************************************************/
9035 
acdSetDistances(AcdPAcd thys)9036 static void acdSetDistances(AcdPAcd thys)
9037 {
9038     AjPPhyloDist* val = NULL;
9039 
9040     AjBool required = ajFalse;
9041     AjBool ok       = ajFalse;
9042 
9043     AjPStr infname  = NULL;
9044     ajint itry;
9045 
9046     AjBool nullok = ajFalse;
9047     ajint size;
9048     AjBool missing;
9049     ajint i;
9050 
9051     val = NULL;
9052 
9053     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
9054     acdAttrToInt(thys, "size", 0, &size);
9055     acdAttrToBool(thys, "missval", ajFalse, &missing);
9056 
9057     acdInFilename(&infname);
9058     required = acdIsRequired(thys);
9059     acdReplyInitS(thys, infname, &acdReplyDef);
9060     acdPromptInfile(thys);
9061     ajStrDel(&infname);
9062 
9063     for(itry=acdPromptTry; itry && !ok; itry--)
9064     {
9065 	ok = ajTrue;	   /* accept the default if nothing changes */
9066 
9067 	ajStrAssignS(&acdReply, acdReplyDef);
9068 
9069 	if(required)
9070 	    acdUserGet(thys, &acdReply);
9071 
9072 	if(ajStrGetLen(acdReply))
9073 	{
9074 	    val = ajPhyloDistRead(acdReply, size, missing);
9075 
9076 	    if(!val)
9077 	    {
9078 		acdBadVal(thys, required,
9079 			  "Unable to read distances file '%S'",
9080 			  acdReply);
9081 		ok = ajFalse;
9082 	    }
9083 	}
9084 	else
9085 	    if(!nullok)
9086 	    {
9087 		acdBadVal(thys, required,
9088 			  "Distances file is required");
9089 		ok = ajFalse;
9090 	    }
9091     }
9092 
9093     if(!ok)
9094 	acdBadRetry(thys);
9095 
9096     acdInFileSave(acdReply, NULL, ajTrue);
9097 
9098     /* properties have special set attributes */
9099 
9100     thys->SAttr = acdAttrListCount(acdCalcDistances);
9101     thys->SetAttr = &acdCalcDistances[0];
9102     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
9103 
9104     if(val)
9105     {
9106 	for(i=0;val[i];i++)
9107 	    continue;
9108 	ajStrFromInt(&thys->SetStr[0],i); /* matrix count */
9109 	ajStrFromInt(&thys->SetStr[1],val[0]->Size); /* string count */
9110 	ajStrFromBool(&thys->SetStr[2],val[0]->HasReplicates);
9111 	ajStrFromBool(&thys->SetStr[3],val[0]->HasMissing);
9112  	ajStrAssignS(&thys->ValStr, acdReply);
9113     }
9114     else
9115     {
9116 	ajStrFromInt(&thys->SetStr[0],0); /* matrix count */
9117 	ajStrFromInt(&thys->SetStr[1],0); /* string count */
9118 	ajStrFromBool(&thys->SetStr[2],ajFalse);
9119 	ajStrFromBool(&thys->SetStr[3],ajFalse);
9120 	ajStrAssignClear(&thys->ValStr);
9121     }
9122 
9123     thys->Value = val;
9124 
9125     return;
9126 }
9127 
9128 
9129 
9130 
9131 /* @func ajAcdGetFeatout ******************************************************
9132 **
9133 ** Returns an item of type FeatOut as defined in a named ACD item.
9134 ** Called by the application after all ACD values have been set,
9135 ** and simply returns what the ACD item already has.
9136 **
9137 ** @param [r] token [const char*] Text token name
9138 ** @return [AjPFeattabOut] Feature Table output object. Already opened
9139 **                      by acdSetFeatout so this just returns the object
9140 ** @cre failure to find an item with the right name and type aborts.
9141 **
9142 ** @release 1.0.0
9143 ** @@
9144 ******************************************************************************/
9145 
ajAcdGetFeatout(const char * token)9146 AjPFeattabOut ajAcdGetFeatout(const char *token)
9147 {
9148     return acdGetValueRef(token, "featout");
9149 }
9150 
9151 
9152 
9153 
9154 /* @funcstatic acdSetFeatout **************************************************
9155 **
9156 ** Using the definition in the ACD file, and any values for the
9157 ** item or its associated qualifiers provided on the command line,
9158 ** prompts the user if necessary (and possible) and
9159 ** sets the actual value for an ACD feature table item.
9160 **
9161 ** Understands all attributes and associated qualifiers for this item type.
9162 **
9163 ** The default value (if no other available) is a null string, which
9164 ** is invalid.
9165 **
9166 ** Associated qualifiers "-offormat", "-ofopenfile"
9167 ** are applied to the UFO before opening the output file.
9168 **
9169 ** @param [u] thys [AcdPAcd] ACD item.
9170 ** @return [void]
9171 ** @see ajFeatTabOutOpen
9172 **
9173 ** @release 1.0.0
9174 ** @@
9175 ******************************************************************************/
9176 
acdSetFeatout(AcdPAcd thys)9177 static void acdSetFeatout(AcdPAcd thys)
9178 {
9179     AjPFeattabOut val = NULL;
9180 
9181     AjBool required = ajFalse;
9182     AjBool ok       = ajFalse;
9183 
9184     ajint itry;
9185     AjBool nullok;
9186     AjBool nulldefault;
9187 
9188     AjPStr name     = NULL;
9189     AjPStr ext      = NULL;
9190     AjPStr fmt      = NULL;
9191     AjPStr type     = NULL;
9192 
9193     val = NULL;
9194 
9195     if(!acdGetValueAssoc(thys, "ofname", &name))
9196 	acdAttrResolve(thys, "name", &name);
9197 
9198     if(acdGetValueAssoc(thys, "offormat", &fmt))
9199 	ajStrAssignS(&ext, fmt);
9200     else
9201 	acdAttrResolve(thys, "extension", &ext);
9202 
9203     if(!ajStrGetLen(ext))
9204 	ajFeatOutFormatDefault(&ext);
9205 
9206     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
9207     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
9208 
9209     ajDebug("acdSetFeatout checking type\n");
9210 
9211     if(!acdAttrToStr(thys, "type", "", &type))
9212     {
9213 	ajDebug("no type, try '%S'\n", type);
9214 
9215  	if(!acdInTypeFeat(&type))
9216 	    ajWarn("No output type specified for '%S'", thys->Name);
9217     }
9218 
9219 
9220     required = acdIsRequired(thys);
9221 
9222     if(nullok && nulldefault)
9223     {
9224 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
9225 	    acdOutFilename(&acdReplyDef, name, ext);
9226 	else				/* leave empty */
9227 	    acdReplyInitC(thys, "", &acdReplyDef);
9228     }
9229     else
9230     {
9231 	acdOutFilename(&acdTmpOutFName, name, ext);
9232 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
9233     }
9234 
9235     ajStrDel(&name);
9236     ajStrDel(&ext);
9237 
9238     acdPromptFeatout(thys);
9239 
9240     for(itry=acdPromptTry; itry && !ok; itry--)
9241     {
9242 	ok = ajTrue;	   /* accept the default if nothing changes */
9243 
9244 	ajStrAssignS(&acdReply, acdReplyDef);
9245 
9246 	if(required)
9247 	    acdUserGet(thys, &acdReply);
9248 
9249 	if(ajStrGetLen(acdReply))
9250 	{
9251 	    val = ajFeattabOutNew();
9252 	    ajDebug("Type '%S' try ajFeattabOutSetType\n", type);
9253 	    if(!ajFeattabOutSetType(val, type))
9254 		acdError("Invalid type for feature output");
9255 	    acdGetValueAssoc(thys, "ofopenfile", &val->Filename);
9256 	    acdGetValueAssoc(thys, "ofdirectory", &val->Directory);
9257 	    acdOutDirectory(&val->Directory);
9258 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
9259 
9260 	    ok = ajFeattabOutOpen(val, acdReply);
9261 
9262 	    if(!ok)
9263 	    {
9264 		if(ajStrGetLen(val->Directory))
9265 		    acdBadVal(thys, required,
9266 			      "Unable to open features output '%S%S'",
9267 			      val->Directory, acdReply);
9268 		else
9269 		    acdBadVal(thys, required,
9270 			      "Unable to open features output '%S'",
9271 			      acdReply);
9272 
9273 		ajFeattabOutDel(&val);
9274 	    }
9275 	}
9276 	else
9277 	    if(!nullok)
9278 	    {
9279 		acdBadVal(thys, required,
9280 			  "Output UFO is required");
9281 		ok = ajFalse;
9282 	    }
9283     }
9284 
9285     if(!ok)
9286 	acdBadRetry(thys);
9287 
9288     thys->Value = val;
9289     ajStrAssignS(&thys->ValStr, acdReply);
9290 
9291     ajStrDel(&fmt);
9292     ajStrDel(&type);
9293 
9294     return;
9295 }
9296 
9297 
9298 
9299 
9300 /* @func ajAcdGetFeatures *****************************************************
9301 **
9302 ** Returns an item of type Features as defined in a named ACD item.
9303 ** Called by the application after all ACD values have been set,
9304 ** and simply returns what the ACD item already has.
9305 **
9306 ** @param [r] token [const char*] Text token name
9307 ** @return [AjPFeattable] Feature Table object. The table was already loaded by
9308 **         acdSetFeat so this just returns the pointer.
9309 ** @cre failure to find an item with the right name and type aborts.
9310 **
9311 ** @release 6.0.0
9312 ** @@
9313 ******************************************************************************/
9314 
ajAcdGetFeatures(const char * token)9315 AjPFeattable ajAcdGetFeatures(const char *token)
9316 {
9317     AjPFeattaball val = acdGetValue(token, "features");
9318     if(val->Multi)
9319         ajWarn("ajAcdGetFeatures request single feature table "
9320                "but maxreads > 1");
9321 
9322     val->Returned = ajTrue;
9323 
9324     return val->Feattable;
9325 }
9326 
9327 
9328 
9329 
9330 /* @func ajAcdGetFeaturesall **************************************************
9331 **
9332 ** Returns an input stream of an item of type Features as defined in a
9333 ** named ACD item.
9334 **
9335 ** Called by the application after all ACD values have been set,
9336 ** and simply returns what the ACD item already has.
9337 **
9338 ** @param [r] token [const char*] Text token name
9339 ** @return [AjPFeattaball] Features input stream
9340 ** @cre failure to find an item with the right name and type aborts.
9341 **
9342 ** @release 6.4.0
9343 ** @@
9344 ******************************************************************************/
9345 
ajAcdGetFeaturesall(const char * token)9346 AjPFeattaball ajAcdGetFeaturesall(const char *token)
9347 {
9348     AjPFeattaball val = acdGetValueRef(token, "features");
9349 
9350     if(!val->Multi)
9351         ajWarn("ajAcdGetFeattaball request features input stream "
9352                "but maxreads is 1");
9353 
9354     return val;
9355 }
9356 
9357 
9358 
9359 
9360 /* @funcstatic acdSetFeatures *************************************************
9361 **
9362 ** Using the definition in the ACD file, and any values for the
9363 ** item or its associated qualifiers provided on the command line,
9364 ** prompts the user if necessary (and possible) and
9365 ** sets the actual value for an ACD feature table item.
9366 **
9367 ** Understands all attributes and associated qualifiers for this item type.
9368 **
9369 ** The default value (if no other available) is a null string, which
9370 ** is invalid.
9371 **
9372 ** Associated qualifiers "-fformat", "-fopenfile"
9373 ** are applied to the UFO before reading the feature table.
9374 **
9375 ** Associated qualifiers "-fbegin", "-fend" and "-freverse"
9376 ** are applied as appropriate, with prompting for values,
9377 ** after the feature table has been read.
9378 ** They are applied to the feature table,
9379 ** and the resulting table is what is set in the ACD item.
9380 **
9381 ** @param [u] thys [AcdPAcd] ACD item.
9382 ** @return [void]
9383 **
9384 ** @release 6.0.0
9385 ** @@
9386 ******************************************************************************/
9387 
acdSetFeatures(AcdPAcd thys)9388 static void acdSetFeatures(AcdPAcd thys)
9389 {
9390     AjPFeattaball val   = NULL;
9391 
9392     AjBool required = ajFalse;
9393     AjBool ok       = ajFalse;
9394 
9395     ajint itry;
9396 
9397     AjPStr infname = NULL;
9398     static AjPStr type    = NULL;
9399 
9400     ajint fbegin = 0;
9401     ajint fend   = 0;
9402     AjBool freverse = ajFalse;
9403     AjBool fprompt  = ajFalse;
9404     ajint iattr;
9405 
9406     ajint maxreads;
9407 
9408     val = ajFeattaballNew();		/* set the default value */
9409 
9410     acdQualToBool(thys, "fask", ajFalse, &fprompt, &acdReplyDef);
9411     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
9412 
9413     acdAttrToBool(thys, "entry", ajFalse, &val->Feattabin->Input->Text);
9414 
9415     if(acdAttrToStr(thys, "type", "", &type))
9416     {
9417 	if(!ajFeattabinSetTypeS(val->Feattabin, type))
9418 	    acdError("Invalid type for feature input");
9419 	acdInTypeFeatSave(type);
9420     }
9421     else
9422     {
9423 	acdInTypeFeatSave(NULL);
9424     }
9425 
9426     acdInFilename(&infname);
9427     required = acdIsRequired(thys);
9428     acdReplyInitS(thys, infname, &acdReplyDef);
9429     acdPromptFeatures(thys);
9430     ajStrDel(&infname);
9431 
9432     for(itry=acdPromptTry; itry && !ok; itry--)
9433     {
9434 	ok = ajTrue;	   /* accept the default if nothing changes */
9435 
9436 	ajStrAssignS(&acdReply, acdReplyDef);
9437 
9438 	if(required)
9439 	    acdUserGet(thys, &acdReply);
9440 
9441 	acdGetValueAssoc(thys, "fformat", &val->Feattabin->Formatstr);
9442 	acdGetValueAssoc(thys, "fopenfile", &val->Feattabin->Filename);
9443 	acdGetValueAssoc(thys, "iquery", &val->Feattabin->Input->QryFields);
9444 	acdQualToLong(thys, "ioffset", 0L, &val->Feattabin->Input->Fpos,
9445                       &acdTmpStr);
9446 
9447 	ajFeattabinQryS(val->Feattabin, acdReply);
9448 	ok = ajFeattabinRead(val->Feattabin, val->Feattable);
9449     }
9450 
9451     if(!ok)
9452 	acdBadRetry(thys);
9453 
9454     acdInFileSave(acdReply, ajFeattableGetName(val->Feattable),
9455                   ajTrue); /* save sequence name */
9456 
9457     /* now process the begin, end and reverse options */
9458 
9459     ok = acdQualToInt(thys, "fbegin", 1, &fbegin, &acdReplyDef);
9460     for(itry=acdPromptTry; itry && !ok; itry--)
9461     {
9462 	ajStrAssignS(&acdReply, acdReplyDef);
9463 
9464 	if(fprompt)
9465 	    acdUserGetPrompt(thys, "fbegin", " Begin at position", &acdReply);
9466 
9467 	ok = ajStrToInt(acdReply, &fbegin);
9468 
9469 	if(!ok)
9470 	    acdBadVal(thys, ajTrue,
9471 		      "Invalid integer value '%S'", acdReply);
9472     }
9473 
9474     if(!ok)
9475 	acdBadRetry(thys);
9476 
9477     ok = acdQualToInt(thys, "fend", ajFeattableGetLen(val->Feattable), &fend,
9478                       &acdReplyDef);
9479 
9480     for(itry=acdPromptTry; itry && !ok; itry--)
9481     {
9482 	ajStrAssignS(&acdReply, acdReplyDef);
9483 
9484 	if(fprompt)
9485 	    acdUserGetPrompt(thys, "fend", "   End at position", &acdReply);
9486 
9487 	ok = ajStrToInt(acdReply, &fend);
9488 
9489 	if(!ok)
9490 	    acdBadVal(thys, ajTrue,
9491 		      "Invalid integer value '%S'", acdReply);
9492     }
9493 
9494     if(!ok)
9495 	acdBadRetry(thys);
9496 
9497     ok = acdQualToBool(thys, "freverse", ajFalse, &freverse, &acdReplyDef);
9498 
9499     for(itry=acdPromptTry; itry && !ok; itry--)
9500     {
9501 	ajStrAssignS(&acdReply, acdReplyDef);
9502 
9503 	if(fprompt)
9504 	    acdUserGetPrompt(thys, "freverse", "    Reverse strand", &acdReply);
9505 	ok = ajStrToBool(acdReply, &freverse);
9506 
9507 
9508 	if(!ok)
9509 	    acdBadVal(thys, ajTrue,
9510 		      "Invalid Y/N value '%S'", acdReply);
9511     }
9512 
9513     if(!ok)
9514 	acdBadRetry(thys);
9515 
9516     acdLog("sbegin: %d, send: %d, freverse: %B\n",
9517 	   fbegin, fend, freverse);
9518 
9519     if(freverse)
9520     {
9521         val->Feattabin->Rev = freverse;
9522 	ajFeattableReverse(val->Feattable);
9523     }
9524 
9525     ajFeattabinSetRange(val->Feattabin, fbegin, fend);
9526     ajFeattableSetRange(val->Feattable, fbegin, fend);
9527 
9528     if(maxreads > 1)
9529         val->Multi = ajTrue;
9530 
9531     /* features tables have special set attributes */
9532 
9533     thys->SAttr = acdAttrListCount(acdCalcFeat);
9534     thys->SetAttr = &acdCalcFeat[0];
9535     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
9536 
9537     iattr = 0;
9538     ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetBegin(val->Feattable));
9539     ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetEnd(val->Feattable));
9540     ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetLen(val->Feattable));
9541     ajStrFromBool(&thys->SetStr[iattr++], ajFeattableIsProt(val->Feattable));
9542     ajStrFromBool(&thys->SetStr[iattr++], ajFeattableIsNuc(val->Feattable));
9543     ajStrAssignS(&thys->SetStr[iattr++], ajFeattableGetName(val->Feattable));
9544     ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetSize(val->Feattable));
9545 
9546     thys->Value = val;
9547     ajStrAssignS(&thys->ValStr, acdReply);
9548 
9549     ajStrDel(&type);
9550 
9551     return;
9552 }
9553 
9554 
9555 
9556 
9557 /* @func ajAcdGetFilelist *****************************************************
9558 **
9559 ** Returns a list of files given a comma-separated list.
9560 ** Called by the application after all ACD values have been set,
9561 ** and simply returns what the ACD item already has.
9562 **
9563 ** @param [r] token [const char*] Text token name
9564 ** @return [AjPList] List of files.
9565 ** @cre failure to find an item with the right name and type aborts.
9566 **
9567 ** @release 2.5.0
9568 ** @@
9569 ******************************************************************************/
9570 
ajAcdGetFilelist(const char * token)9571 AjPList ajAcdGetFilelist(const char *token)
9572 {
9573     return acdGetValueRef(token, "filelist");
9574 }
9575 
9576 
9577 
9578 
9579 /* @funcstatic acdSetFilelist *************************************************
9580 **
9581 ** Using the definition in the ACD file, and any values for the
9582 ** item or its associated qualifiers provided on the command line,
9583 ** prompts the user if necessary (and possible) and
9584 ** sets the actual value for an ACD file list item.
9585 **
9586 ** Understands all attributes and associated qualifiers for this item type.
9587 **
9588 ** There is no default value
9589 **
9590 ** @param [u] thys [AcdPAcd] ACD item.
9591 ** @return [void]
9592 **
9593 ** @release 2.5.0
9594 ** @@
9595 ******************************************************************************/
9596 
acdSetFilelist(AcdPAcd thys)9597 static void acdSetFilelist(AcdPAcd thys)
9598 {
9599     AjPList val;
9600     AjBool required = ajFalse;
9601     AjBool ok       = ajFalse;
9602 
9603     ajint itry;
9604 
9605     AjBool nullok = ajFalse;
9606 
9607     val = ajListNew();
9608 
9609     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
9610 
9611     required = acdIsRequired(thys);
9612     acdReplyInitC(thys, "", &acdReplyDef);
9613     acdPromptFilelist(thys);
9614 
9615     for(itry=acdPromptTry; itry && !ok; itry--)
9616     {
9617 	ok = ajTrue;	   /* accept the default if nothing changes */
9618 
9619 	ajStrAssignS(&acdReply, acdReplyDef);
9620 
9621 	if(required)
9622 	    acdUserGet(thys, &acdReply);
9623 
9624 	if(!ajStrGetLen(acdReply))
9625 	    if(!nullok)
9626 	    {
9627 		acdBadVal(thys, required,
9628 			  "File list is required");
9629 		ok = ajFalse;
9630 	    }
9631     }
9632 
9633     if(!ok)
9634 	acdBadRetry(thys);
9635 
9636     ajFilelistAddListname(val, acdReply);
9637 
9638     thys->Value = val;
9639     ajStrAssignS(&thys->ValStr, acdReply);
9640 
9641     return;
9642 }
9643 
9644 
9645 
9646 
9647 /* @func ajAcdGetFloat ********************************************************
9648 **
9649 ** Returns an item of type Float as defined in a named ACD item. Called by the
9650 ** application after all ACD values have been set, and simply returns
9651 ** what the ACD item already has.
9652 **
9653 ** @param [r] token [const char*] Text token name
9654 ** @return [float] Floating point value from ACD item
9655 ** @cre failure to find an item with the right name and type aborts.
9656 **
9657 ** @release 1.0.0
9658 ** @@
9659 ******************************************************************************/
9660 
ajAcdGetFloat(const char * token)9661 float ajAcdGetFloat(const char *token)
9662 {
9663     double *val;
9664 
9665     val = acdGetValue(token, "float");
9666 
9667     return (float) *val;
9668 }
9669 
9670 
9671 
9672 
9673 /* @func ajAcdGetFloatDouble***************************************************
9674 **
9675 ** Returns an item of type Float as defined in a named ACD item. Called by the
9676 ** application after all ACD values have been set, and simply returns
9677 ** what the ACD item already has.
9678 **
9679 ** @param [r] token [const char*] Text token name
9680 ** @return [double] Floating point value from ACD item
9681 ** @cre failure to find an item with the right name and type aborts.
9682 **
9683 ** @release 6.1.0
9684 ** @@
9685 ******************************************************************************/
9686 
ajAcdGetFloatDouble(const char * token)9687 double ajAcdGetFloatDouble(const char *token)
9688 {
9689     double *val;
9690 
9691     val = acdGetValue(token, "float");
9692 
9693     return *val;
9694 }
9695 
9696 
9697 
9698 
9699 /* @funcstatic acdSetFloat ****************************************************
9700 **
9701 ** Using the definition in the ACD file, and any values for the
9702 ** item or its associated qualifiers provided on the command line,
9703 ** prompts the user if necessary (and possible) and
9704 ** sets the actual value for an ACD floating point item.
9705 **
9706 ** Understands all attributes and associated qualifiers for this item type.
9707 **
9708 ** The default value (if no other available) is "0.0".
9709 **
9710 ** Min and max limits, if set, are applied without comment.
9711 ** Precision is provided for logging purposes but otherwise not (yet) used.
9712 **
9713 ** @param [u] thys [AcdPAcd] ACD item.
9714 ** @return [void]
9715 ** @see ajStrToFloat
9716 **
9717 ** @release 1.0.0
9718 ** @@
9719 ******************************************************************************/
9720 
acdSetFloat(AcdPAcd thys)9721 static void acdSetFloat(AcdPAcd thys)
9722 {
9723     double* val;
9724     float  fval;
9725 
9726     AjBool required = ajFalse;
9727     AjBool ok       = ajFalse;
9728 
9729     ajint itry;
9730     AjBool warnrange;
9731     AjBool failrange;
9732     AjBool isdouble;
9733     AjBool truemin;
9734 
9735     double vfmin;
9736     double vfmax;
9737     ajint precision;
9738     AjPStr failmsg = NULL;
9739 
9740     acdRangeTestCalc(thys);
9741 
9742     acdAttrToDouble(thys, "minimum", -FLT_MAX, &vfmin);
9743     acdLog("minimum: %e\n", vfmin);
9744 
9745     acdAttrToDouble(thys, "maximum", FLT_MAX, &vfmax);
9746     acdLog("maximum: %e\n", vfmax);
9747 
9748     acdAttrToInt(thys, "precision", 3, &precision);
9749     acdLog("precision: %d\n", precision);
9750 
9751     acdAttrToBool(thys, "failrange", ajTrue, &failrange);
9752     acdLog("failrange: %B\n", failrange);
9753 
9754     acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange);
9755     acdLog("warnrange: %B\n", warnrange);
9756 
9757     acdAttrToBool(thys, "large", AJFALSE, &isdouble);
9758     acdLog("large: %B\n", isdouble);
9759 
9760     acdAttrToBool(thys, "trueminimum", AJFALSE, &truemin);
9761     acdLog("trueminimum: %B\n", truemin);
9762 
9763     if(failrange && (vfmin > vfmax))
9764     {
9765         acdAttrResolve(thys, "rangemessage", &failmsg);
9766         if(ajStrGetLen(failmsg))
9767             acdErrorAcd(thys, "Invalid range: %S", failmsg);
9768         else
9769             acdErrorAcd(thys,
9770                         "Invalid range: "
9771                         "minimum value %.3f more than maximum %.3f",
9772                         vfmin, vfmax);
9773     }
9774 
9775     AJNEW0(val);		   /* create storage for the result */
9776 
9777     *val = 0.0;				/* set the default value */
9778 
9779     required = acdIsRequired(thys);
9780     acdReplyInitC(thys, "0.0", &acdReplyDef);
9781 
9782     for(itry=acdPromptTry; itry && !ok; itry--)
9783     {
9784 	ajStrAssignS(&acdReply, acdReplyDef);
9785 
9786 	if(required)
9787 	    acdUserGet(thys, &acdReply);
9788 
9789         if(isdouble)
9790             ok = ajStrToDouble(acdReply, val);
9791         else
9792         {
9793             ok = ajStrToFloat(acdReply, &fval);
9794             *val = fval;
9795         }
9796 
9797 	if(!ok)
9798 	    acdBadVal(thys, required,
9799 		      "Invalid decimal value '%S', please try again",
9800 		      acdReply);
9801     }
9802 
9803     if(!ok)
9804 	acdBadRetry(thys);
9805 
9806     if(isdouble && vfmin == FLT_MIN)
9807         vfmin = DBL_MIN;
9808 
9809     if(isdouble && vfmax == FLT_MAX)
9810         vfmax = DBL_MAX;
9811 
9812     if(!truemin && *val < vfmin)
9813     {					/* reset within limits */
9814 	if(warnrange)
9815 	    ajWarn("floating point value out of range %.*f "
9816 		   "less than (reset to) %.*f",
9817 		   precision, *val, precision, vfmin);
9818 	*val = vfmin;
9819     }
9820 
9821     if(*val > vfmax)
9822     {
9823 	if(warnrange)
9824 	    ajWarn("floating point value out of range %.*f "
9825 		   "more than (reset to) %.*f",
9826 		   precision, *val, precision, vfmax);
9827 	*val = vfmax;
9828     }
9829 
9830     if(truemin && *val < vfmin)
9831     {					/* reset within limits */
9832 	if(warnrange)
9833 	    ajWarn("floating point value out of range %.*f "
9834 		   "less than (reset to) %.*f",
9835 		   precision, *val, precision, vfmin);
9836 	*val = vfmin;
9837     }
9838 
9839    thys->Value = val;
9840     ajStrFromFloat(&thys->ValStr, (float) *val, precision);
9841 
9842     return;
9843 }
9844 
9845 
9846 
9847 
9848 /* @func ajAcdGetFrequencies **************************************************
9849 **
9850 ** Returns an item of type Frequencies as defined in a named ACD item.
9851 ** Called by the application after all ACD values have been set,
9852 ** and simply returns what the ACD item already has.
9853 **
9854 ** @param [r] token [const char*] Text token name
9855 ** @return [AjPPhyloFreq] Frequencies object. The string was already set by
9856 **         acdSetFrequencies so this just returns the pointer.
9857 ** @cre failure to find an item with the right name and type aborts.
9858 **
9859 ** @release 2.8.0
9860 ** @@
9861 ******************************************************************************/
9862 
ajAcdGetFrequencies(const char * token)9863 AjPPhyloFreq ajAcdGetFrequencies(const char *token)
9864 {
9865     return acdGetValueRef(token, "frequencies");
9866 }
9867 
9868 
9869 
9870 
9871 /* @funcstatic acdSetFrequencies **********************************************
9872 **
9873 ** Using the definition in the ACD file, and any values for the
9874 ** item or its associated qualifiers provided on the command line,
9875 ** prompts the user if necessary (and possible) and
9876 ** sets the actual value for an ACD weights file item.
9877 **
9878 ** Understands all attributes and associated qualifiers for this item type.
9879 **
9880 ** The default value (if no other is available) is an empty string.
9881 **
9882 ** Attributes for length and maximum property character are applied with error
9883 ** messages if exceeded.
9884 **
9885 ** @param [u] thys [AcdPAcd] ACD item.
9886 ** @return [void]
9887 **
9888 ** @release 2.8.0
9889 ** @@
9890 ******************************************************************************/
9891 
acdSetFrequencies(AcdPAcd thys)9892 static void acdSetFrequencies(AcdPAcd thys)
9893 {
9894     AjPPhyloFreq val;
9895 
9896     AjBool required = ajFalse;
9897     AjBool ok       = ajFalse;
9898 
9899     AjPStr infname  = NULL;
9900     ajint itry;
9901 
9902     AjBool nullok   = ajFalse;
9903     AjBool contchar = ajFalse;
9904     AjBool genedata = ajFalse;
9905     AjBool within   = ajFalse;
9906     ajint size;
9907 
9908     val = NULL;
9909 
9910     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
9911     acdAttrToInt(thys, "size", 1, &size);
9912     acdAttrToBool(thys, "continuous", ajFalse, &contchar);
9913     acdAttrToBool(thys, "genedata", ajFalse, &genedata);
9914     acdAttrToBool(thys, "within", ajFalse, &within);
9915 
9916     acdInFilename(&infname);
9917 
9918     required = acdIsRequired(thys);
9919     acdReplyInitS(thys, infname, &acdReplyDef);
9920     acdPromptInfile(thys);
9921     ajStrDel(&infname);
9922 
9923     for(itry=acdPromptTry; itry && !ok; itry--)
9924     {
9925 	ok = ajTrue;	   /* accept the default if nothing changes */
9926 
9927 	ajStrAssignS(&acdReply, acdReplyDef);
9928 
9929 	if(required)
9930 	    acdUserGet(thys, &acdReply);
9931 
9932 	if(ajStrGetLen(acdReply))
9933 	{
9934 	    val = ajPhyloFreqRead(acdReply, contchar, genedata, within);
9935 
9936 	    if(!val)
9937 	    {
9938 		acdBadVal(thys, required,
9939 			  "Unable to read frequencies file '%S'",
9940 			  acdReply);
9941 		ok = ajFalse;
9942 	    }
9943 	}
9944 	else
9945 	    if(!nullok)
9946 	    {
9947 		acdBadVal(thys, required,
9948 			  "Input frequencies file is required");
9949 		ok = ajFalse;
9950 	    }
9951     }
9952 
9953     if(!ok)
9954 	acdBadRetry(thys);
9955 
9956     acdInFileSave(acdReply, NULL, ajTrue);
9957 
9958     /* properties have special set attributes */
9959 
9960     thys->SAttr = acdAttrListCount(acdCalcFrequencies);
9961     thys->SetAttr = &acdCalcFrequencies[0];
9962     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
9963 
9964     if(val)
9965     {
9966 	ajStrFromInt(&thys->SetStr[0],val->Len); /* string count */
9967 	ajStrFromInt(&thys->SetStr[1],val->Size); /* string count */
9968 	ajStrFromInt(&thys->SetStr[2],val->Loci); /* string count */
9969 	ajStrFromBool(&thys->SetStr[3],!val->ContChar); /* genes */
9970 	ajStrFromBool(&thys->SetStr[4],val->ContChar); /* contin */
9971 	ajStrFromBool(&thys->SetStr[5],val->Within); /* indivs */
9972  	ajStrAssignS(&thys->ValStr, acdReply);
9973     }
9974     else
9975     {
9976 	ajStrFromInt(&thys->SetStr[0],0); /* string count */
9977 	ajStrFromInt(&thys->SetStr[1],0); /* string count */
9978 	ajStrFromInt(&thys->SetStr[2],0); /* string count */
9979 	ajStrFromBool(&thys->SetStr[3],0); /* genes */
9980 	ajStrFromBool(&thys->SetStr[4],0); /* contin */
9981 	ajStrFromBool(&thys->SetStr[5],0); /* indivs */
9982 	ajStrAssignClear(&thys->ValStr);
9983     }
9984 
9985     thys->Value = val;
9986 
9987     return;
9988 }
9989 
9990 
9991 
9992 
9993 /* @func ajAcdGetGraph ********************************************************
9994 **
9995 ** Returns a graph object which hold user graphics options.
9996 **
9997 ** @param [r] token [const char*] Text token name
9998 ** @return [AjPGraph] Graph object.
9999 ** @cre failure to find an item with the right name and type aborts.
10000 **
10001 ** @release 1.0.0
10002 ** @@
10003 ******************************************************************************/
10004 
ajAcdGetGraph(const char * token)10005 AjPGraph ajAcdGetGraph(const char *token)
10006 {
10007     return acdGetValueRef(token, "graph");
10008 }
10009 
10010 
10011 
10012 
10013 /* @funcstatic acdSetGraph ****************************************************
10014 **
10015 ** Using the definition in the ACD file, and any values for the
10016 ** item or its associated qualifiers provided on the command line,
10017 ** prompts the user if necessary (and possible) and
10018 ** sets the actual value for an ACD graph item.
10019 **
10020 ** Understands all attributes and associated qualifiers for this item type.
10021 **
10022 ** @param [u] thys [AcdPAcd] ACD item.
10023 ** @return [void]
10024 **
10025 ** @release 1.0.0
10026 ** @@
10027 ******************************************************************************/
10028 
acdSetGraph(AcdPAcd thys)10029 static void acdSetGraph(AcdPAcd thys)
10030 {
10031     AjPGraph val = NULL;
10032 
10033     AjBool required = ajFalse;
10034     AjBool ok       = ajFalse;
10035 
10036     AjPStr title    = NULL;
10037     AjPStr gdev     = NULL;
10038 
10039     ajint itry;
10040     AjBool nullok;
10041     AjBool nulldefault;
10042     AjBool hasseq   = ajFalse;
10043 
10044     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
10045     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
10046     required = acdIsRequired(thys);
10047     if(nullok && nulldefault)
10048     {
10049 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
10050 	{
10051 	    if(ajNamGetValueC("GRAPHICS",&gdev))
10052 		acdReplyInitS(thys, gdev, &acdReplyDef);
10053 	    else
10054 #ifndef WIN32
10055 #ifndef X_DISPLAY_MISSING /* X11 is available */
10056 		acdReplyInitC(thys, "x11", &acdReplyDef);
10057 #else
10058 #ifdef PLD_png          /* if png/gd/zlib libraries available for png driver */
10059 		acdReplyInitC(thys, "png", &acdReplyDef);
10060 #else
10061 		acdReplyInitC(thys, "ps", &acdReplyDef);
10062 #endif
10063 #endif
10064 #else
10065 	    acdReplyInitC(thys, "win3", &acdReplyDef);
10066 #endif
10067 	}
10068 	else				/* leave empty */
10069 	    acdReplyInitC(thys, "", &acdReplyDef);
10070     }
10071     else
10072     {
10073 	if(ajNamGetValueC("GRAPHICS",&gdev))
10074 	    acdReplyInitS(thys, gdev, &acdReplyDef);
10075 	else
10076 #ifndef WIN32
10077 #ifndef X_DISPLAY_MISSING /* X11 is available */
10078 	    acdReplyInitC(thys, "x11", &acdReplyDef);
10079 #else
10080 #ifdef PLD_png          /* if png/gd/zlib libraries available for png driver */
10081 	    acdReplyInitC(thys, "png", &acdReplyDef);
10082 #else
10083 	    acdReplyInitC(thys, "ps", &acdReplyDef);
10084 #endif
10085 #endif
10086 #else
10087 	    acdReplyInitC(thys, "win3", &acdReplyDef);
10088 #endif
10089     }
10090 
10091     ajStrDel(&gdev);
10092     acdPromptGraph(thys);
10093 
10094     for(itry=acdPromptTry; itry && !ok; itry--)
10095     {
10096 	ok = ajTrue;
10097 
10098 	ajStrAssignS(&acdReply, acdReplyDef);
10099 
10100 	if(required)
10101 	    acdUserGet(thys, &acdReply);
10102 
10103 	if(ajStrGetLen(acdReply))	/* valid no graph type */
10104 	{
10105 
10106 	    if(!val)
10107 	      val = ajGraphNew();
10108 	    ok = ajGraphSetDevicetype(val, acdReply);
10109 
10110 	    if(!ok)
10111 	    {
10112 	        ajGraphicsDumpDevices();
10113 		acdBadVal(thys, required,
10114 			  "Invalid graph value '%S'", acdReply);
10115 	    }
10116 	}
10117 	else
10118 	    if(!nullok)
10119 	    {
10120 		acdBadVal(thys, required,
10121 			  "Graph is required");
10122 		ok = ajFalse;
10123 	    }
10124     }
10125 
10126     if(!ok)
10127 	acdBadRetry(thys);
10128 
10129     thys->Value = val;
10130     ajStrAssignC(&thys->ValStr, "graph definition");
10131 
10132     if(val)
10133     {
10134         acdAttrToBool(thys, "sequence", ajFalse, &hasseq);
10135 
10136 	if(acdGetValueAssoc(thys, "gdesc", &title))
10137 	    ajGraphSetDescS(val,title);
10138 
10139 	if(acdGetValueAssoc(thys, "gtitle", &title))
10140 	    ajGraphSetTitleS(val,title);
10141 
10142 	if(acdGetValueAssoc(thys, "gsubtitle", &title))
10143 	    ajGraphSetSubtitleS(val,title);
10144 
10145 	if(acdGetValueAssoc(thys, "gxtitle", &title))
10146 	    ajGraphSetXlabelS(val,title);
10147         else if(hasseq)
10148             ajGraphSetXlabelS(val, acdInFName);
10149 
10150 	if(acdGetValueAssoc(thys, "gytitle", &title))
10151 	    ajGraphSetYlabelS(val,title);
10152 
10153 	if(acdGetValueAssoc(thys, "goutfile", &title))
10154 	    ajGraphSetOutfileS(val,title);
10155 
10156 	if(acdGetValueAssoc(thys, "gdirectory", &title))
10157 	    ajGraphSetOutdirS(val,title);
10158 	else
10159 	{
10160 	    ajStrAssignClear(&title);
10161 	    if(acdOutDirectory(&title))
10162 	        ajGraphSetOutdirS(val,title);
10163 	}
10164 
10165 	ajStrDel(&title);
10166 	ajGraphTrace(val);
10167     }
10168 
10169     return;
10170 }
10171 
10172 
10173 
10174 
10175 /* @func ajAcdGetGraphxy ******************************************************
10176 **
10177 ** Returns a graph object which hold user graphics options.
10178 **
10179 ** @param [r] token [const char*] Text token name
10180 ** @return [AjPGraph] Graph object.
10181 ** @cre failure to find an item with the right name and type aborts.
10182 **
10183 ** @release 1.0.0
10184 ** @@
10185 ******************************************************************************/
10186 
ajAcdGetGraphxy(const char * token)10187 AjPGraph ajAcdGetGraphxy(const char *token)
10188 {
10189     return acdGetValueRef(token, "xygraph");
10190 }
10191 
10192 
10193 
10194 
10195 /* @funcstatic acdSetGraphxy **************************************************
10196 **
10197 ** Using the definition in the ACD file, and any values for the
10198 ** item or its associated qualifiers provided on the command line,
10199 ** prompts the user if necessary (and possible) and
10200 ** sets the actual value for an ACD XY graph item.
10201 **
10202 ** Understands all attributes and associated qualifiers for this item type.
10203 **
10204 ** @param [u] thys [AcdPAcd] ACD item.
10205 ** @return [void]
10206 **
10207 ** @release 1.0.0
10208 ** @@
10209 ******************************************************************************/
10210 
acdSetGraphxy(AcdPAcd thys)10211 static void acdSetGraphxy(AcdPAcd thys)
10212 {
10213     AjPGraph val;
10214     AjPStr gdev = NULL;
10215 
10216     AjBool required = ajFalse;
10217     AjBool ok       = ajFalse;
10218 
10219     AjPStr title    = NULL;
10220     ajint itry;
10221     AjBool nullok;
10222     AjBool nulldefault;
10223     ajint multi;
10224     AjBool hasseq   = ajFalse;
10225 
10226     val = NULL;
10227 
10228     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
10229     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
10230     acdAttrToInt(thys, "multi", 1, &multi);
10231     if(multi < 1) multi = 1;
10232     acdLog("multi: %d\n", multi);
10233 
10234     required = acdIsRequired(thys);
10235     if(nullok && nulldefault)
10236     {
10237 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
10238 	{
10239 	    if(ajNamGetValueC("GRAPHICS",&gdev))
10240 		acdReplyInitS(thys, gdev, &acdReplyDef);
10241 	    else
10242 #ifndef WIN32
10243 #ifndef X_DISPLAY_MISSING /* X11 is available */
10244 		acdReplyInitC(thys, "x11", &acdReplyDef);
10245 #else
10246 #ifdef PLD_png          /* if png/gd/zlib libraries available for png driver */
10247 		acdReplyInitC(thys, "png", &acdReplyDef);
10248 #else
10249 		acdReplyInitC(thys, "ps", &acdReplyDef);
10250 #endif
10251 #endif
10252 #else
10253 	    acdReplyInitC(thys, "win3", &acdReplyDef);
10254 #endif
10255 	}
10256 	else				/* leave empty */
10257 	    acdReplyInitC(thys, "", &acdReplyDef);
10258     }
10259     else
10260     {
10261 	if(ajNamGetValueC("GRAPHICS",&gdev))
10262 	    acdReplyInitS(thys, gdev, &acdReplyDef);
10263 	else
10264 #ifndef WIN32
10265 #ifndef X_DISPLAY_MISSING /* X11 is available */
10266 	    acdReplyInitC(thys, "x11", &acdReplyDef);
10267 #else
10268 #ifdef PLD_png          /* if png/gd/zlib libraries available for png driver */
10269 	    acdReplyInitC(thys, "png", &acdReplyDef);
10270 #else
10271 	    acdReplyInitC(thys, "ps", &acdReplyDef);
10272 #endif
10273 #endif
10274 #else
10275 	    acdReplyInitC(thys, "win3", &acdReplyDef);
10276 #endif
10277     }
10278     ajStrDel(&gdev);
10279     acdPromptGraph(thys);
10280 
10281     for(itry=acdPromptTry; itry && !ok; itry--)
10282     {
10283 	ok = ajTrue;	   /* accept the default if nothing changes */
10284 
10285 	ajStrAssignS(&acdReply, acdReplyDef);
10286 
10287 	if(required)
10288 	    acdUserGet(thys, &acdReply);
10289 
10290 	if(ajStrGetLen(acdReply))	/* valid no graph type */
10291 	{
10292 	    if(!val)
10293 	        val = ajGraphxyNewI(multi);
10294 
10295 	    ok = ajGraphxySetDevicetype(val, acdReply);
10296 
10297 	    if(!ok)
10298 	    {
10299 	        ajGraphicsDumpDevices();
10300 		acdBadVal(thys, required,
10301 			  "Invalid XY graph value '%S'", acdReply);
10302 	    }
10303 	}
10304 	else
10305 	    if(!nullok)
10306 	    {
10307 		acdBadVal(thys, required,
10308 			  "Graph is required");
10309 		ok = ajFalse;
10310 	    }
10311     }
10312 
10313     if(!ok)
10314 	acdBadRetry(thys);
10315 
10316     thys->Value = val;
10317     ajStrAssignC(&thys->ValStr, "XY graph definition");
10318 
10319     if(val)
10320     {
10321         acdAttrToBool(thys, "sequence", ajFalse, &hasseq);
10322         if(hasseq)
10323             ajGraphSetDatanameS(val, acdInFName);
10324 
10325 	if(acdGetValueAssoc(thys, "gdesc", &title))
10326 	    ajGraphSetDescS(val,title);
10327 
10328 	if(acdGetValueAssoc(thys, "gtitle", &title))
10329 	    ajGraphSetTitleS(val,title);
10330 
10331 	if(acdGetValueAssoc(thys, "gsubtitle", &title))
10332 	    ajGraphSetSubtitleS(val,title);
10333 
10334 	if(acdGetValueAssoc(thys, "gxtitle", &title))
10335 	    ajGraphSetXlabelS(val,title);
10336         else if(hasseq)
10337             ajGraphSetXlabelS(val, acdInFName);
10338 
10339 	if(acdGetValueAssoc(thys, "gytitle", &title))
10340 	    ajGraphSetYlabelS(val,title);
10341 
10342 	if(acdGetValueAssoc(thys, "goutfile", &title))
10343 	    ajGraphSetOutfileS(val,title);
10344 
10345 	if(acdGetValueAssoc(thys, "gdirectory", &title))
10346 	    ajGraphSetOutdirS(val,title);
10347 	else
10348 	{
10349 	    ajStrAssignClear(&title);
10350 	    if(acdOutDirectory(&title))
10351                 ajGraphSetOutdirS(val,title);
10352 	}
10353 
10354 	ajStrDel(&title);
10355 	ajGraphTrace(val);
10356     }
10357 
10358     return;
10359 }
10360 
10361 
10362 
10363 
10364 /* @func ajAcdGetInfile *******************************************************
10365 **
10366 ** Returns an item of type file as defined in a named ACD item.
10367 ** Called by the application after all ACD values have been set,
10368 ** and simply returns what the ACD item already has.
10369 **
10370 ** @param [r] token [const char*] Text token name
10371 ** @return [AjPFile] File object. The file was already opened by
10372 **         acdSetInfile so this just returns the pointer.
10373 ** @cre failure to find an item with the right name and type aborts.
10374 **
10375 ** @release 1.0.0
10376 ** @@
10377 ******************************************************************************/
10378 
ajAcdGetInfile(const char * token)10379 AjPFile ajAcdGetInfile(const char *token)
10380 {
10381     return acdGetValueRef(token, "infile");
10382 }
10383 
10384 
10385 
10386 
10387 /* @funcstatic acdSetInfile ***************************************************
10388 **
10389 ** Using the definition in the ACD file, and any values for the
10390 ** item or its associated qualifiers provided on the command line,
10391 ** prompts the user if necessary (and possible) and
10392 ** sets the actual value for an ACD infile item.
10393 **
10394 ** Understands all attributes and associated qualifiers for this item type.
10395 **
10396 ** The default value (if filtering is on) is "stdin", but then
10397 ** prompting is turned off.
10398 **
10399 ** Otherwise there is no default value unless the ACD file has one.
10400 **
10401 ** Various file naming options are defined, but not yet implemented here.
10402 **
10403 ** @param [u] thys [AcdPAcd] ACD item.
10404 ** @return [void]
10405 ** @see ajFileNewIn
10406 **
10407 ** @release 1.0.0
10408 ** @@
10409 ******************************************************************************/
10410 
acdSetInfile(AcdPAcd thys)10411 static void acdSetInfile(AcdPAcd thys)
10412 {
10413     AjPFile val;
10414 
10415     AjBool required = ajFalse;
10416     AjBool ok       = ajFalse;
10417 
10418     ajint itry;
10419     AjBool nullok;
10420     AjBool trydefault;
10421 
10422     AjPStr infname = NULL;
10423     AjPStr inpath = NULL;
10424 
10425     val = NULL;				/* set the default value */
10426 
10427     acdAttrToStr(thys, "directory", "", &inpath);
10428     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
10429     acdAttrToBool(thys, "trydefault", ajFalse, &trydefault);
10430 
10431     acdInFilename(&infname);
10432     required = acdIsRequired(thys);
10433     acdReplyInitS(thys, infname, &acdReplyDef);
10434     acdPromptInfile(thys);
10435     ajStrDel(&infname);
10436 
10437     for(itry=acdPromptTry; itry && !ok; itry--)
10438     {
10439 	ok = ajTrue;	   /* accept the default if nothing changes */
10440 
10441 	ajStrAssignS(&acdReply, acdReplyDef);
10442 
10443 	if(required)
10444 	    acdUserGet(thys, &acdReply);
10445 
10446 	if(ajStrGetLen(acdReply))
10447 	{
10448 	    if(!ajFilenameHasPath(acdReply))
10449                 val = ajFileNewInNamePathS(acdReply,inpath);
10450             else
10451                 val = ajFileNewInNameS(acdReply);
10452 
10453 	    if(!val)
10454 	    {
10455 		if(!nullok ||
10456 		   !trydefault ||
10457 		   !ajStrMatchS(acdReply, acdReplyDef))
10458 		{
10459                     if(ajStrGetLen(inpath) && !ajFilenameHasPath(acdReply))
10460                         acdBadVal(thys, required,
10461                                   "Unable to open file '%S/%S' for input",
10462                                   inpath, acdReply);
10463                     else
10464                         acdBadVal(thys, required,
10465                                   "Unable to open file '%S' for input",
10466                                   acdReply);
10467 		    ok = ajFalse;
10468 		}
10469 	    }
10470 	}
10471 	else
10472 	    if(!nullok)
10473 	    {
10474 		acdBadVal(thys, required,
10475 			  "Input file is required");
10476 		ok = ajFalse;
10477 	    }
10478     }
10479 
10480     if(!ok)
10481 	acdBadRetry(thys);
10482 
10483     acdInFileSave(acdReply, NULL, ajTrue);
10484 
10485     thys->Value = val;
10486     ajStrAssignS(&thys->ValStr, acdReply);
10487 
10488     ajStrDel(&inpath);
10489 
10490     return;
10491 }
10492 
10493 
10494 
10495 
10496 /* @func ajAcdGetInt **********************************************************
10497 **
10498 ** Returns an item of type ajint as defined in a named ACD item. Called by the
10499 ** application after all ACD values have been set, and simply returns
10500 ** what the ACD item already has.
10501 **
10502 ** The ACD item is expected to have the large attribute set to false.
10503 **
10504 ** @param [r] token [const char*] Text token name
10505 ** @return [ajint] Integer value from ACD item
10506 ** @cre failure to find an item with the right name and type aborts.
10507 **
10508 ** @release 1.0.0
10509 ** @@
10510 ******************************************************************************/
10511 
ajAcdGetInt(const char * token)10512 ajint ajAcdGetInt(const char *token)
10513 {
10514     ajlong *val;
10515 
10516     val = acdGetValue(token, "integer");
10517 
10518     return (ajint) *val;
10519 }
10520 
10521 
10522 
10523 
10524 /* @func ajAcdGetIntLong ******************************************************
10525 **
10526 ** Returns an item of type ajlong as defined in a named ACD item. Called by the
10527 ** application after all ACD values have been set, and simply returns
10528 ** what the ACD item already has.
10529 **
10530 ** The ACD item is expected to have the large attribute set to true.
10531 **
10532 ** @param [r] token [const char*] Text token name
10533 ** @return [ajlong] Integer value from ACD item
10534 ** @cre failure to find an item with the right name and type aborts.
10535 **
10536 ** @release 6.1.0
10537 ** @@
10538 ******************************************************************************/
10539 
ajAcdGetIntLong(const char * token)10540 ajlong ajAcdGetIntLong(const char *token)
10541 {
10542     ajlong *val;
10543 
10544     val = acdGetValue(token, "integer");
10545 
10546     return *val;
10547 }
10548 
10549 
10550 
10551 
10552 /* @funcstatic acdSetInt ******************************************************
10553 **
10554 ** Using the definition in the ACD file, and any values for the
10555 ** item or its associated qualifiers provided on the command line,
10556 ** prompts the user if necessary (and possible) and
10557 ** sets the actual value for an ACD integer item.
10558 **
10559 ** Understands all attributes and associated qualifiers for this item type.
10560 **
10561 ** The default value (if no other available) is "0".
10562 **
10563 ** Min and max limits, if set, are applied without comment.
10564 **
10565 ** @param [u] thys [AcdPAcd] ACD item.
10566 ** @return [void]
10567 ** @see ajStrToInt
10568 **
10569 ** @release 1.0.0
10570 ** @@
10571 ******************************************************************************/
10572 
acdSetInt(AcdPAcd thys)10573 static void acdSetInt(AcdPAcd thys)
10574 {
10575     ajlong* val;
10576     ajint ival;
10577 
10578     AjBool required = ajFalse;
10579     AjBool ok       = ajFalse;
10580 
10581     ajint itry;
10582     AjBool failrange;
10583     AjBool warnrange;
10584     AjBool islong;
10585     AjBool truemin;
10586 
10587     ajlong imin;
10588     ajlong imax;
10589     AjPStr failmsg = NULL;
10590     AjBool iscalc = ajFalse;
10591 
10592     acdRangeTestCalc(thys);
10593 
10594     acdAttrToLong(thys, "minimum", INT_MIN, &imin);
10595     acdLog("minimum: %Ld\n", imin);
10596 
10597     acdAttrToLong(thys, "maximum", INT_MAX, &imax);
10598     acdLog("maximum: %Ld\n", imax);
10599 
10600     acdAttrToBool(thys, "failrange", ajTrue, &failrange);
10601     acdLog("failrange: %B\n", failrange);
10602 
10603     acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange);
10604     acdLog("warnrange: %B\n", warnrange);
10605 
10606     acdAttrToBool(thys, "large", AJFALSE, &islong);
10607     acdLog("large: %B\n", islong);
10608 
10609     acdAttrToBool(thys, "trueminimum", AJFALSE, &truemin);
10610     acdLog("trueminimum: %B\n", truemin);
10611 
10612     if(failrange && (imin > imax))
10613     {
10614         acdAttrResolve(thys, "rangemessage", &failmsg);
10615         if(ajStrGetLen(failmsg))
10616             acdErrorAcd(thys, "Invalid range: %S", failmsg);
10617         else
10618             acdErrorAcd(thys,
10619                         "Invalid range: "
10620                         "minimum value %d more than maximum %d",
10621                         imin, imax);
10622     }
10623 
10624     AJNEW0(val);		   /* create storage for the result */
10625 
10626     *val = 0;				/* set the default value */
10627 
10628     required = acdIsRequired(thys);
10629     acdReplyInitC(thys, "0", &acdReplyDef);
10630 
10631     acdLog("acdSetInt %S default '%S' Required: %B\n",
10632 	   thys->Name, acdReplyDef, required);
10633 
10634     for(itry=acdPromptTry; itry && !ok; itry--)
10635     {
10636 	ajStrAssignS(&acdReply, acdReplyDef);
10637 
10638 	if(required)
10639 	    acdUserGet(thys, &acdReply);
10640 
10641 	acdLog(" reply: '%S' \n", acdReply);
10642 
10643 	if(ajStrMatchC(acdReply, "default"))
10644 	    ajStrAssignC(&acdReply, "0");
10645 
10646         if(islong)
10647             ok = ajStrToLong(acdReply, val);
10648         else
10649         {
10650             ok = ajStrToInt(acdReply, &ival);
10651             *val = ival;
10652         }
10653 
10654 	acdLog(" modified reply: '%S' val: %Ld ok: %B\n", acdReply, *val, ok);
10655 
10656 	if(!ok)
10657 	    acdBadVal(thys, required,
10658 		      "Invalid integer value '%S'", acdReply);
10659     }
10660 
10661     if(!ok)
10662 	acdBadRetry(thys);
10663 
10664     if(islong && imin == INT_MIN)
10665         imin = LONG_MIN;
10666 
10667     if(islong && imax == INT_MAX)
10668         imax = LONG_MAX;
10669 
10670     if(iscalc)
10671     {
10672         if(!truemin && *val < imin)
10673         {					/* reset within limits */
10674             if(warnrange)
10675                 ajWarn("integer value out of range %Ld less than "
10676                        "(reset to) %Ld",
10677                        *val, imin);
10678             *val = imin;
10679         }
10680 
10681         if(*val > imax)
10682         {
10683             if(warnrange)
10684                 ajWarn("integer value out of range %Ld more than "
10685                        "(reset to) %Ld",
10686                        *val, imax);
10687             *val = imax;
10688         }
10689 
10690         if(truemin && *val < imin)
10691         {					/* reset within limits */
10692             if(warnrange)
10693                 ajWarn("integer value out of range %Ld less than "
10694                        "(reset to) %Ld",
10695                        *val, imin);
10696             *val = imin;
10697         }
10698     }
10699 
10700     else
10701     {
10702         if(*val < imin)
10703         {					/* reset within limits */
10704             if(warnrange)
10705                 ajWarn("integer value out of range %Ld less than "
10706                        "(reset to) %Ld",
10707                        *val, imin);
10708             *val = imin;
10709         }
10710 
10711         if(*val > imax)
10712         {
10713             if(warnrange)
10714                 ajWarn("integer value out of range %Ld more than "
10715                        "(reset to) %Ld",
10716                        *val, imax);
10717             *val = imax;
10718         }
10719     }
10720 
10721     thys->Value = val;
10722     ajStrFromLong(&thys->ValStr, *val);
10723 
10724     return;
10725 }
10726 
10727 
10728 
10729 
10730 /* @func ajAcdGetList *********************************************************
10731 **
10732 ** Returns an item of type List as defined in a named ACD item,
10733 ** which is an array of strings terminated by a null value.
10734 ** Called by the application after all ACD values have been set,
10735 ** and simply returns what the ACD item already has.
10736 **
10737 ** @param [r] token [const char*] Text token name
10738 ** @return [AjPStr*] String array of values with NULL for last element.
10739 ** @cre failure to find an item with the right name and type aborts.
10740 **
10741 ** @release 1.0.0
10742 ** @@
10743 ******************************************************************************/
10744 
ajAcdGetList(const char * token)10745 AjPStr* ajAcdGetList(const char *token)
10746 {
10747     return acdGetValueRef(token, "list");
10748 }
10749 
10750 
10751 
10752 
10753 /* @func ajAcdGetListSingle ***************************************************
10754 **
10755 ** Returns a single item from an array of type List as defined in a named
10756 ** ACD item, which is an array of strings terminated by a null value.
10757 ** Called by the application after all ACD values have been set, and
10758 ** simply returns what the ACD item already has.
10759 **
10760 ** @param [r] token [const char*] Text token name
10761 ** @return [AjPStr] String array of values with NULL for last element.
10762 ** @cre failure to find an item with the right name and type aborts.
10763 **
10764 ** @release 4.0.0
10765 ** @@
10766 ******************************************************************************/
10767 
ajAcdGetListSingle(const char * token)10768 AjPStr ajAcdGetListSingle(const char *token)
10769 {
10770     AjPStr *val;
10771     ajint i;
10772 
10773     val = acdGetValueSingle(token, "list");
10774 
10775     for(i=0; val[i]; i++)
10776 	continue;
10777 
10778     if(i > 1)
10779 	ajWarn("Single list value %s, but can choose %d values",
10780 	       token, i);
10781 
10782     if(i < 1)
10783 	ajWarn("Single list value %s, no value found: returning NULL value",
10784 	       token);
10785 
10786     return val[0];
10787 }
10788 
10789 
10790 
10791 
10792 /* @funcstatic acdSetList *****************************************************
10793 **
10794 ** Using the definition in the ACD file, and any values for the
10795 ** item or its associated qualifiers provided on the command line,
10796 ** prompts the user if necessary (and possible) and
10797 ** sets the actual value for an ACD outfile item.
10798 **
10799 ** Understands all attributes and associated qualifiers for this item type.
10800 **
10801 ** If a value is required and not yet given, prints out a header
10802 ** and the list of options, then asks for a selection or (if max is
10803 ** more than 1) a list of selections.
10804 **
10805 ** @param [u] thys [AcdPAcd] ACD item.
10806 ** @return [void]
10807 **
10808 ** @release 1.0.0
10809 ** @@
10810 ******************************************************************************/
10811 
acdSetList(AcdPAcd thys)10812 static void acdSetList(AcdPAcd thys)
10813 {
10814     AjPStr *val;
10815 
10816     AjBool required = ajFalse;
10817     AjBool ok       = ajFalse;
10818 
10819     ajint itry;
10820     ajint i;
10821 
10822     ajint min, max;
10823 
10824     val = NULL;				/* set the default value */
10825 
10826     required = acdIsRequired(thys);
10827     acdReplyInitC(thys, "", &acdReplyDef);
10828 
10829     acdAttrToInt(thys, "minimum", 1, &min);
10830     acdAttrToInt(thys, "maximum", 1, &max);
10831 
10832     for(itry=acdPromptTry; itry && !ok; itry--)
10833     {
10834 	ok = ajTrue;	   /* accept the default if nothing changes */
10835 
10836 	ajStrAssignS(&acdReply, acdReplyDef);
10837 
10838 	if(required)
10839 	{
10840 	    acdListPrompt(thys);
10841 	    acdUserGet(thys, &acdReply);
10842 	}
10843 
10844 	val = acdListValue(thys, min, max, acdReply);
10845 
10846 	if(!val)
10847 	{
10848 	    acdBadVal(thys, required, "Bad menu option '%S'", acdReply);
10849 	    ok = ajFalse;
10850 	}
10851     }
10852 
10853     if(!ok)
10854 	acdBadRetry(thys);
10855 
10856     thys->Value = val;
10857 
10858     for(i=0; val[i]; i++)
10859     {
10860 	acdLog("Storing val[%d] '%S'\n", i,val[i]);
10861 
10862 	if(i)
10863 	    ajStrAppendC(&thys->ValStr, ";");
10864 
10865 	ajStrAppendS(&thys->ValStr, val[i]);
10866     }
10867 
10868     return;
10869 }
10870 
10871 
10872 
10873 
10874 /* @func ajAcdGetMatrix *******************************************************
10875 **
10876 ** Returns an item of type Matrix as defined in a named ACD item.
10877 ** Called by the application after all ACD values have been set,
10878 ** and simply returns what the ACD item already has.
10879 **
10880 ** @param [r] token [const char*] Text token name
10881 ** @return [AjPMatrix] Matrix object.
10882 ** @cre failure to find an item with the right name and type aborts.
10883 **
10884 ** @release 1.0.0
10885 ** @@
10886 ******************************************************************************/
10887 
ajAcdGetMatrix(const char * token)10888 AjPMatrix ajAcdGetMatrix(const char *token)
10889 {
10890     return acdGetValueRef(token, "matrix");
10891 }
10892 
10893 
10894 
10895 
10896 /* @func ajAcdGetMatrixf ******************************************************
10897 **
10898 ** Returns an item of type Matrix as defined in a named ACD item.
10899 ** Called by the application after all ACD values have been set,
10900 ** and simply returns what the ACD item already has.
10901 **
10902 ** @param [r] token [const char*] Text token name
10903 ** @return [AjPMatrixf] Float Matrix object.
10904 ** @cre failure to find an item with the right name and type aborts.
10905 **
10906 ** @release 1.0.0
10907 ** @@
10908 ******************************************************************************/
10909 
ajAcdGetMatrixf(const char * token)10910 AjPMatrixf ajAcdGetMatrixf(const char *token)
10911 {
10912     return acdGetValueRef(token, "matrixf");
10913 }
10914 
10915 
10916 
10917 
10918 /* @funcstatic acdSetMatrix ***************************************************
10919 **
10920 ** Using the definition in the ACD file, and any values for the
10921 ** item or its associated qualifiers provided on the command line,
10922 ** prompts the user if necessary (and possible) and
10923 ** sets the actual value for an ACD matrix item.
10924 **
10925 ** Understands all attributes and associated qualifiers for this item type.
10926 **
10927 ** @param [u] thys [AcdPAcd] ACD item.
10928 ** @return [void]
10929 ** @see ajMatrixNewFile
10930 **
10931 ** @release 1.0.0
10932 ** @@
10933 ******************************************************************************/
10934 
acdSetMatrix(AcdPAcd thys)10935 static void acdSetMatrix(AcdPAcd thys)
10936 {
10937     AjPMatrix val;
10938 
10939     AjBool required = ajFalse;
10940     AjBool ok       = ajFalse;
10941 
10942     ajint itry;
10943     AjBool isprot;
10944 
10945     AjPStr infname = NULL;
10946 
10947     val = NULL;				/* set the default value */
10948 
10949     acdAttrToBool(thys, "protein", ajTrue, &isprot);
10950 
10951     if(isprot)
10952     {
10953 	acdAttrResolve(thys, "pname", &infname);
10954 	if(!ajStrGetLen(infname))
10955 	    ajStrAssignC(&infname, DEFBLOSUM);
10956     }
10957     else
10958     {
10959 	acdAttrResolve(thys, "nname", &infname);
10960 
10961 	if(!ajStrGetLen(infname))
10962 	    ajStrAssignC(&infname, DEFDNA);
10963     }
10964 
10965     required = acdIsRequired(thys);
10966     acdReplyInitS(thys, infname, &acdReplyDef);
10967     ajStrDel(&infname);
10968 
10969     for(itry=acdPromptTry; itry && !ok; itry--)
10970     {
10971 	ok = ajTrue;	   /* accept the default if nothing changes */
10972 
10973 	ajStrAssignS(&acdReply, acdReplyDef);
10974 
10975 	if(required)
10976 	    acdUserGet(thys, &acdReply);
10977 
10978 	if(ajStrGetLen(acdReply))
10979 	{
10980 	    val = ajMatrixNewFile(acdReply);
10981             if(!val)
10982 	    {
10983 		acdBadVal(thys, required,
10984 			  "Unable to read matrix '%S'", acdReply);
10985 		ok = ajFalse;
10986 	    }
10987 	}
10988 	else
10989 	{
10990 	    acdBadVal(thys, required, "Matrix is required");
10991 	    ok = ajFalse;
10992 	}
10993     }
10994 
10995     if(!ok)
10996 	acdBadRetry(thys);
10997 
10998     thys->Value = val;
10999     ajStrAssignS(&thys->ValStr, acdReply);
11000 
11001     return;
11002 }
11003 
11004 
11005 
11006 
11007 /* @funcstatic acdSetMatrixf **************************************************
11008 **
11009 ** Using the definition in the ACD file, and any values for the
11010 ** item or its associated qualifiers provided on the command line,
11011 ** prompts the user if necessary (and possible) and
11012 ** sets the actual value for an ACD matrix item.
11013 **
11014 ** Understands all attributes and associated qualifiers for this item type.
11015 **
11016 ** @param [u] thys [AcdPAcd] ACD item.
11017 ** @return [void]
11018 ** @see ajMatrixfNewFile
11019 **
11020 ** @release 1.0.0
11021 ** @@
11022 ******************************************************************************/
11023 
acdSetMatrixf(AcdPAcd thys)11024 static void acdSetMatrixf(AcdPAcd thys)
11025 {
11026     AjPMatrixf val;
11027 
11028     AjBool required = ajFalse;
11029     AjBool ok       = ajFalse;
11030 
11031     ajint itry;
11032     AjBool isprot;
11033 
11034     AjPStr infname = NULL;
11035 
11036 
11037     val = NULL;				/* set the default value */
11038 
11039     acdAttrToBool(thys, "protein", ajTrue, &isprot);
11040 
11041     if(isprot)
11042     {
11043 	acdAttrResolve(thys, "pname", &infname);
11044 
11045 	if(!ajStrGetLen(infname))
11046 	    ajStrAssignC(&infname, DEFBLOSUM);
11047     }
11048     else
11049     {
11050 	acdAttrResolve(thys, "nname", &infname);
11051 
11052 	if(!ajStrGetLen(infname))
11053 	    ajStrAssignC(&infname, DEFDNA);
11054     }
11055 
11056     required = acdIsRequired(thys);
11057     acdReplyInitS(thys, infname, &acdReplyDef);
11058     ajStrDel(&infname);
11059 
11060     for(itry=acdPromptTry; itry && !ok; itry--)
11061     {
11062 	ok = ajTrue;	   /* accept the default if nothing changes */
11063 
11064 	ajStrAssignS(&acdReply, acdReplyDef);
11065 
11066 	if(required)
11067 	    acdUserGet(thys, &acdReply);
11068 
11069 	if(ajStrGetLen(acdReply))
11070 	{
11071 	    val = ajMatrixfNewFile(acdReply);
11072 	    if(!val)
11073             {
11074 		acdBadVal(thys, required,
11075 			  "Unable to read matrix '%S'", acdReply);
11076 		ok = ajFalse;
11077 	    }
11078 	}
11079 	else
11080 	{
11081 	    acdBadVal(thys, required, "Matrix is required");
11082 	    ok = ajFalse;
11083 	}
11084     }
11085 
11086     if(!ok)
11087 	acdBadRetry(thys);
11088 
11089     thys->Value = val;
11090     ajStrAssignS(&thys->ValStr, acdReply);
11091 
11092     return;
11093 }
11094 
11095 
11096 
11097 
11098 /* @func ajAcdGetObo **********************************************************
11099 **
11100 ** Returns an item of type Obo as defined in a named ACD item.
11101 ** Called by the application after all ACD values have been set,
11102 ** and simply returns what the ACD item already has.
11103 **
11104 ** @param [r] token [const char*] Text token name
11105 ** @return [AjPObo] Obo term object
11106 ** @cre failure to find an item with the right name and type aborts.
11107 **
11108 ** @release 6.4.0
11109 ** @@
11110 ******************************************************************************/
11111 
ajAcdGetObo(const char * token)11112 AjPObo ajAcdGetObo(const char *token)
11113 {
11114     AjPOboall val = acdGetValue(token, "obo");
11115     if(val->Multi)
11116         ajWarn("ajAcdGetObo request single obo term but maxreads > 1");
11117 
11118     val->Returned = ajTrue;
11119 
11120     return val->Obo;
11121 }
11122 
11123 
11124 
11125 
11126 /* @func ajAcdGetOboall *******************************************************
11127 **
11128 ** Returns an input stream of an item of type Obo as defined in a
11129 ** named ACD item.
11130 ** Called by the application after all ACD values have been set,
11131 ** and simply returns what the ACD item already has.
11132 **
11133 ** @param [r] token [const char*] Text token name
11134 ** @return [AjPOboall] Obo input stream
11135 ** @cre failure to find an item with the right name and type aborts.
11136 **
11137 ** @release 6.4.0
11138 ** @@
11139 ******************************************************************************/
11140 
ajAcdGetOboall(const char * token)11141 AjPOboall ajAcdGetOboall(const char *token)
11142 {
11143     AjPOboall val = acdGetValueRef(token, "obo");
11144 
11145     if(!val->Multi)
11146         ajWarn("ajAcdGetOboall request obo input stream but maxreads is 1");
11147 
11148     return val;
11149 }
11150 
11151 
11152 
11153 
11154 /* @funcstatic acdSetObo ******************************************************
11155 **
11156 ** Using the definition in the ACD file, and any values for the
11157 ** item or its associated qualifiers provided on the command line,
11158 ** prompts the user if necessary (and possible) and
11159 ** sets the actual value for an ACD obo term input
11160 **
11161 ** Understands all attributes and associated qualifiers for this item type.
11162 **
11163 ** @param [u] thys [AcdPAcd] ACD item.
11164 ** @return [void]
11165 **
11166 ** @release 6.4.0
11167 ** @@
11168 ******************************************************************************/
11169 
acdSetObo(AcdPAcd thys)11170 static void acdSetObo(AcdPAcd thys)
11171 {
11172     AjPOboall val;
11173 
11174     AjBool required = ajFalse;
11175     AjBool ok       = ajFalse;
11176     AjBool nullok   = ajFalse;
11177     ajint itry;
11178 
11179     ajint maxreads;
11180 
11181     AjPStr infname = NULL;
11182 
11183     val = ajOboallNew();        /* set the default value */
11184 
11185     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
11186     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
11187 
11188     acdInFilename(&infname);
11189     required = acdIsRequired(thys);
11190     acdReplyInitS(thys, infname, &acdReplyDef);
11191     ajStrDel(&infname);
11192 
11193     acdAttrToBool(thys, "entry", ajFalse, &val->Oboin->Input->Text);
11194 
11195     for(itry=acdPromptTry; itry && !ok; itry--)
11196     {
11197 	ok = ajTrue;	   /* accept the default if nothing changes */
11198 
11199 	ajStrAssignS(&acdReply, acdReplyDef);
11200 
11201 	if(required)
11202 	    acdUserGet(thys, &acdReply);
11203 
11204 	if(!ajStrGetLen(acdReply) && nullok)
11205         {
11206             ajOboallDel(&val);
11207 	    break;
11208 	}
11209 
11210 	ajOboinQryS(val->Oboin, acdReply);
11211 
11212 	acdGetValueAssoc(thys, "iformat", &val->Oboin->Input->Formatstr);
11213 	acdGetValueAssoc(thys, "iquery", &val->Oboin->Input->QryFields);
11214 	acdQualToLong(thys, "ioffset", 0L, &val->Oboin->Input->Fpos,
11215                       &acdTmpStr);
11216 
11217         ok = ajOboinRead(val->Oboin, val->Obo);
11218     }
11219 
11220     if(!ok)
11221 	acdBadRetry(thys);
11222 
11223     if(maxreads > 1)
11224         val->Multi = ajTrue;
11225 
11226     acdInFileSave(acdReply, ajOboallGetoboId(val), ajTrue);
11227 
11228     thys->Value = val;
11229     ajStrAssignS(&thys->ValStr, acdReply);
11230 
11231     return;
11232 }
11233 
11234 
11235 
11236 
11237 /* @funcstatic acdSetOutType **************************************************
11238 **
11239 ** Generic definition for any of the ACD formatted output types.
11240 ** May be replaced by a specific acdSet function if additional attributes
11241 ** or qualifiers are to be processed.
11242 **
11243 ** Understands all attributes and associated qualifiers for these item types.
11244 **
11245 ** The default value (if no other available) is a null string, which
11246 ** is invalid.
11247 **
11248 ** Associated qualifiers "-oformat"
11249 ** are stored in the object and applied to the data on output.
11250 **
11251 ** @param [u] thys [AcdPAcd] ACD item.
11252 ** @param [r] type [const char*] Standard output type name.
11253 ** @return [AjPOutfile] Output file object of the specified type
11254 **
11255 ** @release 2.9.0
11256 ** @@
11257 ******************************************************************************/
11258 
acdSetOutType(AcdPAcd thys,const char * type)11259 static AjPOutfile acdSetOutType(AcdPAcd thys, const char* type)
11260 {
11261     AjPOutfile val = NULL;
11262 
11263     AjBool required = ajFalse;
11264     AjBool ok       = ajFalse;
11265 
11266     ajint itry;
11267     AjBool nullok;
11268     AjBool nulldefault;
11269 
11270     AjPStr name      = NULL;
11271     AjPStr ext       = NULL;
11272     AjPStr fmt       = NULL;
11273     AjPStr dir       = NULL;
11274     ajint itype = -1;
11275     ajint i;
11276 
11277     val = NULL;
11278 
11279     for (i=0; acdOuttype[i].Name; i++)
11280 	if (ajCharMatchC(acdOuttype[i].Name, type))
11281 	{
11282 	    itype = i;
11283 	    break;
11284 	}
11285 
11286     if (itype < 0)
11287 	acdError("Unknown output type '%s'", type);
11288 
11289     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
11290     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
11291     acdAttrResolve(thys, "name", &name);
11292 
11293     if (!acdGetValueAssoc(thys, "oformat", &fmt))
11294 	ajStrAssignC(&fmt, acdOuttype[itype].Format);
11295 
11296     if(!acdAttrResolve(thys, "extension", &ext))
11297 	ajStrAssignS(&ext, fmt);
11298 
11299     acdGetValueAssoc(thys, "odirectory", &dir);
11300 
11301     acdOutDirectory(&dir);
11302     required = acdIsRequired(thys);
11303     if(nullok && nulldefault)
11304     {
11305 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
11306 	    acdOutFilename(&acdReplyDef, name, ext);
11307 	else				/* leave empty */
11308 	    acdReplyInitC(thys, "", &acdReplyDef);
11309     }
11310     else
11311     {
11312 	acdOutFilename(&acdTmpOutFName, name, ext);
11313 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
11314     }
11315 
11316     ajStrDel(&name);
11317     ajStrDel(&ext);
11318 
11319     if(acdOuttype[itype].Prompt)
11320 	(*acdOuttype[itype].Prompt)(thys);
11321 
11322     for(itry=acdPromptTry; itry && !ok; itry--)
11323     {
11324 	ok = ajTrue;	   /* accept the default if nothing changes */
11325 
11326 	ajStrAssignS(&acdReply, acdReplyDef);
11327 
11328 	if(required)
11329 	    acdUserGet(thys, &acdReply);
11330 
11331 	if(ajStrGetLen(acdReply))
11332 	{
11333 	    ajStrAssignS(&acdOutFullFName, acdReply);
11334 	    ajFilenameReplacePathS(&acdOutFullFName, dir);
11335 	    val = ajOutfileNewNameS(acdOutFullFName);
11336 
11337 	    if(!ok)
11338 	    {
11339 		acdBadVal(thys, required,
11340 			  "Unable to open output file '%S'",
11341 			  acdOutFullFName);
11342 		ajOutfileClose(&val);
11343 	    }
11344 
11345 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
11346 	    ajStrAssignEmptyC(&val->Type, type);
11347 
11348 	    if(acdOuttype[itype].Outformat)
11349 	    {
11350 		if(!(*acdOuttype[itype].Outformat)(val->Formatstr,
11351                                                    &val->Format))
11352 		{			/* test acdc-outbadformat */
11353 		    ajDie("Output option -%S: "
11354 			  "Format validation failed for type '%s'",
11355 			  thys->Name, type);
11356 		}
11357 	    }
11358 
11359 	}
11360 	else
11361 	    if(!nullok)
11362 	    {
11363 		acdBadVal(thys, required,
11364 			  "Output file is required");
11365 		ok = ajFalse;
11366 	    }
11367     }
11368 
11369     if(!ok)
11370 	acdBadRetry(thys);
11371 
11372     thys->Value = val;
11373     ajStrAssignS(&thys->ValStr, acdOutFullFName);
11374 
11375     ajStrDel(&fmt);
11376     ajStrDel(&dir);
11377 
11378     return val;
11379 }
11380 
11381 
11382 
11383 
11384 /* @func ajAcdGetOutassembly **************************************************
11385 **
11386 ** Returns an item of type Outassembly as defined in a named ACD item.
11387 ** Called by the application after all ACD values have been set,
11388 ** and simply returns what the ACD item already has.
11389 **
11390 ** @param [r] token [const char*] Text token name
11391 ** @return [AjPOutfile] File object. The file was already opened by
11392 **         acdSetOut so this just returns the pointer.
11393 ** @cre failure to find an item with the right name and type aborts.
11394 **
11395 ** @release 6.5.0
11396 ** @@
11397 ******************************************************************************/
11398 
ajAcdGetOutassembly(const char * token)11399 AjPOutfile ajAcdGetOutassembly(const char *token)
11400 {
11401     return acdGetValueRef(token, "outassembly");
11402 }
11403 
11404 
11405 
11406 
11407 /* @funcstatic acdSetOutassembly **********************************************
11408 **
11409 ** Using the definition in the ACD file, and any values for the
11410 ** item or its associated qualifiers provided on the command line,
11411 ** prompts the user if necessary (and possible) and
11412 ** sets the actual value for an ACD outassembly item.
11413 **
11414 ** Understands all attributes and associated qualifiers for this item type.
11415 **
11416 ** The default value (if no other available) is a null string, which
11417 ** is invalid.
11418 **
11419 ** Associated qualifiers "-oformat"
11420 ** are stored in the object and applied to the data on output.
11421 **
11422 ** @param [u] thys [AcdPAcd] ACD item.
11423 ** @return [void]
11424 **
11425 ** @release 6.5.0
11426 ** @@
11427 ******************************************************************************/
11428 
acdSetOutassembly(AcdPAcd thys)11429 static void acdSetOutassembly(AcdPAcd thys)
11430 {
11431     acdSetOutType(thys, "outassembly");
11432 
11433     return;
11434 }
11435 
11436 
11437 
11438 
11439 /* @func ajAcdGetOutcodon *****************************************************
11440 **
11441 ** Returns an item of type Outcodon as defined in a named ACD item.
11442 ** Called by the application after all ACD values have been set,
11443 ** and simply returns what the ACD item already has.
11444 **
11445 ** @param [r] token [const char*] Text token name
11446 ** @return [AjPOutfile] File object. The file was already opened by
11447 **         acdSetOut so this just returns the pointer.
11448 ** @cre failure to find an item with the right name and type aborts.
11449 **
11450 ** @release 2.9.0
11451 ** @@
11452 ******************************************************************************/
11453 
ajAcdGetOutcodon(const char * token)11454 AjPOutfile ajAcdGetOutcodon(const char *token)
11455 {
11456     return acdGetValueRef(token, "outcodon");
11457 }
11458 
11459 
11460 
11461 
11462 /* @funcstatic acdSetOutcodon *************************************************
11463 **
11464 ** Using the definition in the ACD file, and any values for the
11465 ** item or its associated qualifiers provided on the command line,
11466 ** prompts the user if necessary (and possible) and
11467 ** sets the actual value for an ACD outcodon item.
11468 **
11469 ** Understands all attributes and associated qualifiers for this item type.
11470 **
11471 ** The default value (if no other available) is a null string, which
11472 ** is invalid.
11473 **
11474 ** Associated qualifiers "-oformat"
11475 ** are stored in the object and applied to the data on output.
11476 **
11477 ** @param [u] thys [AcdPAcd] ACD item.
11478 ** @return [void]
11479 ** @see ajSeqRead
11480 **
11481 ** @release 2.9.0
11482 ** @@
11483 ******************************************************************************/
11484 
acdSetOutcodon(AcdPAcd thys)11485 static void acdSetOutcodon(AcdPAcd thys)
11486 {
11487     acdSetOutType(thys, "outcodon");
11488     return;
11489 }
11490 
11491 
11492 
11493 
11494 /* @func ajAcdGetOutcpdb ******************************************************
11495 **
11496 ** Returns an item of type Outcpdb as defined in a named ACD item.
11497 ** Called by the application after all ACD values have been set,
11498 ** and simply returns what the ACD item already has.
11499 **
11500 ** @param [r] token [const char*] Text token name
11501 ** @return [AjPOutfile] File object. The file was already opened by
11502 **         acdSetOut so this just returns the pointer.
11503 ** @cre failure to find an item with the right name and type aborts.
11504 **
11505 ** @release 2.9.0
11506 ** @@
11507 ******************************************************************************/
11508 
ajAcdGetOutcpdb(const char * token)11509 AjPOutfile ajAcdGetOutcpdb(const char *token)
11510 {
11511     return acdGetValueRef(token, "outcpdb");
11512 }
11513 
11514 
11515 
11516 
11517 /* @funcstatic acdSetOutcpdb **************************************************
11518 **
11519 ** Using the definition in the ACD file, and any values for the
11520 ** item or its associated qualifiers provided on the command line,
11521 ** prompts the user if necessary (and possible) and
11522 ** sets the actual value for an ACD outcpdb item.
11523 **
11524 ** Understands all attributes and associated qualifiers for this item type.
11525 **
11526 ** The default value (if no other available) is a null string, which
11527 ** is invalid.
11528 **
11529 ** Associated qualifiers "-oformat"
11530 ** are stored in the object and applied to the data on output.
11531 **
11532 ** @param [u] thys [AcdPAcd] ACD item.
11533 ** @return [void]
11534 ** @see ajSeqRead
11535 **
11536 ** @release 2.9.0
11537 ** @@
11538 ******************************************************************************/
11539 
acdSetOutcpdb(AcdPAcd thys)11540 static void acdSetOutcpdb(AcdPAcd thys)
11541 {
11542     acdSetOutType(thys, "outcpdb");
11543     return;
11544 }
11545 
11546 
11547 
11548 
11549 /* @func ajAcdGetOutdata ******************************************************
11550 **
11551 ** Returns an item of type Outdata as defined in a named ACD item.
11552 ** Called by the application after all ACD values have been set,
11553 ** and simply returns what the ACD item already has.
11554 **
11555 ** @param [r] token [const char*] Text token name
11556 ** @return [AjPOutfile] File object. The file was already opened by
11557 **         acdSetOut so this just returns the pointer.
11558 ** @cre failure to find an item with the right name and type aborts.
11559 **
11560 ** @release 2.9.0
11561 ** @@
11562 ******************************************************************************/
11563 
ajAcdGetOutdata(const char * token)11564 AjPOutfile ajAcdGetOutdata(const char *token)
11565 {
11566     return acdGetValueRef(token, "outdata");
11567 }
11568 
11569 
11570 
11571 
11572 /* @funcstatic acdSetOutdata **************************************************
11573 **
11574 ** Using the definition in the ACD file, and any values for the
11575 ** item or its associated qualifiers provided on the command line,
11576 ** prompts the user if necessary (and possible) and
11577 ** sets the actual value for an ACD outdata item.
11578 **
11579 ** Understands all attributes and associated qualifiers for this item type.
11580 **
11581 ** The default value (if no other available) is a null string, which
11582 ** is invalid.
11583 **
11584 ** Associated qualifiers "-oformat"
11585 ** are stored in the object and applied to the data on output.
11586 **
11587 ** @param [u] thys [AcdPAcd] ACD item.
11588 ** @return [void]
11589 ** @see ajSeqRead
11590 **
11591 ** @release 2.9.0
11592 ** @@
11593 ******************************************************************************/
11594 
acdSetOutdata(AcdPAcd thys)11595 static void acdSetOutdata(AcdPAcd thys)
11596 {
11597     acdSetOutType(thys, "outdata");
11598 
11599     return;
11600 }
11601 
11602 
11603 
11604 
11605 /* @func ajAcdGetOutdir *******************************************************
11606 **
11607 ** Returns an item of type AjPDirout which has been validated as an output
11608 ** directory.
11609 **
11610 ** Optionally can be forced to have a fully qualified path when returned.
11611 **
11612 ** @param [r] token [const char*] Text token name
11613 ** @return [AjPDirout] Output directory object
11614 ** @cre failure to find an item with the right name and type aborts.
11615 **
11616 ** @release 2.9.0
11617 ** @@
11618 ******************************************************************************/
11619 
ajAcdGetOutdir(const char * token)11620 AjPDirout ajAcdGetOutdir(const char *token)
11621 {
11622     return acdGetValueRef(token, "outdir");
11623 }
11624 
11625 
11626 
11627 
11628 /* @func ajAcdGetOutdirName ***************************************************
11629 **
11630 ** Returns an item of type AjPStr which has been validated as an output
11631 ** directory.
11632 **
11633 ** Optionally can be forced to have a fully qualified path when returned.
11634 **
11635 ** @param [r] token [const char*] Text token name
11636 ** @return [AjPStr] String containing a directory name
11637 ** @cre failure to find an item with the right name and type aborts.
11638 **
11639 ** @release 2.9.0
11640 ** @@
11641 ******************************************************************************/
11642 
ajAcdGetOutdirName(const char * token)11643 AjPStr ajAcdGetOutdirName(const char *token)
11644 {
11645     AjPStr ret = NULL;
11646     AjPDirout dirout;
11647 
11648     dirout =  acdGetValue(token, "outdir");
11649     ret = ajStrNewS(ajDiroutGetPath(dirout));
11650 
11651     return ret;
11652 }
11653 
11654 
11655 
11656 
11657 /* @funcstatic acdSetOutdir ***************************************************
11658 **
11659 ** Using the definition in the ACD file, and any values for the
11660 ** item or its associated qualifiers provided on the command line,
11661 ** prompts the user if necessary (and possible) and
11662 ** sets the actual value for an ACD output directory item.
11663 **
11664 ** Understands all attributes and associated qualifiers for this item type.
11665 **
11666 ** The default value is "." the current directory.
11667 **
11668 ** @param [u] thys [AcdPAcd] ACD item.
11669 ** @return [void]
11670 **
11671 ** @release 2.9.0
11672 ** @@
11673 ******************************************************************************/
11674 
acdSetOutdir(AcdPAcd thys)11675 static void acdSetOutdir(AcdPAcd thys)
11676 {
11677     AjPDirout val;
11678 
11679     AjBool required = ajFalse;
11680     AjBool ok       = ajFalse;
11681 
11682     ajint itry;
11683 
11684     AjBool nullok = ajFalse;
11685     AjBool dopath = ajFalse;
11686     AjBool create = ajFalse;
11687     AjPStr ext = NULL;
11688 
11689     val = NULL;				/* set the default value */
11690 
11691     acdAttrToBool(thys, "fullpath", ajFalse, &dopath);
11692     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
11693     acdAttrToBool(thys, "create", ajFalse, &create);
11694     acdGetValueAssoc(thys, "extension", &ext);
11695 
11696     required = acdIsRequired(thys);
11697     acdReplyInitC(thys, ".", &acdReplyDef);
11698 
11699     acdPromptOutdir(thys);
11700     for(itry=acdPromptTry; itry && !ok; itry--)
11701     {
11702 	ok = ajTrue;	   /* accept the default if nothing changes */
11703 
11704 	ajStrAssignS(&acdReply, acdReplyDef);
11705 
11706 	if(required)
11707 	    acdUserGet(thys, &acdReply);
11708 
11709 	if(ajStrGetLen(acdReply))
11710 	{
11711 	    ajDebug("acdSetOutdir start reply '%S' dopath:%B ok:%B\n",
11712 		    acdReply, dopath,ok);
11713 	    if(dopath)
11714 		ok = ajDirnameFillPath(&acdReply);
11715 
11716 	    ajDebug("acdSetOutdir dir done reply '%S' dopath:%B ok:%B\n",
11717 		    acdReply, dopath,ok);
11718 	    if (ok)
11719 	    {
11720 		val = ajDiroutNewPathExt(acdReply, ext);
11721 
11722 		if (!val)
11723 		    ok = ajFalse;
11724                 else
11725                 {
11726                     if(create)
11727                         ok = ajDiroutOpen(val);
11728                     else
11729                         ok = ajDiroutExists(val);
11730                 }
11731 
11732 	    }
11733 
11734 	    if(!ok)
11735 		acdBadVal(thys, required,
11736 			  "Unable to open output directory '%S'",
11737 			  acdReply);
11738 	}
11739 	else
11740 	    if(!nullok)
11741 	    {
11742 		acdBadVal(thys, required,
11743 			  "Directory path is required");
11744 		ok = ajFalse;
11745 	    }
11746     }
11747     if(!ok)
11748 	acdBadRetry(thys);
11749 
11750     thys->Value = val;
11751     ajStrAssignS(&thys->ValStr, acdReply);
11752 
11753     ajStrDel(&ext);
11754 
11755     return;
11756 }
11757 
11758 
11759 
11760 
11761 /* @func ajAcdGetOutdiscrete **************************************************
11762 **
11763 ** Returns an item of type Outdiscrete as defined in a named ACD item.
11764 ** Called by the application after all ACD values have been set,
11765 ** and simply returns what the ACD item already has.
11766 **
11767 ** @param [r] token [const char*] Text token name
11768 ** @return [AjPOutfile] File object. The file was already opened by
11769 **         acdSetOut so this just returns the pointer.
11770 ** @cre failure to find an item with the right name and type aborts.
11771 **
11772 ** @release 2.9.0
11773 ** @@
11774 ******************************************************************************/
11775 
ajAcdGetOutdiscrete(const char * token)11776 AjPOutfile ajAcdGetOutdiscrete(const char *token)
11777 {
11778     return acdGetValueRef(token, "outdiscrete");
11779 }
11780 
11781 
11782 
11783 
11784 /* @funcstatic acdSetOutdiscrete **********************************************
11785 **
11786 ** Using the definition in the ACD file, and any values for the
11787 ** item or its associated qualifiers provided on the command line,
11788 ** prompts the user if necessary (and possible) and
11789 ** sets the actual value for an ACD outdiscrete item.
11790 **
11791 ** Understands all attributes and associated qualifiers for this item type.
11792 **
11793 ** The default value (if no other available) is a null string, which
11794 ** is invalid.
11795 **
11796 ** Associated qualifiers "-oformat"
11797 ** are stored in the object and applied to the data on output.
11798 **
11799 ** @param [u] thys [AcdPAcd] ACD item.
11800 ** @return [void]
11801 ** @see ajSeqRead
11802 **
11803 ** @release 2.9.0
11804 ** @@
11805 ******************************************************************************/
11806 
acdSetOutdiscrete(AcdPAcd thys)11807 static void acdSetOutdiscrete(AcdPAcd thys)
11808 {
11809     acdSetOutType(thys, "outdiscrete");
11810     return;
11811 }
11812 
11813 
11814 
11815 
11816 /* @func ajAcdGetOutdistance **************************************************
11817 **
11818 ** Returns an item of type Outdistance as defined in a named ACD item.
11819 ** Called by the application after all ACD values have been set,
11820 ** and simply returns what the ACD item already has.
11821 **
11822 ** @param [r] token [const char*] Text token name
11823 ** @return [AjPOutfile] File object. The file was already opened by
11824 **         acdSetOut so this just returns the pointer.
11825 ** @cre failure to find an item with the right name and type aborts.
11826 **
11827 ** @release 2.9.0
11828 ** @@
11829 ******************************************************************************/
11830 
ajAcdGetOutdistance(const char * token)11831 AjPOutfile ajAcdGetOutdistance(const char *token)
11832 {
11833     return acdGetValueRef(token, "outdistance");
11834 }
11835 
11836 
11837 
11838 
11839 /* @funcstatic acdSetOutdistance **********************************************
11840 **
11841 ** Using the definition in the ACD file, and any values for the
11842 ** item or its associated qualifiers provided on the command line,
11843 ** prompts the user if necessary (and possible) and
11844 ** sets the actual value for an ACD outdistance item.
11845 **
11846 ** Understands all attributes and associated qualifiers for this item type.
11847 **
11848 ** The default value (if no other available) is a null string, which
11849 ** is invalid.
11850 **
11851 ** Associated qualifiers "-oformat"
11852 ** are stored in the object and applied to the data on output.
11853 **
11854 ** @param [u] thys [AcdPAcd] ACD item.
11855 ** @return [void]
11856 ** @see ajSeqRead
11857 **
11858 ** @release 2.9.0
11859 ** @@
11860 ******************************************************************************/
11861 
acdSetOutdistance(AcdPAcd thys)11862 static void acdSetOutdistance(AcdPAcd thys)
11863 {
11864     acdSetOutType(thys, "outdistance");
11865     return;
11866 }
11867 
11868 
11869 
11870 
11871 /* @func ajAcdGetOutfile ******************************************************
11872 **
11873 ** Returns an item of type Outfile as defined in a named ACD item.
11874 ** Called by the application after all ACD values have been set,
11875 ** and simply returns what the ACD item already has.
11876 **
11877 ** @param [r] token [const char*] Text token name
11878 ** @return [AjPFile] File object. The file was already opened by
11879 **         acdSetOutfile so this just returns the pointer.
11880 ** @cre failure to find an item with the right name and type aborts.
11881 **
11882 ** @release 1.0.0
11883 ** @@
11884 ******************************************************************************/
11885 
ajAcdGetOutfile(const char * token)11886 AjPFile ajAcdGetOutfile(const char *token)
11887 {
11888     return acdGetValueRef(token, "outfile");
11889 }
11890 
11891 
11892 
11893 
11894 /* @func ajAcdGetOutfileName **************************************************
11895 **
11896 ** Returns the filename of an item of type Outfile as defined in a
11897 ** named ACD item. The file is closed and can be reused. If the file
11898 ** had the append attribute set it still has the original contents.
11899 **
11900 ** Called by the application after all ACD values have been set,
11901 ** and simply returns what the ACD item already has.
11902 **
11903 ** @param [r] token [const char*] Text token name
11904 ** @return [AjPStr] Filename.
11905 ** @cre failure to find an item with the right name and type aborts.
11906 **
11907 ** @release 6.3.0
11908 ** @@
11909 ******************************************************************************/
11910 
ajAcdGetOutfileName(const char * token)11911 AjPStr ajAcdGetOutfileName(const char *token)
11912 {
11913     AjPStr ret;
11914     AjPFile outfile;
11915 
11916     outfile = acdGetValueRef(token, "outfile");
11917 
11918     if(!outfile)
11919         return NULL;
11920 
11921     ret = ajStrNewS(ajFileGetPrintnameS(outfile));
11922 
11923     ajFileClose(&outfile);
11924 
11925     return ret;
11926 }
11927 
11928 
11929 
11930 
11931 /* @funcstatic acdSetOutfile **************************************************
11932 **
11933 ** Using the definition in the ACD file, and any values for the
11934 ** item or its associated qualifiers provided on the command line,
11935 ** prompts the user if necessary (and possible) and
11936 ** sets the actual value for an ACD outfile item.
11937 **
11938 ** Understands all attributes and associated qualifiers for this item type.
11939 **
11940 ** The default value, if stdout or filtering is on is "stdout" for the
11941 ** first file.
11942 **
11943 ** Otherwise an output file name is constructed.
11944 **
11945 ** Various file naming options are defined, but not yet implemented here.
11946 **
11947 ** @param [u] thys [AcdPAcd] ACD item.
11948 ** @return [void]
11949 ** @see ajFileNewOut
11950 **
11951 ** @release 1.0.0
11952 ** @@
11953 ******************************************************************************/
11954 
acdSetOutfile(AcdPAcd thys)11955 static void acdSetOutfile(AcdPAcd thys)
11956 {
11957     AjPFile val;
11958 
11959     AjBool required = ajFalse;
11960     AjBool ok       = ajFalse;
11961 
11962     ajint itry;
11963     AjBool nullok;
11964     AjBool nulldefault;
11965     AjBool append;
11966 
11967     AjPStr name      = NULL;
11968     AjPStr ext       = NULL;
11969     AjPStr dir       = NULL;
11970 
11971     val = NULL;				/* set the default value */
11972 
11973     acdAttrResolve(thys, "name", &name);
11974     acdAttrResolve(thys, "extension", &ext);
11975     acdGetValueAssoc(thys, "odirectory", &dir);
11976 
11977     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
11978     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
11979     acdAttrToBool(thys, "append", ajFalse, &append);
11980     acdOutDirectory(&dir);
11981 
11982     required = acdIsRequired(thys);
11983 
11984     if(nullok && nulldefault)
11985     {
11986 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
11987 	    acdOutFilename(&acdReplyDef, name, ext);
11988 	else				/* leave empty */
11989 	    acdReplyInitC(thys, "", &acdReplyDef);
11990     }
11991     else
11992     {
11993 	acdOutFilename(&acdTmpOutFName, name, ext);
11994 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
11995     }
11996     ajStrDel(&name);
11997     ajStrDel(&ext);
11998 
11999     acdPromptOutfile(thys);
12000 
12001     for(itry=acdPromptTry; itry && !ok; itry--)
12002     {
12003 	ok = ajTrue;	   /* accept the default if nothing changes */
12004 
12005 	ajStrAssignS(&acdReply, acdReplyDef);
12006 
12007 	if(required)
12008 	    acdUserGet(thys, &acdReply);
12009 
12010 	ajStrAssignS(&acdOutFullFName, acdReply);
12011 
12012 	if(ajStrGetLen(acdReply))
12013 	{
12014 	    ajFilenameReplacePathS(&acdOutFullFName, dir);
12015 
12016 	    if(append)
12017 		val = ajFileNewOutappendNameS(acdOutFullFName);
12018 	    else
12019 		val = ajFileNewOutNameS(acdOutFullFName);
12020 
12021 	    if(!val)
12022 	    {
12023 		acdBadVal(thys, required,
12024 			  "Unable to open file '%S' for output",
12025 			  acdOutFullFName);
12026 		ok = ajFalse;
12027 	    }
12028 	}
12029 	else
12030 	    if(!nullok)
12031 	    {
12032 		acdBadVal(thys, required,
12033 			  "Output file is required");
12034 		ok = ajFalse;
12035 	    }
12036     }
12037 
12038     if(!ok)
12039 	acdBadRetry(thys);
12040 
12041     thys->Value = val;
12042     ajStrAssignS(&thys->ValStr, acdOutFullFName);
12043 
12044     ajStrDel(&dir);
12045 
12046     return;
12047 }
12048 
12049 
12050 
12051 
12052 /* @func ajAcdGetOutfreq ******************************************************
12053 **
12054 ** Returns an item of type Outfreq as defined in a named ACD item.
12055 ** Called by the application after all ACD values have been set,
12056 ** and simply returns what the ACD item already has.
12057 **
12058 ** @param [r] token [const char*] Text token name
12059 ** @return [AjPOutfile] File object. The file was already opened by
12060 **         acdSetOut so this just returns the pointer.
12061 ** @cre failure to find an item with the right name and type aborts.
12062 **
12063 ** @release 2.9.0
12064 ** @@
12065 ******************************************************************************/
12066 
ajAcdGetOutfreq(const char * token)12067 AjPOutfile ajAcdGetOutfreq(const char *token)
12068 {
12069     return acdGetValueRef(token, "outfreq");
12070 }
12071 
12072 
12073 
12074 
12075 /* @funcstatic acdSetOutfreq **************************************************
12076 **
12077 ** Using the definition in the ACD file, and any values for the
12078 ** item or its associated qualifiers provided on the command line,
12079 ** prompts the user if necessary (and possible) and
12080 ** sets the actual value for an ACD outfreq item.
12081 **
12082 ** Understands all attributes and associated qualifiers for this item type.
12083 **
12084 ** The default value (if no other available) is a null string, which
12085 ** is invalid.
12086 **
12087 ** Associated qualifiers "-oformat"
12088 ** are stored in the object and applied to the data on output.
12089 **
12090 ** @param [u] thys [AcdPAcd] ACD item.
12091 ** @return [void]
12092 ** @see ajSeqRead
12093 **
12094 ** @release 2.9.0
12095 ** @@
12096 ******************************************************************************/
12097 
acdSetOutfreq(AcdPAcd thys)12098 static void acdSetOutfreq(AcdPAcd thys)
12099 {
12100     acdSetOutType(thys, "outfreq");
12101     return;
12102 }
12103 
12104 
12105 
12106 
12107 /* @func ajAcdGetOutmatrix ****************************************************
12108 **
12109 ** Returns an item of type Outmatrix as defined in a named ACD item.
12110 ** Called by the application after all ACD values have been set,
12111 ** and simply returns what the ACD item already has.
12112 **
12113 ** @param [r] token [const char*] Text token name
12114 ** @return [AjPOutfile] File object. The file was already opened by
12115 **         acdSetOut so this just returns the pointer.
12116 ** @cre failure to find an item with the right name and type aborts.
12117 **
12118 ** @release 2.9.0
12119 ** @@
12120 ******************************************************************************/
12121 
ajAcdGetOutmatrix(const char * token)12122 AjPOutfile ajAcdGetOutmatrix(const char *token)
12123 {
12124     return acdGetValueRef(token, "outmatrix");
12125 }
12126 
12127 
12128 
12129 
12130 /* @funcstatic acdSetOutmatrix ************************************************
12131 **
12132 ** Using the definition in the ACD file, and any values for the
12133 ** item or its associated qualifiers provided on the command line,
12134 ** prompts the user if necessary (and possible) and
12135 ** sets the actual value for an ACD outmatrix item.
12136 **
12137 ** Understands all attributes and associated qualifiers for this item type.
12138 **
12139 ** The default value (if no other available) is a null string, which
12140 ** is invalid.
12141 **
12142 ** Associated qualifiers "-oformat"
12143 ** are stored in the object and applied to the data on output.
12144 **
12145 ** @param [u] thys [AcdPAcd] ACD item.
12146 ** @return [void]
12147 ** @see ajSeqRead
12148 **
12149 ** @release 2.9.0
12150 ** @@
12151 ******************************************************************************/
12152 
acdSetOutmatrix(AcdPAcd thys)12153 static void acdSetOutmatrix(AcdPAcd thys)
12154 {
12155     acdSetOutType(thys, "outmatrix");
12156 
12157     return;
12158 }
12159 
12160 
12161 
12162 
12163 /* @func ajAcdGetOutmatrixf ***************************************************
12164 **
12165 ** Returns an item of type Outmatrixf as defined in a named ACD item.
12166 ** Called by the application after all ACD values have been set,
12167 ** and simply returns what the ACD item already has.
12168 **
12169 ** @param [r] token [const char*] Text token name
12170 ** @return [AjPOutfile] File object. The file was already opened by
12171 **         acdSetOut so this just returns the pointer.
12172 ** @cre failure to find an item with the right name and type aborts.
12173 **
12174 ** @release 2.9.0
12175 ** @@
12176 ******************************************************************************/
12177 
ajAcdGetOutmatrixf(const char * token)12178 AjPOutfile ajAcdGetOutmatrixf(const char *token)
12179 {
12180     return acdGetValueRef(token, "outmatrixf");
12181 }
12182 
12183 
12184 
12185 
12186 /* @funcstatic acdSetOutmatrixf ***********************************************
12187 **
12188 ** Using the definition in the ACD file, and any values for the
12189 ** item or its associated qualifiers provided on the command line,
12190 ** prompts the user if necessary (and possible) and
12191 ** sets the actual value for an ACD outmatrixf item.
12192 **
12193 ** Understands all attributes and associated qualifiers for this item type.
12194 **
12195 ** The default value (if no other available) is a null string, which
12196 ** is invalid.
12197 **
12198 ** Associated qualifiers "-oformat"
12199 ** are stored in the object and applied to the data on output.
12200 **
12201 ** @param [u] thys [AcdPAcd] ACD item.
12202 ** @return [void]
12203 ** @see ajSeqRead
12204 **
12205 ** @release 2.9.0
12206 ** @@
12207 ******************************************************************************/
12208 
acdSetOutmatrixf(AcdPAcd thys)12209 static void acdSetOutmatrixf(AcdPAcd thys)
12210 {
12211     acdSetOutType(thys, "outmatrixf");
12212     return;
12213 }
12214 
12215 
12216 
12217 
12218 /* @func ajAcdGetOutobo *******************************************************
12219 **
12220 ** Returns an item of type Outobo as defined in a named ACD item.
12221 ** Called by the application after all ACD values have been set,
12222 ** and simply returns what the ACD item already has.
12223 **
12224 ** @param [r] token [const char*] Text token name
12225 ** @return [AjPOutfile] File object. The file was already opened by
12226 **         acdSetOut so this just returns the pointer.
12227 ** @cre failure to find an item with the right name and type aborts.
12228 **
12229 ** @release 6.4.0
12230 ** @@
12231 ******************************************************************************/
12232 
ajAcdGetOutobo(const char * token)12233 AjPOutfile ajAcdGetOutobo(const char *token)
12234 {
12235     return acdGetValueRef(token, "outobo");
12236 }
12237 
12238 
12239 
12240 
12241 /* @funcstatic acdSetOutobo ***************************************************
12242 **
12243 ** Using the definition in the ACD file, and any values for the
12244 ** item or its associated qualifiers provided on the command line,
12245 ** prompts the user if necessary (and possible) and
12246 ** sets the actual value for an ACD outobo item.
12247 **
12248 ** Understands all attributes and associated qualifiers for this item type.
12249 **
12250 ** The default value (if no other available) is a null string, which
12251 ** is invalid.
12252 **
12253 ** Associated qualifiers "-oformat"
12254 ** are stored in the object and applied to the data on output.
12255 **
12256 ** @param [u] thys [AcdPAcd] ACD item.
12257 ** @return [void]
12258 ** @see ajSeqRead
12259 **
12260 ** @release 6.4.0
12261 ** @@
12262 ******************************************************************************/
12263 
acdSetOutobo(AcdPAcd thys)12264 static void acdSetOutobo(AcdPAcd thys)
12265 {
12266     acdSetOutType(thys, "outobo");
12267 
12268     return;
12269 }
12270 
12271 
12272 
12273 
12274 /* @func ajAcdGetOutproperties ************************************************
12275 **
12276 ** Returns an item of type Outproperties as defined in a named ACD item.
12277 ** Called by the application after all ACD values have been set,
12278 ** and simply returns what the ACD item already has.
12279 **
12280 ** @param [r] token [const char*] Text token name
12281 ** @return [AjPOutfile] File object. The file was already opened by
12282 **         acdSetOut so this just returns the pointer.
12283 ** @cre failure to find an item with the right name and type aborts.
12284 **
12285 ** @release 2.9.0
12286 ** @@
12287 ******************************************************************************/
12288 
ajAcdGetOutproperties(const char * token)12289 AjPOutfile ajAcdGetOutproperties(const char *token)
12290 {
12291     return acdGetValueRef(token, "outproperties");
12292 }
12293 
12294 
12295 
12296 
12297 /* @funcstatic acdSetOutproperties ********************************************
12298 **
12299 ** Using the definition in the ACD file, and any values for the
12300 ** item or its associated qualifiers provided on the command line,
12301 ** prompts the user if necessary (and possible) and
12302 ** sets the actual value for an ACD outproperties item.
12303 **
12304 ** Understands all attributes and associated qualifiers for this item type.
12305 **
12306 ** The default value (if no other available) is a null string, which
12307 ** is invalid.
12308 **
12309 ** Associated qualifiers "-oformat"
12310 ** are stored in the object and applied to the data on output.
12311 **
12312 ** @param [u] thys [AcdPAcd] ACD item.
12313 ** @return [void]
12314 ** @see ajSeqRead
12315 **
12316 ** @release 2.9.0
12317 ** @@
12318 ******************************************************************************/
12319 
acdSetOutproperties(AcdPAcd thys)12320 static void acdSetOutproperties(AcdPAcd thys)
12321 {
12322     acdSetOutType(thys, "properties");
12323 
12324     return;
12325 }
12326 
12327 
12328 
12329 
12330 /* @func ajAcdGetOutrefseq ****************************************************
12331 **
12332 ** Returns an item of type Outrefseq as defined in a named ACD item.
12333 ** Called by the application after all ACD values have been set,
12334 ** and simply returns what the ACD item already has.
12335 **
12336 ** @param [r] token [const char*] Text token name
12337 ** @return [AjPOutfile] File object. The file was already opened by
12338 **         acdSetOut so this just returns the pointer.
12339 ** @cre failure to find an item with the right name and type aborts.
12340 **
12341 ** @release 6.5.0
12342 ** @@
12343 ******************************************************************************/
12344 
ajAcdGetOutrefseq(const char * token)12345 AjPOutfile ajAcdGetOutrefseq(const char *token)
12346 {
12347     return acdGetValueRef(token, "outrefseq");
12348 }
12349 
12350 
12351 
12352 
12353 /* @funcstatic acdSetOutrefseq **********************************************
12354 **
12355 ** Using the definition in the ACD file, and any values for the
12356 ** item or its associated qualifiers provided on the command line,
12357 ** prompts the user if necessary (and possible) and
12358 ** sets the actual value for an ACD outrefseq item.
12359 **
12360 ** Understands all attributes and associated qualifiers for this item type.
12361 **
12362 ** The default value (if no other available) is a null string, which
12363 ** is invalid.
12364 **
12365 ** Associated qualifiers "-oformat"
12366 ** are stored in the object and applied to the data on output.
12367 **
12368 ** @param [u] thys [AcdPAcd] ACD item.
12369 ** @return [void]
12370 **
12371 ** @release 6.5.0
12372 ** @@
12373 ******************************************************************************/
12374 
acdSetOutrefseq(AcdPAcd thys)12375 static void acdSetOutrefseq(AcdPAcd thys)
12376 {
12377     acdSetOutType(thys, "outrefseq");
12378 
12379     return;
12380 }
12381 
12382 
12383 
12384 
12385 /* @func ajAcdGetOutresource **************************************************
12386 **
12387 ** Returns an item of type Outresource as defined in a named ACD item.
12388 ** Called by the application after all ACD values have been set,
12389 ** and simply returns what the ACD item already has.
12390 **
12391 ** @param [r] token [const char*] Text token name
12392 ** @return [AjPOutfile] File object. The file was already opened by
12393 **         acdSetOut so this just returns the pointer.
12394 ** @cre failure to find an item with the right name and type aborts.
12395 **
12396 ** @release 6.4.0
12397 ** @@
12398 ******************************************************************************/
12399 
ajAcdGetOutresource(const char * token)12400 AjPOutfile ajAcdGetOutresource(const char *token)
12401 {
12402     return acdGetValueRef(token, "outresource");
12403 }
12404 
12405 
12406 
12407 
12408 /* @funcstatic acdSetOutresource **********************************************
12409 **
12410 ** Using the definition in the ACD file, and any values for the
12411 ** item or its associated qualifiers provided on the command line,
12412 ** prompts the user if necessary (and possible) and
12413 ** sets the actual value for an ACD data resource output item.
12414 **
12415 ** Understands all attributes and associated qualifiers for this item type.
12416 **
12417 ** The default value (if no other available) is a null string, which
12418 ** is invalid.
12419 **
12420 ** Associated qualifiers "-oformat"
12421 ** are stored in the object and applied to the data on output.
12422 **
12423 ** @param [u] thys [AcdPAcd] ACD item.
12424 ** @return [void]
12425 ** @see ajSeqRead
12426 **
12427 ** @release 6.4.0
12428 ** @@
12429 ******************************************************************************/
12430 
acdSetOutresource(AcdPAcd thys)12431 static void acdSetOutresource(AcdPAcd thys)
12432 {
12433     acdSetOutType(thys, "outresource");
12434 
12435     return;
12436 }
12437 
12438 
12439 
12440 
12441 /* @func ajAcdGetOutscop ******************************************************
12442 **
12443 ** Returns an item of type Outscop as defined in a named ACD item.
12444 ** Called by the application after all ACD values have been set,
12445 ** and simply returns what the ACD item already has.
12446 **
12447 ** @param [r] token [const char*] Text token name
12448 ** @return [AjPOutfile] File object. The file was already opened by
12449 **         acdSetOut so this just returns the pointer.
12450 ** @cre failure to find an item with the right name and type aborts.
12451 **
12452 ** @release 2.9.0
12453 ** @@
12454 ******************************************************************************/
12455 
ajAcdGetOutscop(const char * token)12456 AjPOutfile ajAcdGetOutscop(const char *token)
12457 {
12458     return acdGetValueRef(token, "outscop");
12459 }
12460 
12461 
12462 
12463 
12464 /* @funcstatic acdSetOutscop **************************************************
12465 **
12466 ** Using the definition in the ACD file, and any values for the
12467 ** item or its associated qualifiers provided on the command line,
12468 ** prompts the user if necessary (and possible) and
12469 ** sets the actual value for an ACD outscop item.
12470 **
12471 ** Understands all attributes and associated qualifiers for this item type.
12472 **
12473 ** The default value (if no other available) is a null string, which
12474 ** is invalid.
12475 **
12476 ** Associated qualifiers "-oformat"
12477 ** are stored in the object and applied to the data on output.
12478 **
12479 ** @param [u] thys [AcdPAcd] ACD item.
12480 ** @return [void]
12481 ** @see ajSeqRead
12482 **
12483 ** @release 2.9.0
12484 ** @@
12485 ******************************************************************************/
12486 
acdSetOutscop(AcdPAcd thys)12487 static void acdSetOutscop(AcdPAcd thys)
12488 {
12489     acdSetOutType(thys, "outscop");
12490 
12491     return;
12492 }
12493 
12494 
12495 
12496 
12497 /* @func ajAcdGetOuttaxon *****************************************************
12498 **
12499 ** Returns an item of type Outtaxon as defined in a named ACD item.
12500 ** Called by the application after all ACD values have been set,
12501 ** and simply returns what the ACD item already has.
12502 **
12503 ** @param [r] token [const char*] Text token name
12504 ** @return [AjPOutfile] File object. The file was already opened by
12505 **         acdSetOut so this just returns the pointer.
12506 ** @cre failure to find an item with the right name and type aborts.
12507 **
12508 ** @release 6.4.0
12509 ** @@
12510 ******************************************************************************/
12511 
ajAcdGetOuttaxon(const char * token)12512 AjPOutfile ajAcdGetOuttaxon(const char *token)
12513 {
12514     return acdGetValueRef(token, "outtaxon");
12515 }
12516 
12517 
12518 
12519 
12520 /* @funcstatic acdSetOuttaxon *************************************************
12521 **
12522 ** Using the definition in the ACD file, and any values for the
12523 ** item or its associated qualifiers provided on the command line,
12524 ** prompts the user if necessary (and possible) and
12525 ** sets the actual value for an ACD outtaxon item.
12526 **
12527 ** Understands all attributes and associated qualifiers for this item type.
12528 **
12529 ** The default value (if no other available) is a null string, which
12530 ** is invalid.
12531 **
12532 ** Associated qualifiers "-oformat"
12533 ** are stored in the object and applied to the data on output.
12534 **
12535 ** @param [u] thys [AcdPAcd] ACD item.
12536 ** @return [void]
12537 ** @see ajSeqRead
12538 **
12539 ** @release 6.4.0
12540 ** @@
12541 ******************************************************************************/
12542 
acdSetOuttaxon(AcdPAcd thys)12543 static void acdSetOuttaxon(AcdPAcd thys)
12544 {
12545     acdSetOutType(thys, "outtaxon");
12546 
12547     return;
12548 }
12549 
12550 
12551 
12552 
12553 /* @func ajAcdGetOuttext ******************************************************
12554 **
12555 ** Returns an item of type Outtext as defined in a named ACD item.
12556 ** Called by the application after all ACD values have been set,
12557 ** and simply returns what the ACD item already has.
12558 **
12559 ** @param [r] token [const char*] Text token name
12560 ** @return [AjPOutfile] File object. The file was already opened by
12561 **         acdSetOut so this just returns the pointer.
12562 ** @cre failure to find an item with the right name and type aborts.
12563 **
12564 ** @release 6.4.0
12565 ** @@
12566 ******************************************************************************/
12567 
ajAcdGetOuttext(const char * token)12568 AjPOutfile ajAcdGetOuttext(const char *token)
12569 {
12570     return acdGetValueRef(token, "outtext");
12571 }
12572 
12573 
12574 
12575 
12576 /* @funcstatic acdSetOuttext **************************************************
12577 **
12578 ** Using the definition in the ACD file, and any values for the
12579 ** item or its associated qualifiers provided on the command line,
12580 ** prompts the user if necessary (and possible) and
12581 ** sets the actual value for an ACD outtext item.
12582 **
12583 ** Understands all attributes and associated qualifiers for this item type.
12584 **
12585 ** The default value (if no other available) is a null string, which
12586 ** is invalid.
12587 **
12588 ** Associated qualifiers "-oformat"
12589 ** are stored in the object and applied to the data on output.
12590 **
12591 ** @param [u] thys [AcdPAcd] ACD item.
12592 ** @return [void]
12593 ** @see ajSeqRead
12594 **
12595 ** @release 6.4.0
12596 ** @@
12597 ******************************************************************************/
12598 
acdSetOuttext(AcdPAcd thys)12599 static void acdSetOuttext(AcdPAcd thys)
12600 {
12601     acdSetOutType(thys, "outtext");
12602 
12603     return;
12604 }
12605 
12606 
12607 
12608 
12609 /* @func ajAcdGetOuttree ******************************************************
12610 **
12611 ** Returns an item of type Outtree as defined in a named ACD item.
12612 ** Called by the application after all ACD values have been set,
12613 ** and simply returns what the ACD item already has.
12614 **
12615 ** @param [r] token [const char*] Text token name
12616 ** @return [AjPOutfile] File object. The file was already opened by
12617 **         acdSetOut so this just returns the pointer.
12618 ** @cre failure to find an item with the right name and type aborts.
12619 **
12620 ** @release 2.9.0
12621 ** @@
12622 ******************************************************************************/
12623 
ajAcdGetOuttree(const char * token)12624 AjPOutfile ajAcdGetOuttree(const char *token)
12625 {
12626     return acdGetValueRef(token, "outtree");
12627 }
12628 
12629 
12630 
12631 
12632 /* @funcstatic acdSetOuttree **************************************************
12633 **
12634 ** Using the definition in the ACD file, and any values for the
12635 ** item or its associated qualifiers provided on the command line,
12636 ** prompts the user if necessary (and possible) and
12637 ** sets the actual value for an ACD outtree item.
12638 **
12639 ** Understands all attributes and associated qualifiers for this item type.
12640 **
12641 ** The default value (if no other available) is a null string, which
12642 ** is invalid.
12643 **
12644 ** Associated qualifiers "-oformat"
12645 ** are stored in the object and applied to the data on output.
12646 **
12647 ** @param [u] thys [AcdPAcd] ACD item.
12648 ** @return [void]
12649 ** @see ajSeqRead
12650 **
12651 ** @release 2.9.0
12652 ** @@
12653 ******************************************************************************/
12654 
acdSetOuttree(AcdPAcd thys)12655 static void acdSetOuttree(AcdPAcd thys)
12656 {
12657     acdSetOutType(thys, "outtree");
12658 
12659     return;
12660 }
12661 
12662 
12663 
12664 
12665 /* @func ajAcdGetOuturl *******************************************************
12666 **
12667 ** Returns an item of type Outurl as defined in a named ACD item.
12668 ** Called by the application after all ACD values have been set,
12669 ** and simply returns what the ACD item already has.
12670 **
12671 ** @param [r] token [const char*] Text token name
12672 ** @return [AjPOutfile] File object. The file was already opened by
12673 **         acdSetOut so this just returns the pointer.
12674 ** @cre failure to find an item with the right name and type aborts.
12675 **
12676 ** @release 6.4.0
12677 ** @@
12678 ******************************************************************************/
12679 
ajAcdGetOuturl(const char * token)12680 AjPOutfile ajAcdGetOuturl(const char *token)
12681 {
12682     return acdGetValueRef(token, "outurl");
12683 }
12684 
12685 
12686 
12687 
12688 /* @funcstatic acdSetOuturl ***************************************************
12689 **
12690 ** Using the definition in the ACD file, and any values for the
12691 ** item or its associated qualifiers provided on the command line,
12692 ** prompts the user if necessary (and possible) and
12693 ** sets the actual value for an ACD outurl item.
12694 **
12695 ** Understands all attributes and associated qualifiers for this item type.
12696 **
12697 ** The default value (if no other available) is a null string, which
12698 ** is invalid.
12699 **
12700 ** Associated qualifiers "-oformat"
12701 ** are stored in the object and applied to the data on output.
12702 **
12703 ** @param [u] thys [AcdPAcd] ACD item.
12704 ** @return [void]
12705 **
12706 ** @release 6.4.0
12707 ** @@
12708 ******************************************************************************/
12709 
acdSetOuturl(AcdPAcd thys)12710 static void acdSetOuturl(AcdPAcd thys)
12711 {
12712     acdSetOutType(thys, "outurl");
12713 
12714     return;
12715 }
12716 
12717 
12718 
12719 
12720 /* @func ajAcdGetOutvariation *************************************************
12721 **
12722 ** Returns an item of type Outvariation as defined in a named ACD item.
12723 ** Called by the application after all ACD values have been set,
12724 ** and simply returns what the ACD item already has.
12725 **
12726 ** @param [r] token [const char*] Text token name
12727 ** @return [AjPOutfile] File object. The file was already opened by
12728 **         acdSetOut so this just returns the pointer.
12729 ** @cre failure to find an item with the right name and type aborts.
12730 **
12731 ** @release 6.4.0
12732 ** @@
12733 ******************************************************************************/
12734 
ajAcdGetOutvariation(const char * token)12735 AjPOutfile ajAcdGetOutvariation(const char *token)
12736 {
12737     return acdGetValueRef(token, "outvariation");
12738 }
12739 
12740 
12741 
12742 
12743 /* @funcstatic acdSetOutvariation *********************************************
12744 **
12745 ** Using the definition in the ACD file, and any values for the
12746 ** item or its associated qualifiers provided on the command line,
12747 ** prompts the user if necessary (and possible) and
12748 ** sets the actual value for an ACD outvariation item.
12749 **
12750 ** Understands all attributes and associated qualifiers for this item type.
12751 **
12752 ** The default value (if no other available) is a null string, which
12753 ** is invalid.
12754 **
12755 ** Associated qualifiers "-oformat"
12756 ** are stored in the object and applied to the data on output.
12757 **
12758 ** @param [u] thys [AcdPAcd] ACD item.
12759 ** @return [void]
12760 **
12761 ** @release 6.4.0
12762 ** @@
12763 ******************************************************************************/
12764 
acdSetOutvariation(AcdPAcd thys)12765 static void acdSetOutvariation(AcdPAcd thys)
12766 {
12767     acdSetOutType(thys, "outvariation");
12768 
12769     return;
12770 }
12771 
12772 
12773 
12774 
12775 /* @func ajAcdGetOutxml *******************************************************
12776 **
12777 ** Returns an item of type Outxml as defined in a named ACD item.
12778 ** Called by the application after all ACD values have been set,
12779 ** and simply returns what the ACD item already has.
12780 **
12781 ** @param [r] token [const char*] Text token name
12782 ** @return [AjPOutfile] File object. The file was already opened by
12783 **         acdSetOut so this just returns the pointer.
12784 ** @cre failure to find an item with the right name and type aborts.
12785 **
12786 ** @release 6.6.0
12787 ** @@
12788 ******************************************************************************/
12789 
ajAcdGetOutxml(const char * token)12790 AjPOutfile ajAcdGetOutxml(const char *token)
12791 {
12792     return acdGetValueRef(token, "outxml");
12793 }
12794 
12795 
12796 
12797 
12798 /* @funcstatic acdSetOutxml ***************************************************
12799 **
12800 ** Using the definition in the ACD file, and any values for the
12801 ** item or its associated qualifiers provided on the command line,
12802 ** prompts the user if necessary (and possible) and
12803 ** sets the actual value for an ACD outxml item.
12804 **
12805 ** Understands all attributes and associated qualifiers for this item type.
12806 **
12807 ** The default value (if no other available) is a null string, which
12808 ** is invalid.
12809 **
12810 ** Associated qualifiers "-oformat"
12811 ** are stored in the object and applied to the data on output.
12812 **
12813 ** @param [u] thys [AcdPAcd] ACD item.
12814 ** @return [void]
12815 **
12816 ** @release 6.6.0
12817 ** @@
12818 ******************************************************************************/
12819 
acdSetOutxml(AcdPAcd thys)12820 static void acdSetOutxml(AcdPAcd thys)
12821 {
12822     acdSetOutType(thys, "outxml");
12823 
12824     return;
12825 }
12826 
12827 
12828 
12829 
12830 /* @func ajAcdGetPattern ******************************************************
12831 **
12832 ** Returns an item of type Pattern as defined in a named ACD item.
12833 ** Called by the application after all ACD values have been set,
12834 ** and simply returns what the ACD item already has.
12835 **
12836 ** @param [r] token [const char*] Text token name
12837 ** @return [AjPPatlistSeq] Compiled pattern list of sequence patterns.
12838 **                     The original pattern string is available
12839 **                     through a call to ajAcdGetValue
12840 ** @cre failure to find an item with the right name and type aborts.
12841 **
12842 ** @release 4.0.0
12843 ** @@
12844 ******************************************************************************/
12845 
ajAcdGetPattern(const char * token)12846 AjPPatlistSeq ajAcdGetPattern(const char *token)
12847 {
12848     return acdGetValueRef(token, "pattern");
12849 }
12850 
12851 
12852 
12853 
12854 /* @funcstatic acdSetPattern **************************************************
12855 **
12856 ** Using the definition in the ACD file, and any values for the
12857 ** item or its associated qualifiers provided on the command line,
12858 ** prompts the user if necessary (and possible) and
12859 ** sets the actual value for an ACD sequence pattern item.
12860 **
12861 ** Understands all attributes and associated qualifiers for this item type.
12862 **
12863 ** The default value (if no other is available) is NULL.
12864 **
12865 ** Attributes for minimum and maximum length are applied with error
12866 ** messages if exceeded.
12867 **
12868 ** @param [u] thys [AcdPAcd] ACD item.
12869 ** @return [void]
12870 **
12871 ** @release 4.0.0
12872 ** @@
12873 ******************************************************************************/
12874 
acdSetPattern(AcdPAcd thys)12875 static void acdSetPattern(AcdPAcd thys)
12876 {
12877     AjPPatlistSeq val = NULL;
12878 
12879     AjBool required = ajFalse;
12880     AjBool ok       = ajFalse;
12881 
12882     AjBool upper;
12883     AjBool lower;
12884     ajint itry;
12885 
12886     ajint minlen;
12887     ajint maxlen;
12888     ajint maxsize;
12889     ajint len;
12890     AjPStr type = NULL;
12891     AjPStr patname = NULL;
12892     AjPStr fmt = NULL;
12893     ajint mismatch = 0;
12894     AjBool isprotein = ajTrue;
12895 
12896     acdAttrToInt(thys, "minlength", 1, &minlen);
12897 
12898     acdAttrToInt(thys, "maxlength", INT_MAX, &maxlen);
12899     acdAttrToBool(thys, "upper", ajFalse, &upper);
12900     acdAttrToBool(thys, "lower", ajFalse, &lower);
12901     acdAttrToStr(thys, "type", "protein", &type);
12902     acdAttrToInt(thys, "maxsize", INT_MAX, &maxsize);
12903     acdQualToInt(thys, "pmismatch", 0, &mismatch, &acdTmpStr);
12904     acdGetValueAssoc(thys, "pname", &patname);
12905     acdGetValueAssoc(thys, "pformat", &fmt);
12906     ajStrFmtLower(&type);
12907 
12908     if(ajStrGetCharFirst(type) != 'p')
12909 	isprotein = ajFalse;
12910 
12911     if(mismatch < 0)
12912 	mismatch = 0;
12913 
12914     ajDebug("acdSetPattern name '%S' mismatch %d type '%S' protein %B\n",
12915 	    patname, mismatch, type, isprotein);
12916 
12917     required = acdIsRequired(thys);
12918     acdReplyInitC(thys, "", &acdReplyDef);
12919 
12920     for(itry=acdPromptTry; itry && !ok; itry--)
12921     {
12922 	ok = ajTrue;	   /* accept the default if nothing changes */
12923 
12924 	if(val)
12925 	    ajPatlistSeqDel(&val);
12926 
12927 	ajStrAssignS(&acdReply, acdReplyDef);
12928 
12929 	if(required)
12930 	    acdUserGet(thys, &acdReply);
12931 
12932 	len = ajStrGetLen(acdReply);
12933 
12934 	if(len < minlen)
12935 	{
12936 	    acdBadVal(thys, required,
12937 		      "Too short (%S) - minimum length is %d characters",
12938 		      thys->Name, minlen);
12939 	    ok = ajFalse;
12940 	}
12941 
12942 	if(len > maxlen)
12943 	{
12944 	    acdBadVal(thys, required,
12945 		      "Too long (%S) - maximum length is %d characters",
12946 		      thys->Name,maxlen);
12947 	    ok = ajFalse;
12948 	}
12949 
12950 	if(ok)
12951 	    val = ajPatlistSeqRead(acdReply, patname, fmt,
12952 				   isprotein, mismatch);
12953 
12954 	if(ok && !val)
12955 	{
12956 	    acdBadVal(thys, required,
12957 		      "Bad pattern definition:\n   '%S'",
12958 		      acdReply);
12959 	    ok = ajFalse;
12960 	}
12961     }
12962 
12963     if(!ok)
12964 	acdBadRetry(thys);
12965 
12966     ajStrDel(&patname);
12967     ajStrDel(&fmt);
12968     ajStrDel(&type);
12969 
12970     /* regexps have special set attributes the same as strings */
12971 
12972     thys->SAttr = acdAttrListCount(acdCalcRegexp);
12973     thys->SetAttr = &acdCalcRegexp[0];
12974     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
12975 
12976     ajStrFromInt(&thys->SetStr[0], ajStrGetLen(acdReply));
12977 
12978     thys->Value = val;
12979     ajStrAssignS(&thys->ValStr, acdReply);
12980 
12981     return;
12982 }
12983 
12984 
12985 
12986 
12987 /* @func ajAcdGetProperties ***************************************************
12988 **
12989 ** Returns an item of type Properties as defined in a named ACD item.
12990 ** Called by the application after all ACD values have been set,
12991 ** and simply returns what the ACD item already has.
12992 **
12993 ** @param [r] token [const char*] Text token name
12994 ** @return [AjPPhyloProp] Properties array. The data was already set by
12995 **         acdSetProperties so this just returns the pointer.
12996 ** @cre failure to find an item with the right name and type aborts.
12997 **
12998 ** @release 2.8.0
12999 ** @@
13000 ******************************************************************************/
13001 
ajAcdGetProperties(const char * token)13002 AjPPhyloProp ajAcdGetProperties(const char *token)
13003 {
13004     return acdGetValueRef(token, "properties");
13005 }
13006 
13007 
13008 
13009 
13010 /* @funcstatic acdSetProperties ***********************************************
13011 **
13012 ** Using the definition in the ACD file, and any values for the
13013 ** item or its associated qualifiers provided on the command line,
13014 ** prompts the user if necessary (and possible) and
13015 ** sets the actual value for an ACD proerties file item.
13016 **
13017 ** Understands all attributes and associated qualifiers for this item type.
13018 **
13019 ** The default value (if no other is available) is an empty string.
13020 **
13021 ** Attributes for length and maximum property character are applied with error
13022 ** messages if exceeded.
13023 **
13024 ** @param [u] thys [AcdPAcd] ACD item.
13025 ** @return [void]
13026 **
13027 ** @release 2.8.0
13028 ** @@
13029 ******************************************************************************/
13030 
acdSetProperties(AcdPAcd thys)13031 static void acdSetProperties(AcdPAcd thys)
13032 {
13033     AjPPhyloProp val;
13034 
13035     AjBool required = ajFalse;
13036     AjBool ok       = ajFalse;
13037 
13038     AjPStr infname  = NULL;
13039     ajint itry;
13040 
13041     AjBool nullok = ajFalse;
13042     ajint size;
13043     ajint len;
13044     AjPStr propchars = NULL;
13045 
13046     val = NULL;
13047 
13048     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
13049     acdAttrToInt(thys, "length", 0, &len);
13050     acdAttrToInt(thys, "size", 1, &size);
13051     acdAttrToStr(thys, "characters", "", &propchars);
13052 
13053     ajDebug("acdSetProperties len: %d size: %d\n", len, size);
13054 
13055     acdInFilename(&infname);
13056     required = acdIsRequired(thys);
13057     acdReplyInitS(thys, infname, &acdReplyDef);
13058     acdPromptInfile(thys);
13059     ajStrDel(&infname);
13060 
13061     for(itry=acdPromptTry; itry && !ok; itry--)
13062     {
13063 	ok = ajTrue;	   /* accept the default if nothing changes */
13064 
13065 	ajStrAssignS(&acdReply, acdReplyDef);
13066 
13067 	if(required)
13068 	    acdUserGet(thys, &acdReply);
13069 
13070 	if(ajStrGetLen(acdReply))
13071 	{
13072 	    val = ajPhyloPropRead(acdReply, propchars, len, size);
13073 
13074 	    if(!val)
13075 	    {
13076 		acdBadVal(thys, required,
13077 			  "Unable to read properties from '%S'",
13078 			  acdReply);
13079 		ok = ajFalse;
13080 	    }
13081 	}
13082 	else
13083 	    if(!nullok)
13084 	    {
13085 		acdBadVal(thys, required,
13086 			  "Input file is required");
13087 		ok = ajFalse;
13088 	    }
13089     }
13090 
13091     if(!ok)
13092 	acdBadRetry(thys);
13093     acdInFileSave(acdReply, NULL, ajTrue);
13094 
13095     /* properties have special set attributes */
13096 
13097     thys->SAttr = acdAttrListCount(acdCalcProperties);
13098     thys->SetAttr = &acdCalcProperties[0];
13099     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
13100 
13101     if(val)
13102     {
13103 	ajStrFromInt(&thys->SetStr[0],val->Len); /* string length */
13104 	ajStrFromInt(&thys->SetStr[1],val->Size); /* string count */
13105  	ajStrAssignS(&thys->ValStr, val->Str[0]);
13106     }
13107     else
13108     {
13109 	ajStrFromInt(&thys->SetStr[0],0); /* string length */
13110 	ajStrFromInt(&thys->SetStr[1],0); /* string count */
13111 	ajStrAssignClear(&thys->ValStr);
13112     }
13113 
13114     thys->Value = val;
13115     ajStrDel(&propchars);
13116 
13117     return;
13118 }
13119 
13120 
13121 
13122 
13123 /* @func ajAcdGetRange ********************************************************
13124 **
13125 ** Returns an item of type Range as defined in a named ACD item.
13126 ** Called by the application after all ACD values have been set,
13127 ** and simply returns what the ACD item already has.
13128 **
13129 ** @param [r] token [const char*] Text token name
13130 ** @return [AjPRange] Range object.
13131 ** @cre failure to find an item with the right name and type aborts.
13132 **
13133 ** @release 1.0.0
13134 ** @@
13135 ******************************************************************************/
13136 
ajAcdGetRange(const char * token)13137 AjPRange ajAcdGetRange(const char *token)
13138 {
13139     return acdGetValueRef(token, "range");
13140 }
13141 
13142 
13143 
13144 
13145 /* @funcstatic acdSetRange ****************************************************
13146 **
13147 ** Using the definition in the ACD file, and any values for the
13148 ** item or its associated qualifiers provided on the command line,
13149 ** prompts the user if necessary (and possible) and
13150 ** sets the actual value for an ACD range item.
13151 **
13152 ** Understands all attributes and associated qualifiers for this item type.
13153 **
13154 ** @param [u] thys [AcdPAcd] ACD item.
13155 ** @return [void]
13156 **
13157 ** @release 1.0.0
13158 ** @@
13159 ******************************************************************************/
13160 
acdSetRange(AcdPAcd thys)13161 static void acdSetRange(AcdPAcd thys)
13162 {
13163     AjPRange val = NULL;
13164 
13165     AjBool required = ajFalse;
13166     AjBool ok       = ajFalse;
13167 
13168     AjBool warnrange;
13169     AjBool failrange;
13170 
13171     ajint itry;
13172 
13173     ajuint imin;
13174     ajuint imax;
13175     ajuint isize;
13176     ajuint iminsize;
13177     AjPStr failmsg = NULL;
13178 
13179     acdRangeTestCalc(thys);
13180 
13181     acdAttrToUint(thys, "minimum", 1, &imin);
13182     acdLog("minimum: %d\n", imin);
13183 
13184     acdAttrToUint(thys, "maximum", UINT_MAX, &imax);
13185     acdLog("maximum: %d\n", imax);
13186 
13187     acdAttrToUint(thys, "minsize", 0, &iminsize);
13188     acdLog("minsize: %d\n", iminsize);
13189 
13190     acdAttrToUint(thys, "size", 0, &isize);
13191     acdLog("size: %d\n", isize);
13192 
13193     acdAttrToBool(thys, "failrange", ajTrue, &failrange);
13194     acdLog("failrange: %B\n", failrange);
13195 
13196     acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange);
13197     acdLog("warnrange: %B\n", warnrange);
13198 
13199     if(failrange && (imin > imax))
13200     {
13201         acdAttrResolve(thys, "rangemessage", &failmsg);
13202         if(ajStrGetLen(failmsg))
13203             acdErrorAcd(thys, "Invalid range: %S", failmsg);
13204         else
13205             acdErrorAcd(thys,
13206                         "Invalid range: "
13207                         "minimum value %d more than maximum %d",
13208                         imin, imax);
13209     }
13210 
13211     required = acdIsRequired(thys);
13212     acdReplyInitC(thys, "", &acdReplyDef);
13213 
13214     for(itry=acdPromptTry; itry && !ok; itry--)
13215     {
13216 	ok = ajTrue;	   /* accept the default if nothing changes */
13217 
13218 	ajStrAssignS(&acdReply, acdReplyDef);
13219 
13220 	if(required)
13221 	    acdUserGet(thys, &acdReply);
13222 
13223 	val = ajRangeNewStringLimits(acdReply, imin, imax, iminsize, isize);
13224 
13225 	if(!val)
13226 	{
13227 	    acdBadVal(thys, required,
13228 		      "Bad range specification '%S'", acdReply);
13229 	    ok = ajFalse;
13230 	}
13231     }
13232 
13233     if(!ok)
13234 	acdBadRetry(thys);
13235 
13236     thys->Value = val;
13237     ajStrAssignS(&thys->ValStr, acdReply);
13238 
13239     return;
13240 }
13241 
13242 
13243 
13244 
13245 /* @func ajAcdGetRefseq *******************************************************
13246 **
13247 ** Returns an item of type reference sequence as defined in a named ACD item.
13248 ** Called by the application after all ACD values have been set,
13249 ** and simply returns what the ACD item already has.
13250 **
13251 ** @param [r] token [const char*] Text token name
13252 ** @return [AjPRefseq] Reference sequence object
13253 ** @cre failure to find an item with the right name and type aborts.
13254 **
13255 ** @release 6.5.0
13256 ** @@
13257 ******************************************************************************/
13258 
ajAcdGetRefseq(const char * token)13259 AjPRefseq ajAcdGetRefseq(const char *token)
13260 {
13261     AjPRefseq val = acdGetValueRef(token, "refseq");
13262 
13263     return val;
13264 }
13265 
13266 
13267 
13268 
13269 /* @funcstatic acdSetRefseq ***************************************************
13270 **
13271 ** Using the definition in the ACD file, and any values for the
13272 ** item or its associated qualifiers provided on the command line,
13273 ** prompts the user if necessary (and possible) and
13274 ** sets the actual value for an ACD reference sequence input
13275 **
13276 ** Understands all attributes and associated qualifiers for this item type.
13277 **
13278 ** @param [u] thys [AcdPAcd] ACD item.
13279 ** @return [void]
13280 **
13281 ** @release 6.5.0
13282 ** @@
13283 ******************************************************************************/
13284 
acdSetRefseq(AcdPAcd thys)13285 static void acdSetRefseq(AcdPAcd thys)
13286 {
13287     AjPRefseq val;
13288     AjPRefseqin refseqin;
13289 
13290     AjBool required = ajFalse;
13291     AjBool ok       = ajFalse;
13292     AjBool nullok   = ajFalse;
13293     ajint itry;
13294 
13295     AjPStr infname = NULL;
13296 
13297     val = ajRefseqNew();        /* set the default value */
13298     refseqin = ajRefseqinNew();
13299 
13300     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
13301 
13302     acdInFilename(&infname);
13303     required = acdIsRequired(thys);
13304     acdReplyInitS(thys, infname, &acdReplyDef);
13305     ajStrDel(&infname);
13306 
13307     acdAttrToBool(thys, "entry", ajFalse, &refseqin->Input->Text);
13308 
13309     for(itry=acdPromptTry; itry && !ok; itry--)
13310     {
13311 	ok = ajTrue;	   /* accept the default if nothing changes */
13312 
13313 	ajStrAssignS(&acdReply, acdReplyDef);
13314 
13315 	if(required)
13316 	    acdUserGet(thys, &acdReply);
13317 
13318 	if(!ajStrGetLen(acdReply) && nullok)
13319         {
13320             ajRefseqinDel(&refseqin);
13321 	    break;
13322 	}
13323 
13324 	ajRefseqinQryS(refseqin, acdReply);
13325 
13326 	acdGetValueAssoc(thys, "iformat", &refseqin->Input->Formatstr);
13327 	acdGetValueAssoc(thys, "iquery", &refseqin->Input->QryFields);
13328 	acdQualToLong(thys, "ioffset", 0L, &refseqin->Input->Fpos,
13329                       &acdTmpStr);
13330 
13331         ok = ajRefseqinRead(refseqin, val);
13332     }
13333 
13334     if(!ok)
13335 	acdBadRetry(thys);
13336 
13337     acdInFileSave(acdReply, ajRefseqGetId(val), ajTrue);
13338 
13339     thys->Value = val;
13340     ajStrAssignS(&thys->ValStr, acdReply);
13341 
13342     ajRefseqinDel(&refseqin);
13343 
13344     return;
13345 }
13346 
13347 
13348 
13349 
13350 /* @func ajAcdGetRegexp *******************************************************
13351 **
13352 ** Returns an item of type Regexp as defined in a named ACD item.
13353 ** Called by the application after all ACD values have been set,
13354 ** and simply returns what the ACD item already has.
13355 **
13356 ** @param [r] token [const char*] Text token name
13357 ** @return [AjPPatlistRegex] Compiled regular expression pattern.
13358 **                            The original pattern string is available
13359 **                            through a call to ajAcdGetValue
13360 ** @cre failure to find an item with the right name and type aborts.
13361 **
13362 ** @release 1.0.0
13363 ** @@
13364 ******************************************************************************/
13365 
ajAcdGetRegexp(const char * token)13366 AjPPatlistRegex ajAcdGetRegexp(const char *token)
13367 {
13368     return acdGetValueRef(token, "regexp");
13369 }
13370 
13371 
13372 
13373 
13374 /* @func ajAcdGetRegexpSingle *************************************************
13375 **
13376 ** Returns an item of type Regexp as defined in a named ACD item.
13377 ** Called by the application after all ACD values have been set,
13378 ** and simply returns what the ACD item already has.
13379 **
13380 ** @param [r] token [const char*] Text token name
13381 ** @return [AjPRegexp] Compiled regular expression.
13382 **                     The original pattern string is available
13383 **                     through a call to ajAcdGetValue
13384 ** @cre failure to find an item with the right name and type aborts.
13385 **
13386 ** @release 4.0.0
13387 ** @@
13388 ******************************************************************************/
13389 
ajAcdGetRegexpSingle(const char * token)13390 AjPRegexp ajAcdGetRegexpSingle(const char *token)
13391 {
13392     AjPPatlistRegex val;
13393     AjPPatternRegex patreg = NULL;
13394     ajint i = 0;
13395 
13396     val = acdGetValueSingle(token, "regexp");
13397 
13398     while (ajPatlistRegexGetNext(val, &patreg))
13399 	i++;
13400 
13401     if(i > 1)
13402 	ajWarn("Single list value %s, but can choose %d values",
13403 	       token, i);
13404 
13405     if(i < 1)
13406 	ajWarn("Single list value %s, no value found: returning NULL value",
13407 	       token);
13408 
13409     return ajPatternRegexGetCompiled(patreg);
13410 }
13411 
13412 
13413 
13414 
13415 /* @funcstatic acdSetRegexp ***************************************************
13416 **
13417 ** Using the definition in the ACD file, and any values for the
13418 ** item or its associated qualifiers provided on the command line,
13419 ** prompts the user if necessary (and possible) and
13420 ** sets the actual value for an ACD regular expression item.
13421 **
13422 ** Understands all attributes and associated qualifiers for this item type.
13423 **
13424 ** The default value (if no other is available) is NULL.
13425 **
13426 ** Attributes for minimum and maximum length are applied with error
13427 ** messages if exceeded.
13428 **
13429 ** @param [u] thys [AcdPAcd] ACD item.
13430 ** @return [void]
13431 **
13432 ** @release 1.0.0
13433 ** @@
13434 ******************************************************************************/
13435 
acdSetRegexp(AcdPAcd thys)13436 static void acdSetRegexp(AcdPAcd thys)
13437 {
13438     AjPPatlistRegex val = NULL;
13439 
13440     AjBool required = ajFalse;
13441     AjBool ok       = ajFalse;
13442 
13443     AjBool upper;
13444     AjBool lower;
13445     ajint itry;
13446 
13447     ajint minlen;
13448     ajint maxlen;
13449     ajint maxsize;
13450     ajint len;
13451     AjPStr type = NULL;
13452     AjPStr patname = NULL;
13453     AjPStr fmt = NULL;
13454     ajint itype = 0;
13455 
13456     acdAttrToInt(thys, "minlength", 1, &minlen);
13457 
13458     acdAttrToInt(thys, "maxlength", INT_MAX, &maxlen);
13459     acdAttrToBool(thys, "upper", ajFalse, &upper);
13460     acdAttrToBool(thys, "lower", ajFalse, &lower);
13461     acdAttrToStr(thys, "type", "string", &type);
13462     acdAttrToInt(thys, "maxsize", INT_MAX, &maxsize);
13463     acdGetValueAssoc(thys, "pname", &patname);
13464     acdGetValueAssoc(thys, "pformat", &fmt);
13465     ajStrFmtLower(&type);
13466     itype = ajPatternRegexType(type);
13467 
13468     required = acdIsRequired(thys);
13469     acdReplyInitC(thys, "", &acdReplyDef);
13470 
13471     for(itry=acdPromptTry; itry && !ok; itry--)
13472     {
13473 	ok = ajTrue;	   /* accept the default if nothing changes */
13474 	if(val)
13475 	    ajPatlistRegexDel(&val);
13476 
13477 	ajStrAssignS(&acdReply, acdReplyDef);
13478 
13479 	if(required)
13480 	    acdUserGet(thys, &acdReply);
13481 
13482 	len = ajStrGetLen(acdReply);
13483 
13484 	if(len < minlen)
13485 	{
13486 	    acdBadVal(thys, required,
13487 		      "Too short (%S) - minimum length is %d characters",
13488 		      thys->Name, minlen);
13489 	    ok = ajFalse;
13490 	}
13491 
13492 	if(len > maxlen)
13493 	{
13494 	    acdBadVal(thys, required,
13495 		      "Too long (%S) - maximum length is %d characters",
13496 		      thys->Name,maxlen);
13497 	    ok = ajFalse;
13498 	}
13499 
13500 /*
13501 	if(upper)
13502 	    ajStrFmtUpper(&acdReply);
13503 
13504 	if(lower)
13505 	    ajStrFmtLower(&acdReply);
13506 */
13507 	if(ok)
13508 	    val = ajPatlistRegexRead(acdReply, patname, fmt,
13509 				     itype, upper, lower);
13510 
13511 	if(ok && !val)
13512 	{
13513 	    acdBadVal(thys, required,
13514 		      "Bad regular expression pattern:\n   '%S'",
13515 		      acdReply);
13516 	    ok = ajFalse;
13517 	}
13518     }
13519 
13520     if(!ok)
13521 	acdBadRetry(thys);
13522 
13523     ajStrDel(&patname);
13524     ajStrDel(&fmt);
13525     ajStrDel(&type);
13526 
13527     /* regexps have special set attributes the same as strings */
13528 
13529     thys->SAttr = acdAttrListCount(acdCalcRegexp);
13530     thys->SetAttr = &acdCalcRegexp[0];
13531     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
13532 
13533     ajStrFromInt(&thys->SetStr[0], ajStrGetLen(acdReply));
13534 
13535     thys->Value = val;
13536     ajStrAssignS(&thys->ValStr, acdReply);
13537 
13538     return;
13539 }
13540 
13541 
13542 
13543 
13544 /* @funcstatic acdSetRel ******************************************************
13545 **
13546 ** Defines an ACD relation.
13547 **
13548 ** Called when a "variable" type ACD item is checked. Should not be called
13549 ** for any other item.
13550 **
13551 ** At present there is nothing to prompt for here, though there could
13552 ** be, for example, a report of what the program does which would appear
13553 ** before any user prompts.
13554 **
13555 ** @param [u] thys [AcdPAcd] ACD for the application item.
13556 ** @return [void]
13557 **
13558 ** @release 2.9.0
13559 ** @@
13560 ******************************************************************************/
13561 
acdSetRel(AcdPAcd thys)13562 static void acdSetRel(AcdPAcd thys)
13563 {
13564     acdAttrToStr(thys, "relations", "", &thys->ValStr);
13565 
13566     return;
13567 }
13568 
13569 
13570 
13571 
13572 /* @func ajAcdGetReport *******************************************************
13573 **
13574 ** Returns an item of type Report as defined in a named ACD item.
13575 ** Called by the application after all ACD values have been set,
13576 ** and simply returns what the ACD item already has.
13577 **
13578 ** @param [r] token [const char*] Text token name
13579 ** @return [AjPReport] Report output object. Already opened
13580 **                      by ajReportOpen so this just returns the object
13581 ** @cre failure to find an item with the right name and type aborts.
13582 **
13583 ** @release 2.0.0
13584 ** @@
13585 ******************************************************************************/
13586 
ajAcdGetReport(const char * token)13587 AjPReport ajAcdGetReport(const char *token)
13588 {
13589     return acdGetValueRef(token, "report");
13590 }
13591 
13592 
13593 
13594 
13595 /* @funcstatic acdSetReport ***************************************************
13596 **
13597 ** Using the definition in the ACD file, and any values for the
13598 ** item or its associated qualifiers provided on the command line,
13599 ** prompts the user if necessary (and possible) and
13600 ** sets the actual value for an ACD report item.
13601 **
13602 ** Understands all attributes and associated qualifiers for this item type.
13603 **
13604 ** The default value (if no other available) is a null string, which
13605 ** is invalid.
13606 **
13607 ** Associated qualifiers "-rformat", "-ropenfile"
13608 ** are applied to the URO before opening the output file.
13609 **
13610 ** @param [u] thys [AcdPAcd] ACD item.
13611 ** @return [void]
13612 ** @see ajSeqRead
13613 **
13614 ** @release 2.0.0
13615 ** @@
13616 ******************************************************************************/
13617 
acdSetReport(AcdPAcd thys)13618 static void acdSetReport(AcdPAcd thys)
13619 {
13620     AjPReport val = NULL;
13621 
13622     AjBool required = ajFalse;
13623     AjBool ok       = ajFalse;
13624 
13625     ajint itry;
13626     AjBool nullok;
13627     AjBool nulldefault;
13628 
13629     AjPStr name      = NULL;
13630     AjPStr ext       = NULL;
13631     AjPStr fmt       = NULL;
13632     AjPStr dir       = NULL;
13633     AjPStr taglist   = NULL;
13634 
13635     val = NULL;
13636 
13637 
13638     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
13639     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
13640 
13641     acdGetValueAssoc(thys, "rdirectory", &dir);
13642     acdGetValueAssoc(thys, "rextension", &ext);
13643     acdGetValueAssoc(thys, "rname", &name);
13644     acdGetValueAssoc(thys, "rformat", &fmt);
13645     acdOutDirectory(&dir);
13646     required = acdIsRequired(thys);
13647 
13648     if(nullok && nulldefault)
13649     {
13650 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
13651 	    acdOutFilename(&acdReplyDef, name, ext);
13652 	else				/* leave empty */
13653 	    acdReplyInitC(thys, "", &acdReplyDef);
13654     }
13655     else
13656     {
13657 	acdOutFilename(&acdTmpOutFName, name, ext);
13658 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
13659     }
13660 
13661     acdPromptReport(thys);
13662 
13663     for(itry=acdPromptTry; itry && !ok; itry--)
13664     {
13665 	ok = ajTrue;	   /* accept the default if nothing changes */
13666 
13667 	ajStrAssignS(&acdReply, acdReplyDef);
13668 
13669 	if(required)
13670 	    acdUserGet(thys, &acdReply);
13671 
13672 	if(ajStrGetLen(acdReply))
13673 	{
13674 	    val = ajReportNew();
13675 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
13676 	    acdAttrToStr(thys, "type", "", &val->Type);
13677 	    acdAttrToStr(thys, "taglist", "", &taglist);
13678 	    acdAttrToBool(thys, "multiple", ajFalse, &val->Multi);
13679 	    acdAttrToInt(thys, "precision", 3, &val->Precision);
13680 	    acdQualToBool(thys, "raccshow", ajFalse,
13681 			  &val->Showacc, &acdReplyDef);
13682 	    acdQualToBool(thys, "rdesshow", ajFalse,
13683 			  &val->Showdes, &acdReplyDef);
13684 	    acdQualToBool(thys, "rscoreshow", ajTrue,
13685 			  &val->Showscore, &acdReplyDef);
13686 	    acdQualToBool(thys, "rstrandshow", ajTrue,
13687 			  &val->Showstrand, &acdReplyDef);
13688 	    acdQualToBool(thys, "rusashow", ajFalse,
13689 			  &val->Showusa, &acdReplyDef);
13690 	    acdQualToInt(thys, "rmaxall", 0,
13691 			  &val->MaxHitAll, &acdReplyDef);
13692 	    acdQualToInt(thys, "rmaxseq", 0,
13693 			  &val->MaxHitSeq, &acdReplyDef);
13694 
13695 	    /* test acdc-reportbadtaglist */
13696 	    if(!ajReportSetTagsS(val, taglist))
13697 		acdErrorAcd(thys, "Bad tag list for report");
13698 
13699 	    /* test acdc-reportbadtags */
13700 	    if(!ajReportValid(val))
13701 		ajDie("Report option -%S: Validation failed",
13702 		      thys->Name);
13703 
13704 	    ajStrAssignS(&acdOutFullFName, acdReply);
13705 	    ajFilenameReplacePathS(&acdOutFullFName, dir);
13706 	    ok = ajReportOpen(val, acdOutFullFName);
13707 
13708 	    if(!ok)
13709 	    {
13710 		acdBadVal(thys, required,
13711 			  "Unable to open report file '%S'",
13712 			  acdOutFullFName);
13713 		ajReportDel(&val);
13714 	    }
13715 	}
13716 	else
13717 	    if(!nullok)
13718 	    {
13719 		acdBadVal(thys, required,
13720 			  "Report file is required");
13721 		ok = ajFalse;
13722 	    }
13723     }
13724 
13725     if(!ok)
13726 	acdBadRetry(thys);
13727 
13728     thys->Value = val;
13729     ajStrAssignS(&thys->ValStr, acdOutFullFName);
13730 
13731     ajStrDel(&acdReply);
13732     ajStrDel(&acdReplyDef);
13733 
13734     ajStrDel(&name);
13735     ajStrDel(&ext);
13736     ajStrDel(&fmt);
13737     ajStrDel(&dir);
13738     ajStrDel(&taglist);
13739 
13740     return;
13741 }
13742 
13743 
13744 
13745 
13746 /* @func ajAcdGetResource *****************************************************
13747 **
13748 ** Returns an item of type resource as defined in a named ACD item.
13749 ** Called by the application after all ACD values have been set,
13750 ** and simply returns what the ACD item already has.
13751 **
13752 ** @param [r] token [const char*] Text token name
13753 ** @return [AjPResource] Data resource object
13754 ** @cre failure to find an item with the right name and type aborts.
13755 **
13756 ** @release 6.4.0
13757 ** @@
13758 ******************************************************************************/
13759 
ajAcdGetResource(const char * token)13760 AjPResource ajAcdGetResource(const char *token)
13761 {
13762     AjPResourceall val = acdGetValue(token, "resource");
13763     if(val->Multi)
13764         ajWarn("ajAcdGetResource request single resource but maxreads > 1");
13765 
13766     val->Returned = ajTrue;
13767 
13768     return val->Resource;
13769 }
13770 
13771 
13772 
13773 
13774 /* @func ajAcdGetResourceall **************************************************
13775 **
13776 ** Returns an input stream of an item of type Resource as defined in a
13777 ** named ACD item.
13778 ** Called by the application after all ACD values have been set,
13779 ** and simply returns what the ACD item already has.
13780 **
13781 ** @param [r] token [const char*] Text token name
13782 ** @return [AjPResourceall] Data resource input stream
13783 ** @cre failure to find an item with the right name and type aborts.
13784 **
13785 ** @release 6.4.0
13786 ** @@
13787 ******************************************************************************/
13788 
ajAcdGetResourceall(const char * token)13789 AjPResourceall ajAcdGetResourceall(const char *token)
13790 {
13791     AjPResourceall val = acdGetValueRef(token, "resource");
13792 
13793     if(!val->Multi)
13794         ajWarn("ajAcdGetResourceall request data resource input stream "
13795                "but maxreads is 1");
13796 
13797     return val;
13798 }
13799 
13800 
13801 
13802 
13803 /* @funcstatic acdSetResource *************************************************
13804 **
13805 ** Using the definition in the ACD file, and any values for the
13806 ** item or its associated qualifiers provided on the command line,
13807 ** prompts the user if necessary (and possible) and
13808 ** sets the actual value for an ACD data resource input
13809 **
13810 ** Understands all attributes and associated qualifiers for this item type.
13811 **
13812 ** @param [u] thys [AcdPAcd] ACD item.
13813 ** @return [void]
13814 **
13815 ** @release 6.4.0
13816 ** @@
13817 ******************************************************************************/
13818 
acdSetResource(AcdPAcd thys)13819 static void acdSetResource(AcdPAcd thys)
13820 {
13821     AjPResourceall val;
13822 
13823     AjBool required = ajFalse;
13824     AjBool ok       = ajFalse;
13825     AjBool nullok   = ajFalse;
13826     ajint itry;
13827 
13828     ajint maxreads;
13829 
13830     AjPStr infname = NULL;
13831 
13832     val = ajResourceallNew();        /* set the default value */
13833 
13834     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
13835     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
13836 
13837     acdAttrToBool(thys, "entry", ajFalse, &val->Resourcein->Input->Text);
13838 
13839     acdInFilename(&infname);
13840     required = acdIsRequired(thys);
13841     acdReplyInitS(thys, infname, &acdReplyDef);
13842     ajStrDel(&infname);
13843 
13844     for(itry=acdPromptTry; itry && !ok; itry--)
13845     {
13846 	ok = ajTrue;	   /* accept the default if nothing changes */
13847 
13848 	ajStrAssignS(&acdReply, acdReplyDef);
13849 
13850 	if(required)
13851 	    acdUserGet(thys, &acdReply);
13852 
13853 	if(!ajStrGetLen(acdReply) && nullok)
13854         {
13855             ajResourceallDel(&val);
13856 	    break;
13857 	}
13858 
13859 	ajResourceinQryS(val->Resourcein, acdReply);
13860 
13861 	acdGetValueAssoc(thys, "iformat", &val->Resourcein->Input->Formatstr);
13862 	acdGetValueAssoc(thys, "iquery", &val->Resourcein->Input->QryFields);
13863 	acdQualToLong(thys, "ioffset", 0L, &val->Resourcein->Input->Fpos,
13864                       &acdTmpStr);
13865 
13866         ok = ajResourceinRead(val->Resourcein, val->Resource);
13867     }
13868 
13869     if(!ok)
13870 	acdBadRetry(thys);
13871 
13872     if(maxreads > 1)
13873         val->Multi = ajTrue;
13874 
13875     acdInFileSave(acdReply, ajResourceallGetresourceId(val), ajTrue);
13876 
13877     thys->Value = val;
13878     ajStrAssignS(&thys->ValStr, acdReply);
13879 
13880     return;
13881 }
13882 
13883 
13884 
13885 
13886 /* @func ajAcdGetScop *********************************************************
13887 **
13888 ** Returns an item of type Scop as defined in a named ACD item.
13889 ** Called by the application after all ACD values have been set,
13890 ** and simply returns what the ACD item already has.
13891 **
13892 ** @param [r] token [const char*] Text token name
13893 ** @return [AjPFile] Scop input file.
13894 ** @cre failure to find an item with the right name and type aborts.
13895 **
13896 ** @release 1.8.0
13897 ** @@
13898 ******************************************************************************/
13899 
ajAcdGetScop(const char * token)13900 AjPFile ajAcdGetScop(const char *token)
13901 {
13902     return acdGetValueRef(token, "scop");
13903 }
13904 
13905 
13906 
13907 
13908 /* @funcstatic acdSetScop *****************************************************
13909 **
13910 ** Using the definition in the ACD file, and any values for the
13911 ** item or its associated qualifiers provided on the command line,
13912 ** prompts the user if necessary (and possible) and
13913 ** sets the actual value for an ACD clean pdb file item.
13914 **
13915 ** Understands all attributes and associated qualifiers for this item type.
13916 **
13917 ** @param [u] thys [AcdPAcd] ACD item.
13918 ** @return [void]
13919 **
13920 ** @release 1.8.0
13921 ** @@
13922 ******************************************************************************/
13923 
acdSetScop(AcdPAcd thys)13924 static void acdSetScop(AcdPAcd thys)
13925 {
13926     AjPFile val;
13927 
13928     AjPStr name     = NULL;
13929     AjBool required = ajFalse;
13930     AjBool ok       = ajFalse;
13931 
13932     ajint itry;
13933     AjPStr fmt    = NULL;
13934 
13935     val = NULL;				/* set the default value */
13936 
13937     acdAttrResolve(thys, "name", &name);
13938 
13939     if (!acdGetValueAssoc(thys, "format", &fmt))
13940 	ajStrAssignClear(&fmt);
13941 
13942     required = acdIsRequired(thys);
13943     acdReplyInitS(thys, name, &acdReplyDef);
13944     acdPromptScop(thys);
13945 
13946     for(itry=acdPromptTry; itry && !ok; itry--)
13947     {
13948 	ok = ajTrue;	   /* accept the default if nothing changes */
13949 
13950 	ajStrAssignS(&acdReply, acdReplyDef);
13951 
13952 	if(required)
13953 	    acdUserGet(thys, &acdReply);
13954 
13955 	if(ajStrGetLen(acdReply))
13956 	{
13957 	    val = ajFileNewInNameS(acdReply);
13958 
13959 	    if(!val)
13960 	    {
13961 		acdBadVal(thys, required,
13962 			  "Unable to read scop data '%S'", acdReply);
13963 		ok = ajFalse;
13964 	    }
13965 	}
13966 	else
13967 	{
13968 	    acdBadVal(thys, required, "Scop data file is required");
13969 	    ok = ajFalse;
13970 	}
13971     }
13972 
13973     if(!ok)
13974 	acdBadRetry(thys);
13975 
13976     thys->Value = val;
13977     ajStrAssignS(&thys->ValStr, acdReply);
13978 
13979     ajStrDel(&name);
13980     ajStrDel(&fmt);
13981 
13982     return;
13983 }
13984 
13985 
13986 
13987 
13988 /* @func ajAcdGetSelect *******************************************************
13989 **
13990 ** Returns an item of type Select as defined in a named ACD item,
13991 ** which is an array of strings terminated by a null value.
13992 ** Called by the application after all ACD values have been set,
13993 ** and simply returns what the ACD item already has.
13994 **
13995 ** @param [r] token [const char*] Text token name
13996 ** @return [AjPStr*] String array of values with NULL as last element.
13997 ** @cre failure to find an item with the right name and type aborts.
13998 **
13999 ** @release 1.0.0
14000 ** @@
14001 ******************************************************************************/
14002 
ajAcdGetSelect(const char * token)14003 AjPStr* ajAcdGetSelect(const char *token)
14004 {
14005     return acdGetValueRef(token, "selection");
14006 }
14007 
14008 
14009 
14010 
14011 /* @func ajAcdGetSelectSingle *************************************************
14012 **
14013 ** Returns one item from an array of type Select as defined in a named
14014 ** ACD item, which is an array of strings terminated by a null value.
14015 ** Called by the application after all ACD values have been set, and
14016 ** simply returns what the ACD item already has.
14017 **
14018 ** @param [r] token [const char*] Text token name
14019 ** @return [AjPStr] String array of values with NULL as last element.
14020 ** @cre failure to find an item with the right name and type aborts.
14021 **
14022 ** @release 4.0.0
14023 ** @@
14024 ******************************************************************************/
14025 
ajAcdGetSelectSingle(const char * token)14026 AjPStr ajAcdGetSelectSingle(const char *token)
14027 {
14028     AjPStr* val;
14029     ajint i;
14030 
14031     val =  acdGetValueSingle(token, "select");
14032 
14033     for(i=0; val[i]; i++)
14034 	continue;
14035 
14036     if(i > 1)
14037 	ajWarn("Single list value %s, but can choose %d values",
14038 	       token, i);
14039 
14040     if(i < 1)
14041 	ajWarn("Single list value %s, no value found: returning NULL value",
14042 	       token);
14043 
14044     return val[0];
14045 }
14046 
14047 
14048 
14049 
14050 /* @funcstatic acdSetSelect ***************************************************
14051 **
14052 ** Using the definition in the ACD file, and any values for the
14053 ** item or its associated qualifiers provided on the command line,
14054 ** prompts the user if necessary (and possible) and
14055 ** sets the actual value for an ACD select menu item.
14056 **
14057 ** Understands all attributes and associated qualifiers for this item type.
14058 **
14059 ** @param [u] thys [AcdPAcd] ACD item.
14060 ** @return [void]
14061 ** @see ajFileNewOut
14062 **
14063 ** @release 1.0.0
14064 ** @@
14065 ******************************************************************************/
14066 
acdSetSelect(AcdPAcd thys)14067 static void acdSetSelect(AcdPAcd thys)
14068 {
14069     AjPStr* val;
14070 
14071     AjBool required = ajFalse;
14072     AjBool ok       = ajFalse;
14073 
14074     ajint itry;
14075     ajint i;
14076 
14077     ajint min=0, max=5;
14078 
14079     val = NULL;				/* set the default value */
14080 
14081     required = acdIsRequired(thys);
14082     acdReplyInitC(thys, "", &acdReplyDef);
14083 
14084     acdAttrToInt(thys, "minimum", 1, &min);
14085     acdAttrToInt(thys, "maximum", 1, &max);
14086 
14087     for(itry=acdPromptTry; itry && !ok; itry--)
14088     {
14089 	ok = ajTrue;	   /* accept the default if nothing changes */
14090 
14091 	ajStrAssignS(&acdReply, acdReplyDef);
14092 
14093 	if(required)
14094 	{
14095 	    acdSelectPrompt(thys);
14096 	    acdUserGet(thys, &acdReply);
14097 	}
14098 
14099 	val = acdSelectValue(thys, min, max, acdReply);
14100 
14101 	if(!val)
14102 	{
14103 	    acdBadVal(thys, required, "Bad select option '%S'", acdReply);
14104 	    ok = ajFalse;
14105 	}
14106     }
14107 
14108     if(!ok)
14109 	acdBadRetry(thys);
14110 
14111     thys->Value = val;
14112     for(i=0; val[i]; i++)
14113     {
14114 	if(i)
14115 	    ajStrAppendC(&thys->ValStr, ";");
14116 
14117 	ajStrAppendS(&thys->ValStr, val[i]);
14118     }
14119 
14120     return;
14121 }
14122 
14123 
14124 
14125 
14126 /* @func ajAcdGetSeq **********************************************************
14127 **
14128 ** Returns an item of type Seq as defined in a named ACD item.
14129 ** Called by the application after all ACD values have been set,
14130 ** and simply returns what the ACD item already has.
14131 **
14132 ** @param [r] token [const char*] Text token name
14133 ** @return [AjPSeq] Sequence object. The sequence was already loaded by
14134 **         acdSetSeq so this just returns the pointer.
14135 ** @cre failure to find an item with the right name and type aborts.
14136 **
14137 ** @release 1.0.0
14138 ** @@
14139 ******************************************************************************/
14140 
ajAcdGetSeq(const char * token)14141 AjPSeq ajAcdGetSeq(const char *token)
14142 {
14143     return acdGetValueRef(token, "sequence");
14144 }
14145 
14146 
14147 
14148 
14149 /* @funcstatic acdSetSeq ******************************************************
14150 **
14151 ** Using the definition in the ACD file, and any values for the
14152 ** item or its associated qualifiers provided on the command line,
14153 ** prompts the user if necessary (and possible) and
14154 ** sets the actual value for an ACD sequence item.
14155 **
14156 ** Understands all attributes and associated qualifiers for this item type.
14157 **
14158 ** The default value (if no other available) is a null string, which
14159 ** is invalid.
14160 **
14161 ** Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid"
14162 ** are applied to the USA before reading the sequence.
14163 **
14164 ** Associated qualifiers "-supper", "-slower" and "-sask" are applied
14165 ** after reading.
14166 **
14167 ** Associated qualifiers "-sbegin", "-send" and "-sreverse"
14168 ** are applied as appropriate, with prompting for values,
14169 ** after the sequence has been read. They are applied to the sequence,
14170 ** and the resulting sequence is what is set in the ACD item.
14171 **
14172 ** @param [u] thys [AcdPAcd] ACD item.
14173 ** @return [void]
14174 ** @see ajSeqRead
14175 **
14176 ** @release 1.0.0
14177 ** @@
14178 ******************************************************************************/
14179 
acdSetSeq(AcdPAcd thys)14180 static void acdSetSeq(AcdPAcd thys)
14181 {
14182     AjPSeq val = NULL;
14183     AjPSeqin seqin;
14184 
14185     AjBool required = ajFalse;
14186     AjBool ok       = ajFalse;
14187     AjBool okbeg    = ajFalse;
14188     AjBool okend    = ajFalse;
14189     AjBool okrev    = ajFalse;
14190 
14191     ajint itry;
14192     ajint i;
14193 
14194     AjPStr infname = NULL;
14195 
14196     ajint sqbegin = 0;
14197     ajint sqend   = 0;
14198 
14199     AjBool sreverse = ajFalse;
14200     AjBool sprompt  = ajFalse;
14201     AjBool snuc     = ajFalse;
14202     AjBool sprot    = ajFalse;
14203     AjBool nullok   = ajFalse;
14204     AjPStr typestr  = NULL;
14205 
14206 
14207     val   = ajSeqNew();		        /* set the default value */
14208     seqin = ajSeqinNew();		/* set the default value */
14209 
14210     acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef);
14211     acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef);
14212     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
14213     acdAttrToStr(thys, "type", "", &typestr);
14214 
14215     acdInFilename(&infname);
14216     required = acdIsRequired(thys);
14217     acdReplyInitS(thys, infname, &acdReplyDef);
14218     acdPromptSeq(thys);
14219     ajStrDel(&infname);
14220 
14221     for(itry=acdPromptTry; itry && !ok; itry--)
14222     {
14223 	ok = ajTrue;	   /* accept the default if nothing changes */
14224 
14225 	ajStrAssignS(&acdReply, acdReplyDef);
14226 
14227 	if(required)
14228 	    acdUserGet(thys, &acdReply);
14229 
14230 	if(!ajStrGetLen(acdReply) && nullok)
14231         {
14232             ajSeqDel(&val);
14233 	    break;
14234 	}
14235 
14236 	ajSeqinUsa(&seqin, acdReply);
14237 
14238 	if(ajStrGetLen(typestr))
14239 	{
14240 	   ajStrAssignS(&seqin->Inputtype, typestr);
14241 	   acdInTypeSeqSave(seqin->Inputtype);
14242         }
14243 	else
14244 	    acdInTypeSeqSave(NULL);
14245 
14246 	acdAttrToBool(thys, "features", ajFalse, &seqin->Features);
14247 	acdAttrToBool(thys, "entry", ajFalse, &seqin->Input->Text);
14248 
14249 	acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr);
14250 	acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db);
14251 /*	acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */
14252 	acdGetValueAssoc(thys, "sid", &seqin->Entryname);
14253 	acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields);
14254 	acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos,
14255                       &acdTmpStr);
14256 
14257 	acdGetValueAssoc(thys, "ufo", &seqin->Ufo);
14258 
14259 	acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr);
14260 	acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename);
14261 
14262 	acdQualToBool(thys, "squick", ajFalse,
14263 		      &seqin->Minimal, &acdTmpStr);
14264 	acdQualToBool(thys, "scircular", ajFalse,
14265 		      &seqin->Circular, &acdTmpStr);
14266 	acdQualToBool(thys, "supper", ajFalse,
14267 		      &seqin->Upper, &acdTmpStr);
14268 	acdQualToBool(thys, "slower", ajFalse,
14269 		      &seqin->Lower, &acdTmpStr);
14270 	okbeg = acdQualToSeqbegin(thys, "sbegin", 0,
14271 				  &sqbegin, &acdTmpStr);
14272 	okend = acdQualToSeqend(thys, "send", 0,
14273 				&sqend, &acdTmpStr);
14274 	okrev = acdQualToBool(thys, "sreverse", ajFalse,
14275 			      &sreverse, &acdTmpStr);
14276 
14277 	if(snuc)
14278 	    ajSeqinSetNuc(seqin);
14279 
14280 	if(sprot)
14281 	    ajSeqinSetProt(seqin);
14282 
14283 	i = ajStrGetLen(seqin->Ufo) + ajStrGetLen(seqin->Ftquery->Formatstr)
14284 	    + ajStrGetLen(seqin->Ftquery->Filename);
14285 
14286 	if(i && !seqin->Features)
14287 	    ajWarn("Feature table ignored");
14288 
14289 	if(seqin->Features)
14290 	    acdLog("acdSetSeq with features UFO '%S'\n", seqin->Ufo);
14291 
14292       	/* (try to) read the sequence */
14293 
14294 	ok = ajSeqRead(val, seqin);
14295 
14296 	if(!ok)
14297 	{
14298 	    acdBadVal(thys, required,
14299 		      "Unable to read sequence '%S'", acdReply);
14300 	}
14301     }
14302 
14303     if(!ok)
14304 	acdBadRetry(thys);
14305 
14306     acdInFileSave(acdReply, ajSeqGetNameS(val),
14307                   ajTrue);	/* save sequence name */
14308 
14309     /* some standard options using associated qualifiers */
14310 
14311     acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef);
14312 
14313     if(val)
14314     {
14315 
14316         /* now process the begin, end and reverse options */
14317 
14318         if(seqin->Begin)
14319             okbeg = ajTrue;
14320 
14321         for(itry=acdPromptTry; itry && !okbeg; itry--)
14322         {
14323             ajStrAssignC(&acdReplyPrompt, "start");
14324 
14325             if(sprompt)
14326                 acdUserGetPrompt(thys, "sbegin",
14327                                  " Begin at position", &acdReplyPrompt);
14328             if(ajStrMatchCaseC(acdReplyPrompt, "start"))
14329                 ajStrAssignC(&acdReplyPrompt, "0");
14330 
14331             okbeg = ajStrToInt(acdReplyPrompt, &sqbegin);
14332 
14333             if(!okbeg)
14334                 acdBadVal(thys, sprompt,
14335                           "Invalid sequence position '%S'", acdReplyPrompt);
14336         }
14337 
14338         if(!okbeg)
14339             acdBadRetry(thys);
14340 
14341         if(sqbegin)
14342         {
14343             seqin->Begin = sqbegin;
14344             val->Begin = sqbegin;
14345             acdSetQualDefInt(thys, "sbegin", sqbegin);
14346         }
14347 
14348         if(seqin->End)
14349             okend = ajTrue;
14350 
14351         for(itry=acdPromptTry; itry && !okend; itry--)
14352         {
14353             ajStrAssignC(&acdReplyPrompt, "end");
14354 
14355             if(sprompt)
14356                 acdUserGetPrompt(thys, "send",
14357                                  "   End at position", &acdReplyPrompt);
14358             if(ajStrMatchCaseC(acdReplyPrompt, "end"))
14359                 ajStrAssignC(&acdReplyPrompt, "0");
14360 
14361             okend = ajStrToInt(acdReplyPrompt, &sqend);
14362 
14363             if(!okend)
14364                 acdBadVal(thys, sprompt,
14365                           "Invalid sequence position '%S'", acdReplyPrompt);
14366         }
14367 
14368         if(!okend)
14369             acdBadRetry(thys);
14370 
14371         if(sqend)
14372         {
14373             seqin->End = sqend;
14374             val->End = sqend;
14375             acdSetQualDefInt(thys, "send", sqend);
14376         }
14377 
14378         if(ajSeqIsNuc(val))
14379         {
14380             for(itry=acdPromptTry; itry && !okrev; itry--)
14381             {
14382                 ajStrAssignC(&acdReplyPrompt, "N");
14383 
14384                 if(sprompt)
14385                     acdUserGetPrompt(thys, "sreverse",
14386                                      "    Reverse strand", &acdReplyPrompt);
14387 
14388                 okrev = ajStrToBool(acdReplyPrompt, &sreverse);
14389 
14390                 if(!okrev)
14391                     acdBadVal(thys, sprompt,
14392                               "Invalid Y/N value '%S'", acdReplyPrompt);
14393             }
14394 
14395             if(!okrev)
14396                 acdBadRetry(thys);
14397 
14398             if(sreverse)
14399             {
14400                 seqin->Rev = sreverse;
14401                 val->Rev = sreverse;
14402                 acdSetQualDefBool(thys, "sreverse", sreverse);
14403             }
14404         }
14405 
14406         acdLog("sbegin: %d, send: %d, sreverse: %B\n",
14407                sqbegin, sqend, sreverse);
14408 
14409         if(val->Rev)
14410             ajSeqReverseDo(val);
14411 
14412 
14413         /* sequences have special set attributes */
14414 
14415         thys->SAttr = acdAttrListCount(acdCalcSeq);
14416         thys->SetAttr = &acdCalcSeq[0];
14417         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
14418 
14419         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqGetBegin(val));
14420         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqGetEnd(val));
14421         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqGetLen(val));
14422         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqIsNuc(val));
14423         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqIsProt(val));
14424         ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], val->Name);
14425         ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqGetUsaS(val));
14426     }
14427     else
14428     {
14429        /* sequences have special set attributes */
14430 
14431         thys->SAttr = acdAttrListCount(acdCalcSeq);
14432         thys->SetAttr = &acdCalcSeq[0];
14433         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
14434 
14435         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0);
14436         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0);
14437         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0);
14438         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse);
14439         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse);
14440         ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], "");
14441         ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], "");
14442     }
14443 
14444     thys->Value = val;
14445     ajStrAssignS(&thys->ValStr, acdReply);
14446 
14447     ajSeqinDel(&seqin);
14448     ajStrDel(&typestr);
14449 
14450     return;
14451 }
14452 
14453 
14454 
14455 
14456 /* @func ajAcdGetSeqall *******************************************************
14457 **
14458 ** Returns an item of type Seq as defined in a named ACD item.
14459 ** Called by the application after all ACD values have been set,
14460 ** and simply returns what the ACD item already has.
14461 **
14462 ** @param [r] token [const char*] Text token name
14463 ** @return [AjPSeqall] Sequence stream object. The sequence was already
14464 **         loaded by acdSetSeqall so this just returns the pointer.
14465 ** @cre failure to find an item with the right name and type aborts.
14466 **
14467 ** @release 1.0.0
14468 ** @@
14469 ******************************************************************************/
14470 
ajAcdGetSeqall(const char * token)14471 AjPSeqall ajAcdGetSeqall(const char *token)
14472 {
14473     return acdGetValueRef(token, "seqall");
14474 }
14475 
14476 
14477 
14478 
14479 /* @funcstatic acdSetSeqall ***************************************************
14480 **
14481 ** Using the definition in the ACD file, and any values for the
14482 ** item or its associated qualifiers provided on the command line,
14483 ** prompts the user if necessary (and possible) and
14484 ** sets the actual value for an ACD sequence item.
14485 **
14486 ** Understands all attributes and associated qualifiers for this item type.
14487 **
14488 ** The default value (if no other available) is a null string, which
14489 ** is invalid.
14490 **
14491 ** Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid"
14492 ** are applied to the USA before reading the sequence.
14493 **
14494 ** Associated qualifier "-sask" is applied
14495 ** after reading.
14496 **
14497 ** Associated qualifiers "-supper", "-slower" are applied
14498 ** globally
14499 **
14500 ** Associated qualifiers "-sbegin", "-send" and "-sreverse"
14501 ** are applied as appropriate, with prompting for values,
14502 ** after the sequence has been read. They are applied to the sequence,
14503 ** and the resulting sequence is what is set in the ACD item.
14504 **
14505 ** @param [u] thys [AcdPAcd] ACD item.
14506 ** @return [void]
14507 ** @see ajSeqRead
14508 **
14509 ** @release 1.0.0
14510 ** @@
14511 ******************************************************************************/
14512 
acdSetSeqall(AcdPAcd thys)14513 static void acdSetSeqall(AcdPAcd thys)
14514 {
14515     AjPSeqall val = NULL;
14516     AjPSeqin seqin;
14517     AjPSeq seq;
14518 
14519     AjBool required = ajFalse;
14520     AjBool ok       = ajFalse;
14521     AjBool okbeg    = ajFalse;
14522     AjBool okend    = ajFalse;
14523     AjBool okrev    = ajFalse;
14524 
14525     ajint itry;
14526     AjBool nullok = ajFalse;
14527 
14528     AjPStr infname = NULL;
14529 
14530     ajint sqbegin = 0;
14531     ajint sqend   = 0;
14532     AjBool sreverse = ajFalse;
14533     AjBool sprompt  = ajFalse;
14534     AjBool snuc     = ajFalse;
14535     AjBool sprot    = ajFalse;
14536     AjPStr typestr  = NULL;
14537 
14538     val = ajSeqallNew();		/* set the default value */
14539     seqin = val->Seqin;
14540     seqin->Input->Multi = ajTrue;
14541     seq = val->Seq;
14542 
14543     acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef);
14544     acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef);
14545     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
14546     acdAttrToStr(thys, "type", "", &typestr);
14547 
14548     acdInFilename(&infname);
14549     required = acdIsRequired(thys);
14550     acdReplyInitS(thys, infname, &acdReplyDef);
14551     acdPromptSeq(thys);
14552     ajStrDel(&infname);
14553 
14554     for(itry=acdPromptTry; itry && !ok; itry--)
14555     {
14556 	ok = ajTrue;	   /* accept the default if nothing changes */
14557 
14558 	ajStrAssignS(&acdReply, acdReplyDef);
14559 
14560 	if(required)
14561 	    acdUserGet(thys, &acdReply);
14562 
14563 	if(!ajStrGetLen(acdReply) && nullok)
14564         {
14565             ajSeqallDel(&val);
14566 	    break;
14567 	}
14568 
14569 	ajSeqinUsa(&seqin, acdReply);
14570 
14571 	if(ajStrGetLen(typestr))
14572 	{
14573 	    ajStrAssignS(&seqin->Inputtype, typestr);
14574 	    acdInTypeSeqSave(seqin->Inputtype);
14575 	}
14576 	else
14577 	    acdInTypeSeqSave(NULL);
14578 
14579 	acdAttrToBool(thys, "features", ajFalse, &seqin->Features);
14580 	acdAttrToBool(thys, "entry", ajFalse, &seqin->Input->Text);
14581 
14582 	acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr);
14583 	acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db);
14584 /*	acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */
14585 	acdGetValueAssoc(thys, "sid", &seqin->Entryname);
14586 	acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields);
14587 	acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos,
14588                       &acdTmpStr);
14589 
14590 	acdGetValueAssoc(thys, "ufo", &seqin->Ufo);
14591 	acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr);
14592 	acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename);
14593 
14594 	acdQualToBool(thys, "squick", ajFalse,
14595 		      &seqin->Minimal, &acdTmpStr);
14596 	acdQualToBool(thys, "scircular", ajFalse,
14597 		      &seqin->Circular, &acdTmpStr);
14598 	acdQualToBool(thys, "supper", ajFalse,
14599 		      &seqin->Upper, &acdTmpStr);
14600 	acdQualToBool(thys, "slower", ajFalse,
14601 		      &seqin->Lower, &acdTmpStr);
14602 	okbeg = acdQualToSeqbegin(thys, "sbegin", 0,
14603 				  &seqin->Begin, &acdTmpStr);
14604 	okend = acdQualToSeqend(thys, "send", 0,
14605 				&seqin->End, &acdTmpStr);
14606 	okrev = acdQualToBool(thys, "sreverse", ajFalse,
14607 			      &sreverse, &acdTmpStr);
14608 
14609 	if(snuc)
14610 	    ajSeqinSetNuc(seqin);
14611 
14612 	if(sprot)
14613 	    ajSeqinSetProt(seqin);
14614 
14615 	if(ajStrGetLen(seqin->Ufo))
14616 	    seqin->Features = ajTrue;
14617 
14618 	ok = ajSeqAllRead(seq, seqin);
14619 
14620         if(!ok)
14621 	    acdBadVal(thys, required,
14622 		      "Unable to read sequence '%S'", acdReply);
14623     }
14624 
14625     if(!ok)
14626 	acdBadRetry(thys);
14627 
14628     acdInFileSave(acdReply, ajSeqallGetseqName(val), ajTrue);
14629 
14630     /*  commentedout__ajSeqinDel(&seqin);*/
14631 
14632     acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef);
14633 
14634     /* now process the begin, end and reverse options */
14635 
14636     if(val)
14637     {
14638 
14639         if(seqin->Begin)
14640         {
14641             okbeg = ajTrue;
14642             val->Begin = seq->Begin = seqin->Begin;
14643         }
14644 
14645         for(itry=acdPromptTry; itry && !okbeg; itry--)
14646         {
14647             ajStrAssignC(&acdReplyPrompt, "start");
14648 
14649             if(sprompt)
14650                 acdUserGetPrompt(thys, "sbegin",
14651                                  " Begin at position", &acdReplyPrompt);
14652             if(ajStrMatchCaseC(acdReplyPrompt, "start"))
14653                 ajStrAssignC(&acdReplyPrompt, "0");
14654 
14655             okbeg = ajStrToInt(acdReplyPrompt, &sqbegin);
14656 
14657             if(!okbeg)
14658                 acdBadVal(thys, sprompt,
14659                           "Invalid integer value '%S'", acdReplyPrompt);
14660         }
14661 
14662         if(!okbeg)
14663             acdBadRetry(thys);
14664 
14665         if(sqbegin)
14666         {
14667             seqin->Begin = sqbegin;
14668             seq->Begin = sqbegin;
14669             val->Begin = sqbegin;
14670             acdSetQualDefInt(thys, "sbegin", sqbegin);
14671         }
14672 
14673         if(seqin->End)
14674         {
14675             okend = ajTrue;
14676             val->End = seq->End = seqin->End;
14677         }
14678 
14679         for(itry=acdPromptTry; itry && !okend; itry--)
14680         {
14681             ajStrAssignC(&acdReplyPrompt, "end");
14682 
14683             if(sprompt)
14684                 acdUserGetPrompt(thys, "send",
14685                                  "   End at position", &acdReplyPrompt);
14686             if(ajStrMatchCaseC(acdReplyPrompt, "end"))
14687                 ajStrAssignC(&acdReplyPrompt, "0");
14688 
14689             okend = ajStrToInt(acdReplyPrompt, &sqend);
14690 
14691             if(!okend)
14692                 acdBadVal(thys, sprompt,
14693                           "Invalid integer value '%S'", acdReplyPrompt);
14694         }
14695 
14696         if(!okend)
14697             acdBadRetry(thys);
14698 
14699         if(sqend)
14700         {
14701             seqin->End = sqend;
14702             seq->End = sqend;
14703             val->End = sqend;
14704             acdSetQualDefInt(thys, "send", sqend);
14705         }
14706 
14707         if(ajSeqIsNuc(seq))
14708         {
14709             for(itry=acdPromptTry; itry && !okrev; itry--)
14710             {
14711                 ajStrAssignC(&acdReplyPrompt, "N");
14712 
14713                 if(sprompt)
14714                     acdUserGetPrompt(thys, "sreverse",
14715                                      "    Reverse strand", &acdReplyPrompt);
14716                 okrev = ajStrToBool(acdReplyPrompt, &sreverse);
14717 
14718                 if(!okrev)
14719                     acdBadVal(thys, sprompt,
14720                               "Invalid Y/N value '%S'", acdReplyPrompt);
14721             }
14722 
14723             if(!okrev)
14724                 acdBadRetry(thys);
14725 
14726             if(sreverse)
14727             {
14728                 seqin->Rev = sreverse;
14729                 seq->Rev = sreverse;
14730                 val->Rev = sreverse;
14731                 acdSetQualDefBool(thys, "sreverse", sreverse);
14732             }
14733         }
14734 
14735 
14736         acdLog("sbegin: %d, send: %d, sreverse: %B\n",
14737                sqbegin, sqend, sreverse);
14738 
14739         /* sequences have special set attributes */
14740 
14741         thys->SAttr = acdAttrListCount(acdCalcSeqall);
14742         thys->SetAttr = &acdCalcSeqall[0];
14743         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
14744 
14745         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqallGetseqBegin(val));
14746         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqallGetseqEnd(val));
14747         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqGetLen(seq));
14748         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqIsNuc(seq));
14749         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqIsProt(seq));
14750         ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], seq->Name);
14751         ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqallGetUsa(val));
14752     }
14753     else
14754     {
14755        /* sequences have special set attributes */
14756 
14757         thys->SAttr = acdAttrListCount(acdCalcSeqall);
14758         thys->SetAttr = &acdCalcSeq[0];
14759         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
14760 
14761         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0);
14762         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0);
14763         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0);
14764         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse);
14765         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse);
14766         ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], "");
14767         ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], "");
14768     }
14769 
14770     thys->Value = val;
14771     ajStrAssignS(&thys->ValStr, acdReply);
14772 
14773     ajStrDel(&typestr);
14774 
14775     return;
14776 }
14777 
14778 
14779 
14780 
14781 /* @funcstatic acdSetSeqsetall ************************************************
14782 **
14783 ** Using the definition in the ACD file, and any values for the
14784 ** item or its associated qualifiers provided on the command line,
14785 ** prompts the user if necessary (and possible) and
14786 ** sets the actual value for an ACD sequence item.
14787 **
14788 ** Understands all attributes and associated qualifiers for this item type.
14789 **
14790 ** The default value (if no other available) is a null string, which
14791 ** is invalid.
14792 **
14793 ** Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid"
14794 ** are applied to the USA before reading the sequence.
14795 **
14796 ** Associated qualifiers "-supper", "-slower" and "-sask" are applied
14797 ** after reading.
14798 **
14799 ** Associated qualifiers "-sbegin", "-send" and "-sreverse"
14800 ** are applied as appropriate, with prompting for values,
14801 ** after the sequence has been read. They are applied to the sequence,
14802 ** and the resulting sequence is what is set in the ACD item.
14803 **
14804 ** @param [u] thys [AcdPAcd] ACD item.
14805 ** @return [void]
14806 ** @see ajSeqRead
14807 **
14808 ** @release 2.8.0
14809 ** @@
14810 ******************************************************************************/
14811 
14812 
acdSetSeqsetall(AcdPAcd thys)14813 static void acdSetSeqsetall(AcdPAcd thys)
14814 {
14815     AjPSeqset *val = NULL;
14816     AjPSeqin seqin;
14817 
14818     AjBool required = ajFalse;
14819     AjBool ok       = ajFalse;
14820     AjBool okbeg    = ajFalse;
14821     AjBool okend    = ajFalse;
14822     AjBool okrev    = ajFalse;
14823 
14824     ajint itry;
14825     ajint iattr;
14826 
14827     AjPStr infname = NULL;
14828 
14829     ajint sqbegin = 0;
14830     ajint sqend   = 0;
14831     AjBool sreverse = ajFalse;
14832     AjBool sprompt  = ajFalse;
14833     AjBool snuc     = ajFalse;
14834     AjBool sprot    = ajFalse;
14835     AjBool nullok   = ajFalse;
14836     AjBool aligned  = ajFalse;
14837     AjPStr typestr  = NULL;
14838 
14839     void **sets     = NULL;
14840     AjPList seqlist;
14841 
14842     ajint iset = 0;
14843     ajint nsets;
14844 
14845     seqlist = ajListNew();
14846     seqin = ajSeqinNew();		/* set the default value */
14847 
14848     seqin->Input->Multi = ajTrue;
14849 
14850     acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef);
14851     acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef);
14852     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
14853     acdAttrToBool(thys, "aligned", ajFalse, &aligned);
14854     acdAttrToStr(thys, "type", "", &typestr);
14855 
14856     acdInFilename(&infname);
14857     required = acdIsRequired(thys);
14858     acdReplyInitS(thys, infname, &acdReplyDef);
14859     acdPromptSeq(thys);
14860     ajStrDel(&infname);
14861 
14862     for(itry=acdPromptTry; itry && !ok; itry--)
14863     {
14864 	ok = ajTrue;	   /* accept the default if nothing changes */
14865 
14866 	ajStrAssignS(&acdReply, acdReplyDef);
14867 
14868 	if(required)
14869 	    acdUserGet(thys, &acdReply);
14870 
14871 	if(!ajStrGetLen(acdReply) && nullok)
14872 	    break;
14873 
14874 	ajSeqinUsa(&seqin, acdReply);
14875 
14876 	if(ajStrGetLen(typestr))
14877 	{
14878 	    ajStrAssignS(&seqin->Inputtype, typestr);
14879 	    acdInTypeSeqSave(seqin->Inputtype);
14880 	}
14881 	else
14882 	    acdInTypeSeqSave(NULL);
14883 
14884 	acdAttrToBool(thys, "features", ajFalse, &seqin->Features);
14885 
14886 	acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr);
14887 	acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db);
14888 /*	acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */
14889 	acdGetValueAssoc(thys, "sid", &seqin->Entryname);
14890 	acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields);
14891 	acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos,
14892                       &acdTmpStr);
14893 
14894 	acdGetValueAssoc(thys, "ufo", &seqin->Ufo);
14895 	acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr);
14896 	acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename);
14897 
14898 	acdQualToBool(thys, "squick", ajFalse,
14899 		      &seqin->Minimal, &acdTmpStr);
14900 	acdQualToBool(thys, "scircular", ajFalse,
14901 		      &seqin->Circular, &acdTmpStr);
14902 	acdQualToBool(thys, "supper", ajFalse,
14903 		      &seqin->Upper, &acdTmpStr);
14904 	acdQualToBool(thys, "slower", ajFalse,
14905 		      &seqin->Lower, &acdTmpStr);
14906 	okbeg = acdQualToSeqbegin(thys, "sbegin", 0,
14907 				  &seqin->Begin, &acdTmpStr);
14908 	okend = acdQualToSeqend(thys, "send", 0,
14909 				&seqin->End, &acdTmpStr);
14910 	okrev = acdQualToBool(thys, "sreverse", ajFalse,
14911 			      &sreverse, &acdTmpStr);
14912 
14913 	if(snuc)
14914 	    ajSeqinSetNuc(seqin);
14915 
14916 	if(sprot)
14917 	    ajSeqinSetProt(seqin);
14918 
14919 	if(ajStrGetLen(seqin->Ufo))
14920 	    seqin->Features = ajTrue;
14921 
14922 	ok = ajSeqsetallRead(seqlist, seqin);
14923 
14924 	if(!ok)
14925 	    acdBadVal(thys, required,
14926 		      "Unable to read sequence '%S'", acdReply);
14927     }
14928 
14929     if(!ok)
14930 	acdBadRetry(thys);
14931 
14932     nsets = (ajuint) ajListToarray(seqlist,(void***) &sets);
14933 
14934     if(!nsets)
14935     {
14936         acdInFileSave(acdReply, ajStrConstEmpty(),
14937                       ajTrue);
14938        /* sequences have special set attributes */
14939 
14940         thys->SAttr = acdAttrListCount(acdCalcSeqsetall);
14941         thys->SetAttr = &acdCalcSeq[0];
14942         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
14943 
14944         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0);
14945         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0);
14946         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0);
14947         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse);
14948         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse);
14949         ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], "");
14950         ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], "");
14951         ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT],
14952                        0.0, 3);
14953         ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], 0);
14954         ajStrFromInt(&thys->SetStr[ACD_SEQ_MULTICOUNT], 0);
14955     }
14956     else
14957     {
14958         val   = (AjPSeqset*) sets;
14959         ajListFree(&seqlist);
14960 
14961         acdInFileSave(acdReply, ajSeqsetGetNameS(val[0]),
14962                       ajTrue);      /* save sequence name */
14963 
14964         acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef);
14965 
14966         /* now process the begin, end and reverse options */
14967 
14968         if(seqin->Begin)
14969         {
14970             okbeg = ajTrue;
14971 
14972             for(iset=0;iset<nsets;iset++)
14973                 val[iset]->Begin = seqin->Begin;
14974         }
14975 
14976         for(itry=acdPromptTry; itry && !okbeg; itry--)
14977         {
14978             ajStrAssignC(&acdReplyPrompt, "start");
14979 
14980             if(sprompt)
14981                 acdUserGetPrompt(thys, "sbegin",
14982                                  " Begin at position", &acdReplyPrompt);
14983             if(ajStrMatchCaseC(acdReplyPrompt, "start"))
14984                 ajStrAssignC(&acdReplyPrompt, "0");
14985 
14986             okbeg = ajStrToInt(acdReplyPrompt, &sqbegin);
14987 
14988             if(!okbeg)
14989                 acdBadVal(thys, sprompt,
14990                           "Invalid integer value '%S'", acdReplyPrompt);
14991         }
14992 
14993         if(!okbeg)
14994             acdBadRetry(thys);
14995 
14996         if(sqbegin)
14997         {
14998             seqin->Begin = sqbegin;
14999 
15000             for(iset=0;iset<nsets;iset++)
15001                 val[iset]->Begin = sqbegin;
15002 
15003             acdSetQualDefInt(thys, "sbegin", sqbegin);
15004         }
15005 
15006         if(seqin->End)
15007         {
15008             okend = ajTrue;
15009 
15010             for(iset=0;iset<nsets;iset++)
15011                 val[iset]->End = seqin->End;
15012         }
15013 
15014         for(itry=acdPromptTry; itry && !okend; itry--)
15015         {
15016             ajStrAssignC(&acdReplyPrompt, "end");
15017 
15018             if(sprompt)
15019                 acdUserGetPrompt(thys, "send",
15020                                  "   End at position", &acdReplyPrompt);
15021             if(ajStrMatchCaseC(acdReplyPrompt, "end"))
15022                 ajStrAssignC(&acdReplyPrompt, "0");
15023 
15024             okend = ajStrToInt(acdReplyPrompt, &sqend);
15025 
15026             if(!okend)
15027                 acdBadVal(thys, sprompt,
15028                           "Invalid integer value '%S'", acdReplyPrompt);
15029         }
15030 
15031         if(!okend)
15032             acdBadRetry(thys);
15033 
15034         if(sqend)
15035         {
15036             seqin->End = sqend;
15037 
15038             for(iset=0;iset<nsets;iset++)
15039                 val[iset]->End = sqend;
15040 
15041             acdSetQualDefInt(thys, "send", sqend);
15042         }
15043 
15044         if(ajSeqsetIsNuc(val[0]))
15045         {
15046             for(itry=acdPromptTry; itry && !okrev; itry--)
15047             {
15048                 ajStrAssignC(&acdReplyPrompt, "N");
15049 
15050                 if(sprompt)
15051                     acdUserGetPrompt(thys, "sreverse",
15052                                      "    Reverse strand", &acdReplyPrompt);
15053 
15054                 okrev = ajStrToBool(acdReplyPrompt, &sreverse);
15055 
15056                 if(!okrev)
15057                     acdBadVal(thys, sprompt,
15058                               "Invalid Y/N value '%S'", acdReplyPrompt);
15059             }
15060 
15061             if(!okrev)
15062                 acdBadRetry(thys);
15063 
15064             if(sreverse)
15065             {
15066                 seqin->Rev = sreverse;
15067 
15068                 for(iset=0;iset<nsets;iset++)
15069                     val[iset]->Rev = sreverse;
15070 
15071                 acdSetQualDefBool(thys, "sreverse", sreverse);
15072             }
15073         }
15074 
15075         acdLog("sbegin: %d, send: %d, sreverse: Bs\n",
15076                sqbegin, sqend, sreverse);
15077 
15078         if(aligned)
15079             for(iset=0;iset<nsets;iset++)
15080                 ajSeqsetFill(val[iset]);
15081 
15082         for(iset=0;iset<nsets;iset++)
15083             if(val[iset]->Rev)
15084                 ajSeqsetReverse(val[iset]);
15085 
15086 
15087         /* sequences have special set attributes */
15088 
15089         thys->SAttr = acdAttrListCount(acdCalcSeqsetall);
15090         thys->SetAttr = &acdCalcSeqsetall[0];
15091         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
15092 
15093         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqsetGetBegin(val[0]));
15094         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqsetGetEnd(val[0]));
15095         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqsetGetLen(val[0]));
15096         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN],
15097                       ajSeqsetIsProt(val[0]));
15098         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC],
15099                       ajSeqsetIsNuc(val[0]));
15100         ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], val[0]->Name);
15101         ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqsetGetUsa(val[0]));
15102         ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT],
15103                        ajSeqsetGetTotweight(val[0]), 3);
15104         ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], ajSeqsetGetSize(val[0]));
15105         ajStrFromInt(&thys->SetStr[ACD_SEQ_MULTICOUNT], nsets);
15106 
15107         acdInFileSave(acdReply, ajSeqsetGetNameS(val[0]), ajTrue);
15108 
15109         for(iattr=0; iattr < thys->SAttr; iattr++)
15110             ajDebug("CalcAttr %s: '%S'\n",
15111                     acdCalcSeqset[iattr].Name, thys->SetStr[iattr]);
15112     }
15113 
15114     thys->Value = val;
15115     ajStrAssignS(&thys->ValStr, acdReply);
15116 
15117     ajSeqinDel(&seqin);
15118     ajStrDel(&typestr);
15119 
15120     return;
15121 }
15122 
15123 
15124 
15125 
15126 /* @func ajAcdGetSeqout *******************************************************
15127 **
15128 ** Returns an item of type Seqout as defined in a named ACD item.
15129 ** Called by the application after all ACD values have been set,
15130 ** and simply returns what the ACD item already has.
15131 **
15132 ** @param [r] token [const char*] Text token name
15133 ** @return [AjPSeqout] Sequence output object. The file was already opened by
15134 **         acdSetSeqout so this just returns the pointer.
15135 ** @cre failure to find an item with the right name and type aborts.
15136 **
15137 ** @release 1.0.0
15138 ** @@
15139 ******************************************************************************/
15140 
ajAcdGetSeqout(const char * token)15141 AjPSeqout ajAcdGetSeqout(const char *token)
15142 {
15143     return acdGetValueRef(token, "seqout");
15144 }
15145 
15146 
15147 
15148 
15149 /* @funcstatic acdSetSeqout ***************************************************
15150 **
15151 ** Using the definition in the ACD file, and any values for the
15152 ** item or its associated qualifiers provided on the command line,
15153 ** prompts the user if necessary (and possible) and
15154 ** sets the actual value for an ACD sequence output item.
15155 **
15156 ** Understands all attributes and associated qualifiers for this item type.
15157 **
15158 ** The default value (if no other is available) is "stdout".
15159 **
15160 ** Associated qualifier "-osformat"
15161 ** is applied to the USA before opening the output file.
15162 **
15163 ** Associated qualifiers are defined but not yet implemented.
15164 **
15165 ** @param [u] thys [AcdPAcd] ACD item.
15166 ** @return [void]
15167 ** @see ajFileNewOut
15168 **
15169 ** @release 1.0.0
15170 ** @@
15171 ******************************************************************************/
15172 
acdSetSeqout(AcdPAcd thys)15173 static void acdSetSeqout(AcdPAcd thys)
15174 {
15175     AjPSeqout val = NULL;
15176 
15177     AjBool required = ajFalse;
15178     AjBool ok       = ajFalse;
15179 
15180     ajint itry;
15181     AjBool nullok;
15182     AjBool nulldefault;
15183 
15184     AjPStr name     = NULL;
15185     AjPStr ext      = NULL;
15186     AjPStr fmt      = NULL;
15187     AjPStr typestr  = NULL;
15188     AjBool osfeat;
15189 
15190     val = NULL;
15191 
15192     if(!acdGetValueAssoc(thys, "osname", &name))
15193 	acdAttrResolve(thys, "name", &name);
15194 
15195     if(!acdGetValueAssoc(thys, "osextension", &ext))
15196 	acdAttrResolve(thys, "extension", &ext);
15197 
15198     acdGetValueAssoc(thys, "osformat", &fmt);
15199     ajStrAssignEmptyS(&ext, fmt);
15200 
15201     if(!ajStrGetLen(ext))
15202 	ajSeqoutstrGetFormatDefault(&ext);
15203 
15204     acdAttrToBool(thys, "features", ajFalse, &osfeat);
15205 
15206     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
15207     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
15208 
15209     if(!acdAttrToStr(thys, "type", "", &typestr))
15210 	acdInTypeSeq(&typestr);
15211 
15212     required = acdIsRequired(thys);
15213     if(nullok && nulldefault)
15214     {
15215 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
15216 	    acdOutFilename(&acdReplyDef, name, ext);
15217 	else				/* leave empty */
15218 	    acdReplyInitC(thys, "", &acdReplyDef);
15219     }
15220     else
15221     {
15222 	acdOutFilename(&acdTmpOutFName, name, ext);
15223 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
15224     }
15225 
15226     ajStrDel(&name);
15227 
15228     acdPromptSeqout(thys);
15229 
15230     for(itry=acdPromptTry; itry && !ok; itry--)
15231     {
15232 	ok = ajTrue;	   /* accept the default if nothing changes */
15233 
15234 	ajStrAssignS(&acdReply, acdReplyDef);
15235 
15236 	if(required)
15237 	    acdUserGet(thys, &acdReply);
15238 
15239         if(ajStrGetLen(acdReply))
15240 	{
15241 	    val = ajSeqoutNew();	/* set the default value */
15242 
15243 	    ajSeqoutClearUsa(val, acdReply);	/* resets the AjPSeqout */
15244 	    val->Features = osfeat;
15245 	    acdGetValueAssoc(thys, "osdirectory", &val->Directory);
15246 	    acdGetValueAssoc(thys, "osdbname", &val->Setoutdb);
15247 
15248 	    acdOutDirectory(&val->Directory);
15249 	    acdLog("acdSetSeqout features: %B dir '%S'\n",
15250 		   val->Features, val->Directory);
15251 
15252 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
15253 
15254 	    if(!ajStrGetLen(val->Formatstr))
15255 		ajSeqoutstrGetFormatDefault(&val->Formatstr);
15256 
15257 	    ajStrAssignEmptyS(&val->Extension, ext);
15258 	    ajStrAssignEmptyS(&val->Extension, val->Formatstr);
15259 
15260 	    acdGetValueAssoc(thys, "oufo", &val->Ufo);
15261 	    acdGetValueAssoc(thys, "offormat", &val->Ftquery->Formatstr);
15262 
15263 	    if(!ajStrGetLen(val->Ftquery->Formatstr))
15264 		ajFeatOutFormatDefault(&val->Ftquery->Formatstr);
15265 
15266 	    acdGetValueAssoc(thys, "ofname", &val->Ftquery->Filename);
15267 	    acdGetValueAssoc(thys, "ofdirectory",
15268 			     &val->Ftquery->Directory);
15269 	    acdOutDirectory(&val->Ftquery->Directory);
15270 
15271 	    acdQualToBool(thys, "ossingle",
15272 			  ajFalse,
15273 			  &val->Single, &acdTmpStr);
15274 
15275 	    if(ajStrGetLen(typestr))
15276 		ajStrAssignS(&val->Outputtype, typestr);
15277 	    else
15278 	    {
15279 		if(!acdInTypeSeq(&val->Outputtype))
15280 		    ajWarn("No output type specified for '%S'", thys->Name);
15281 	    }
15282 
15283 	    if(!ajSeqoutOpen(val))
15284 	    {
15285 		if(ajStrGetLen(val->Directory))
15286 		    acdBadVal(thys, required,
15287 			      "Unable to write sequence to '%S%S'",
15288 			      val->Directory, acdReply);
15289 		else
15290 		    acdBadVal(thys, required,
15291 			      "Unable to write sequence to '%S'",
15292 			      acdReply);
15293 		ok = ajFalse;
15294 		ajSeqoutDel(&val);
15295 	    }
15296 	}
15297 	else
15298 	    if(!nullok)
15299 	    {
15300 		acdBadVal(thys, required,
15301 			  "Output USA is required");
15302 		ok = ajFalse;
15303 	    }
15304     }
15305 
15306     if(!ok)
15307 	acdBadRetry(thys);
15308 
15309     thys->Value = val;
15310     ajStrAssignS(&thys->ValStr, acdReply);
15311 
15312     if (val)
15313     {
15314 	acdLog("acdSetSeqout features: %B\n", val->Features);
15315 	if(val->Features)
15316 	    acdLog("acdSetSeqout with features UFO '%S'\n", val->Ufo);
15317     }
15318 
15319     ajStrDel(&typestr);
15320     ajStrDel(&fmt);
15321     ajStrDel(&ext);
15322 
15323     return;
15324 }
15325 
15326 
15327 
15328 
15329 /* @func ajAcdGetSeqoutall ****************************************************
15330 **
15331 ** Returns an item of type Seqoutall as defined in a named ACD item.
15332 ** Called by the application after all ACD values have been set,
15333 ** and simply returns what the ACD item already has.
15334 **
15335 ** @param [r] token [const char*] Text token name
15336 ** @return [AjPSeqout] Sequence output object. The file was already
15337 **         opened by acdSetSeqoutall so this just returns the pointer.
15338 ** @cre failure to find an item with the right name and type aborts.
15339 **
15340 ** @release 1.0.0
15341 ** @@
15342 ******************************************************************************/
15343 
ajAcdGetSeqoutall(const char * token)15344 AjPSeqout ajAcdGetSeqoutall(const char *token)
15345 {
15346     return acdGetValueRef(token, "seqoutall");
15347 }
15348 
15349 
15350 
15351 
15352 /* @funcstatic acdSetSeqoutall ************************************************
15353 **
15354 ** Using the definition in the ACD file, and any values for the
15355 ** item or its associated qualifiers provided on the command line,
15356 ** prompts the user if necessary (and possible) and
15357 ** sets the actual value for an ACD sequence output item.
15358 **
15359 ** Understands all attributes and associated qualifiers for this item type.
15360 **
15361 ** The default value (if no other is available) is "stdout".
15362 **
15363 ** Associated qualifier "-osformat"
15364 ** is applied to the USA before opening the output file.
15365 **
15366 ** @param [u] thys [AcdPAcd] ACD item.
15367 ** @return [void]
15368 ** @see ajFileNewOut
15369 **
15370 ** @release 1.0.0
15371 ** @@
15372 ******************************************************************************/
15373 
acdSetSeqoutall(AcdPAcd thys)15374 static void acdSetSeqoutall(AcdPAcd thys)
15375 {
15376     AjPSeqout val = NULL;
15377 
15378     AjBool required = ajFalse;
15379     AjBool ok       = ajFalse;
15380 
15381     ajint itry;
15382     AjBool nullok;
15383     AjBool nulldefault;
15384 
15385     AjPStr name     = NULL;
15386     AjPStr ext      = NULL;
15387     AjPStr fmt      = NULL;
15388     AjPStr typestr  = NULL;
15389     AjBool osfeat;
15390 
15391     val = NULL;
15392 
15393     if(!acdGetValueAssoc(thys, "osname", &name))
15394 	acdAttrResolve(thys, "name", &name);
15395 
15396     if(!acdGetValueAssoc(thys, "osextension", &ext))
15397 	acdAttrResolve(thys, "extension", &ext);
15398 
15399     acdGetValueAssoc(thys, "osformat", &fmt);
15400     ajStrAssignEmptyS(&ext, fmt);
15401 
15402     if(!ajStrGetLen(ext))
15403 	ajSeqoutstrGetFormatDefault(&ext);
15404 
15405 
15406     acdAttrToBool(thys, "features", ajFalse, &osfeat);
15407 
15408     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
15409     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
15410 
15411     if(!acdAttrToStr(thys, "type", "", &typestr))
15412 	acdInTypeSeq(&typestr);
15413 
15414     required = acdIsRequired(thys);
15415 
15416     if(nullok && nulldefault)
15417     {
15418 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
15419 	    acdOutFilename(&acdReplyDef, name, ext);
15420 	else				/* leave empty */
15421 	    acdReplyInitC(thys, "", &acdReplyDef);
15422     }
15423     else
15424     {
15425 	acdOutFilename(&acdTmpOutFName, name, ext);
15426         acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
15427     }
15428     ajStrDel(&name);
15429     acdPromptSeqout(thys);
15430 
15431     for(itry=acdPromptTry; itry && !ok; itry--)
15432     {
15433 	ok = ajTrue;	   /* accept the default if nothing changes */
15434 
15435 	ajStrAssignS(&acdReply, acdReplyDef);
15436 
15437 	if(required)
15438 	    acdUserGet(thys, &acdReply);
15439 
15440 	if(ajStrGetLen(acdReply))
15441 	{
15442 	    val = ajSeqoutNew();		/* set the default value */
15443 	    ajSeqoutClearUsa(val, acdReply);
15444 	    val->Features = osfeat;
15445 	    acdGetValueAssoc(thys, "osdirectory", &val->Directory);
15446 	    acdGetValueAssoc(thys, "osdbname", &val->Setoutdb);
15447 	    acdOutDirectory(&val->Directory);
15448 	    acdLog("acdSetSeqoutall features: %B\n", val->Features);
15449 
15450 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
15451 
15452 	    if(!ajStrGetLen(val->Formatstr))
15453 		ajSeqoutstrGetFormatDefault(&val->Formatstr);
15454 
15455 	    ajStrAssignEmptyS(&val->Extension, ext);
15456 	    ajStrAssignEmptyS(&val->Extension, val->Formatstr);
15457 
15458 	    acdGetValueAssoc(thys, "oufo", &val->Ufo);
15459 	    acdGetValueAssoc(thys, "offormat", &val->Ftquery->Formatstr);
15460 
15461 	    if(!ajStrGetLen(val->Ftquery->Formatstr))
15462 		ajFeatOutFormatDefault(&val->Ftquery->Formatstr);
15463 
15464 	    acdGetValueAssoc(thys, "ofname", &val->Ftquery->Filename);
15465 	    acdGetValueAssoc(thys, "ofdirectory",
15466 			     &val->Ftquery->Directory);
15467 	    acdOutDirectory(&val->Ftquery->Directory);
15468 
15469 	    acdLog("acdSetSeqoutall ossingle default: %B\n",
15470 		   ajSeqoutstrIsFormatSingle(val->Formatstr));
15471 
15472 	    acdQualToBool(thys, "ossingle",
15473 			  ajSeqoutstrIsFormatSingle(val->Formatstr),
15474 			  &val->Single, &acdTmpStr);
15475 	    acdLog("acdSetSeqoutall ossingle value %B '%S'\n",
15476 		   val->Single, acdTmpStr);
15477 
15478 	    if(ajStrGetLen(typestr))
15479 		ajStrAssignS(&val->Outputtype, typestr);
15480 	    else
15481 	    {
15482 		if(!acdInTypeSeq(&val->Outputtype))
15483 		    ajWarn("No output type specified for '%S'", thys->Name);
15484 	    }
15485 
15486 	    if(!ajSeqoutOpen(val))
15487 	    {
15488 		if(ajStrGetLen(val->Directory))
15489 		    acdBadVal(thys, required,
15490 			      "Unable to write sequence to '%S%S'",
15491 			      val->Directory, acdReply);
15492 		else
15493 		    acdBadVal(thys, required,
15494 			      "Unable to write sequence to '%S'",
15495 			      acdReply);
15496 		ok = ajFalse;
15497 		ajSeqoutDel(&val);
15498 	    }
15499 	}
15500 	else
15501 	    if(!nullok)
15502 	    {
15503 		acdBadVal(thys, required,
15504 			  "Output USA is required");
15505 		ok = ajFalse;
15506 	    }
15507     }
15508 
15509     if(!ok)
15510 	acdBadRetry(thys);
15511 
15512     thys->Value = val;
15513     ajStrAssignS(&thys->ValStr, acdReply);
15514 
15515     ajStrDel(&typestr);
15516     ajStrDel(&fmt);
15517     ajStrDel(&ext);
15518 
15519     return;
15520 }
15521 
15522 
15523 
15524 
15525 /* @func ajAcdGetSeqoutset ****************************************************
15526 **
15527 ** Returns an item of type Seqoutset as defined in a named ACD item.
15528 ** Called by the application after all ACD values have been set,
15529 ** and simply returns what the ACD item already has.
15530 **
15531 ** @param [r] token [const char*] Text token name
15532 ** @return [AjPSeqout] Sequence output object. The file was already
15533 **        opened by acdSetSeqoutset so this just returns the pointer.
15534 ** @cre failure to find an item with the right name and type aborts.
15535 **
15536 ** @release 1.0.0
15537 ** @@
15538 ******************************************************************************/
15539 
ajAcdGetSeqoutset(const char * token)15540 AjPSeqout ajAcdGetSeqoutset(const char *token)
15541 {
15542     return acdGetValueRef(token, "seqoutset");
15543 }
15544 
15545 
15546 
15547 
15548 /* @funcstatic acdSetSeqoutset ************************************************
15549 **
15550 ** Using the definition in the ACD file, and any values for the
15551 ** item or its associated qualifiers provided on the command line,
15552 ** prompts the user if necessary (and possible) and
15553 ** sets the actual value for an ACD sequence output item.
15554 **
15555 ** Understands all attributes and associated qualifiers for this item type.
15556 **
15557 ** The default value (if no other is available) is "stdout".
15558 **
15559 ** Associated qualifier "-osformat"
15560 ** is applied to the USA before opening the output file.
15561 **
15562 ** Associated qualifiers are defined but not yet implemented.
15563 **
15564 ** @param [u] thys [AcdPAcd] ACD item.
15565 ** @return [void]
15566 ** @see ajFileNewOut
15567 **
15568 ** @release 1.0.0
15569 ** @@
15570 ******************************************************************************/
15571 
acdSetSeqoutset(AcdPAcd thys)15572 static void acdSetSeqoutset(AcdPAcd thys)
15573 {
15574     AjPSeqout val = NULL;
15575 
15576     AjBool required = ajFalse;
15577     AjBool ok       = ajFalse;
15578     AjBool nullok;
15579     AjBool nulldefault;
15580 
15581     ajint itry;
15582 
15583     AjPStr name     = NULL;
15584     AjPStr ext      = NULL;
15585     AjPStr fmt      = NULL;
15586     AjPStr typestr  = NULL;
15587     AjBool osfeat;
15588 
15589     val = NULL;
15590 
15591     if(!acdGetValueAssoc(thys, "osname", &name))
15592 	acdAttrResolve(thys, "name", &name);
15593 
15594     if(!acdGetValueAssoc(thys, "osextension", &ext))
15595 	acdAttrResolve(thys, "extension", &ext);
15596 
15597     acdGetValueAssoc(thys, "osformat", &fmt);
15598     ajStrAssignEmptyS(&ext, fmt);
15599 
15600     if(!ajStrGetLen(ext))
15601 	ajSeqoutstrGetFormatDefault(&ext);
15602 
15603     acdAttrToBool(thys, "features", ajFalse, &osfeat);
15604 
15605     required = acdIsRequired(thys);
15606     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
15607     acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault);
15608 
15609     if(!acdAttrToStr(thys, "type", "", &typestr))
15610 	acdInTypeSeq(&typestr);
15611 
15612     if(nullok && nulldefault)
15613     {
15614 	if (acdDefinedEmpty(thys))  /* user set to empty - make default name */
15615 	    acdOutFilename(&acdReplyDef, name, ext);
15616 	else				/* leave empty */
15617 	    acdReplyInitC(thys, "", &acdReplyDef);
15618     }
15619     else
15620     {
15621 	acdOutFilename(&acdTmpOutFName, name, ext);
15622 	acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef);
15623     }
15624     ajStrDel(&name);
15625 
15626     acdPromptSeqout(thys);
15627 
15628     for(itry=acdPromptTry; itry && !ok; itry--)
15629     {
15630 	ok = ajTrue;	   /* accept the default if nothing changes */
15631 
15632 	ajStrAssignS(&acdReply, acdReplyDef);
15633 
15634 	if(required)
15635 	    acdUserGet(thys, &acdReply);
15636 
15637 	if(ajStrGetLen(acdReply))
15638 	{
15639 	    val = ajSeqoutNew();		/* set the default value */
15640 
15641 	    ajSeqoutClearUsa(val, acdReply);
15642 	    acdGetValueAssoc(thys, "osdbname", &val->Setoutdb);
15643 	    val->Features = osfeat;
15644 	    acdGetValueAssoc(thys, "osdirectory", &val->Directory);
15645 	    acdOutDirectory(&val->Directory);
15646 	    acdLog("acdSetSeqoutset features: %B\n", val->Features);
15647 
15648 	    ajStrAssignEmptyS(&val->Formatstr, fmt);
15649 
15650 	    if(!ajStrGetLen(val->Formatstr))
15651 		ajSeqoutstrGetFormatDefault(&val->Formatstr);
15652 
15653 	    ajStrAssignEmptyS(&val->Extension, ext);
15654 	    ajStrAssignEmptyS(&val->Extension, val->Formatstr);
15655 
15656 	    acdGetValueAssoc(thys, "oufo", &val->Ufo);
15657 	    acdGetValueAssoc(thys, "offormat", &val->Ftquery->Formatstr);
15658 	    if(!ajStrGetLen(val->Ftquery->Formatstr))
15659 		ajFeatOutFormatDefault(&val->Ftquery->Formatstr);
15660 	    acdGetValueAssoc(thys, "ofname", &val->Ftquery->Filename);
15661 	    acdGetValueAssoc(thys, "ofdirectory",
15662 			     &val->Ftquery->Directory);
15663 	    acdOutDirectory(&val->Ftquery->Directory);
15664 
15665 	    acdQualToBool(thys, "ossingle",
15666 			  ajSeqoutstrIsFormatSingle(val->Formatstr),
15667 			  &val->Single, &acdTmpStr);
15668 
15669 	    if(ajStrGetLen(typestr))
15670 		ajStrAssignS(&val->Outputtype, typestr);
15671 	    else
15672 	    {
15673 		if(!acdInTypeSeq(&val->Outputtype))
15674 		    ajWarn("No output type specified for '%S'", thys->Name);
15675 	    }
15676 
15677 	    if(!ajSeqoutOpen(val))
15678 	    {
15679 		if(ajStrGetLen(val->Directory))
15680 		    acdBadVal(thys, required,
15681 			      "Unable to write sequence to '%S%S'",
15682 			      val->Directory, acdReply);
15683 		else
15684 		    acdBadVal(thys, required,
15685 			      "Unable to write sequence to '%S'",
15686 			      acdReply);
15687 
15688 		ok = ajFalse;
15689 		ajSeqoutDel(&val);
15690 	    }
15691 	}
15692 	else
15693 	    if(!nullok)
15694 	    {
15695 		acdBadVal(thys, required,
15696 			  "Output USA is required");
15697 		ok = ajFalse;
15698 	    }
15699     }
15700 
15701     if(!ok)
15702 	acdBadRetry(thys);
15703 
15704     thys->Value = val;
15705     ajStrAssignS(&thys->ValStr, acdReply);
15706 
15707     ajStrDel(&typestr);
15708     ajStrDel(&fmt);
15709     ajStrDel(&ext);
15710 
15711     return;
15712 }
15713 
15714 
15715 
15716 
15717 /* @func ajAcdGetSeqset *******************************************************
15718 **
15719 ** Returns an item of type Seqset as defined in a named ACD item.
15720 ** Called by the application after all ACD values have been set,
15721 ** and simply returns what the ACD item already has.
15722 **
15723 ** @param [r] token [const char*] Text token name
15724 ** @return [AjPSeqset] Sequence set object. The sequence was already loaded by
15725 **         acdSetSeqset so this just returns the pointer.
15726 ** @cre failure to find an item with the right name and type aborts.
15727 **
15728 ** @release 1.0.0
15729 ** @@
15730 ******************************************************************************/
15731 
ajAcdGetSeqset(const char * token)15732 AjPSeqset ajAcdGetSeqset(const char *token)
15733 {
15734     return acdGetValueRef(token, "seqset");
15735 }
15736 
15737 
15738 
15739 
15740 /* @funcstatic acdSetSeqset ***************************************************
15741 **
15742 ** Using the definition in the ACD file, and any values for the
15743 ** item or its associated qualifiers provided on the command line,
15744 ** prompts the user if necessary (and possible) and
15745 ** sets the actual value for an ACD sequence item.
15746 **
15747 ** Understands all attributes and associated qualifiers for this item type.
15748 **
15749 ** The default value (if no other available) is a null string, which
15750 ** is invalid.
15751 **
15752 ** Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid"
15753 ** are applied to the USA before reading the sequence.
15754 **
15755 ** Associated qualifiers "-supper", "-slower" and "-sask" are applied
15756 ** after reading.
15757 **
15758 ** Associated qualifiers "-sbegin", "-send" and "-sreverse"
15759 ** are applied as appropriate, with prompting for values,
15760 ** after the sequence has been read. They are applied to the sequence,
15761 ** and the resulting sequence is what is set in the ACD item.
15762 **
15763 ** @param [u] thys [AcdPAcd] ACD item.
15764 ** @return [void]
15765 ** @see ajSeqRead
15766 **
15767 ** @release 1.0.0
15768 ** @@
15769 ******************************************************************************/
15770 
acdSetSeqset(AcdPAcd thys)15771 static void acdSetSeqset(AcdPAcd thys)
15772 {
15773     AjPSeqset val = NULL;
15774     AjPSeqin seqin;
15775 
15776     AjBool required = ajFalse;
15777     AjBool ok       = ajFalse;
15778     AjBool okbeg    = ajFalse;
15779     AjBool okend    = ajFalse;
15780     AjBool okrev    = ajFalse;
15781     AjBool aligned  = ajFalse;
15782 
15783     ajint itry;
15784 
15785     AjPStr infname = NULL;
15786 
15787     ajint sqbegin = 0;
15788     ajint sqend   = 0;
15789     AjBool sreverse = ajFalse;
15790     AjBool sprompt  = ajFalse;
15791     AjBool snuc     = ajFalse;
15792     AjBool sprot    = ajFalse;
15793     AjBool nullok   = ajFalse;
15794     AjPStr typestr  = NULL;
15795 
15796     val   = ajSeqsetNew();		/* set the default value */
15797     seqin = ajSeqinNew();		/* set the default value */
15798 
15799     seqin->Input->Multi = ajTrue;
15800 
15801     acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef);
15802     acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef);
15803     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
15804     acdAttrToBool(thys, "aligned", ajFalse, &aligned);
15805     acdAttrToStr(thys, "type", "", &typestr);
15806 
15807     acdInFilename(&infname);
15808     required = acdIsRequired(thys);
15809     acdReplyInitS(thys, infname, &acdReplyDef);
15810     acdPromptSeq(thys);
15811     ajStrDel(&infname);
15812 
15813     for(itry=acdPromptTry; itry && !ok; itry--)
15814     {
15815 	ok = ajTrue;	   /* accept the default if nothing changes */
15816 
15817 	ajStrAssignS(&acdReply, acdReplyDef);
15818 
15819 	if(required)
15820 	    acdUserGet(thys, &acdReply);
15821 
15822 
15823 	if(!ajStrGetLen(acdReply) && nullok)
15824         {
15825             ajSeqsetDel(&val);
15826 	    break;
15827         }
15828 
15829 	ajSeqinUsa(&seqin, acdReply);
15830 
15831 	if(ajStrGetLen(typestr))
15832 	{
15833 	    ajStrAssignS(&seqin->Inputtype, typestr);
15834 	    acdInTypeSeqSave(seqin->Inputtype);
15835 	}
15836 	else
15837 	    acdInTypeSeqSave(NULL);
15838 
15839 	acdAttrToBool(thys, "features", ajFalse, &seqin->Features);
15840 
15841 	acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr);
15842 	acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db);
15843 /*	acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */
15844 	acdGetValueAssoc(thys, "sid", &seqin->Entryname);
15845 	acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields);
15846 	acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos,
15847                       &acdTmpStr);
15848 
15849 	acdGetValueAssoc(thys, "ufo", &seqin->Ufo);
15850 	acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr);
15851 	acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename);
15852 
15853 	acdQualToBool(thys, "squick", ajFalse,
15854 		      &seqin->Minimal, &acdTmpStr);
15855 	acdQualToBool(thys, "scircular", ajFalse,
15856 		      &seqin->Circular, &acdTmpStr);
15857 	acdQualToBool(thys, "supper", ajFalse,
15858 		      &seqin->Upper, &acdTmpStr);
15859 	acdQualToBool(thys, "slower", ajFalse,
15860 		      &seqin->Lower, &acdTmpStr);
15861 	okbeg = acdQualToSeqbegin(thys, "sbegin", 0,
15862 				  &seqin->Begin, &acdTmpStr);
15863 	okend = acdQualToSeqend(thys, "send", 0,
15864 				&seqin->End, &acdTmpStr);
15865 	okrev = acdQualToBool(thys, "sreverse", ajFalse,
15866 			      &sreverse, &acdTmpStr);
15867 
15868 	if(snuc)
15869 	    ajSeqinSetNuc(seqin);
15870 
15871 	if(sprot)
15872 	    ajSeqinSetProt(seqin);
15873 
15874 	if(ajStrGetLen(seqin->Ufo))
15875 	    seqin->Features = ajTrue;
15876 
15877 	ok = ajSeqsetRead(val, seqin);
15878 
15879 	if(!ok)
15880 	    acdBadVal(thys, required,
15881 		      "Unable to read sequence '%S'", acdReply);
15882     }
15883 
15884     if(!ok)
15885 	acdBadRetry(thys);
15886 
15887     acdInFileSave(acdReply, ajSeqsetGetNameS(val),
15888                   ajTrue);      /* save sequence name */
15889 
15890     acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef);
15891 
15892     if(val)
15893     {
15894 
15895         /* now process the begin, end and reverse options */
15896 
15897         if(seqin->Begin)
15898         {
15899             okbeg = ajTrue;
15900             val->Begin = seqin->Begin;
15901         }
15902 
15903         for(itry=acdPromptTry; itry && !okbeg; itry--)
15904         {
15905             ajStrAssignC(&acdReplyPrompt, "start");
15906 
15907             if(sprompt)
15908                 acdUserGetPrompt(thys, "sbegin",
15909                                  " Begin at position", &acdReplyPrompt);
15910             if(ajStrMatchCaseC(acdReplyPrompt, "start"))
15911                 ajStrAssignC(&acdReplyPrompt, "0");
15912 
15913             okbeg = ajStrToInt(acdReplyPrompt, &sqbegin);
15914 
15915             if(!okbeg)
15916                 acdBadVal(thys, sprompt,
15917                           "Invalid integer value '%S'", acdReplyPrompt);
15918         }
15919 
15920         if(!okbeg)
15921             acdBadRetry(thys);
15922 
15923         if(sqbegin)
15924         {
15925             seqin->Begin = sqbegin;
15926             val->Begin = sqbegin;
15927             acdSetQualDefInt(thys, "sbegin", sqbegin);
15928         }
15929 
15930         if(seqin->End)
15931         {
15932             okend = ajTrue;
15933             val->End = seqin->End;
15934         }
15935 
15936         for(itry=acdPromptTry; itry && !okend; itry--)
15937         {
15938             ajStrAssignC(&acdReplyPrompt, "end");
15939 
15940             if(sprompt)
15941                 acdUserGetPrompt(thys, "send",
15942                                  "   End at position", &acdReplyPrompt);
15943 
15944             if(ajStrMatchCaseC(acdReplyPrompt, "end"))
15945                 ajStrAssignC(&acdReplyPrompt, "0");
15946 
15947             okend = ajStrToInt(acdReplyPrompt, &sqend);
15948 
15949             if(!okend)
15950                 acdBadVal(thys, sprompt,
15951                           "Invalid integer value '%S'", acdReplyPrompt);
15952         }
15953 
15954         if(!okend)
15955             acdBadRetry(thys);
15956 
15957         if(sqend)
15958         {
15959             seqin->End = sqend;
15960             val->End = sqend;
15961             acdSetQualDefInt(thys, "send", sqend);
15962         }
15963 
15964         if(ajSeqsetGetSize(val) && ajSeqsetIsNuc(val))
15965         {
15966             for(itry=acdPromptTry; itry && !okrev; itry--)
15967             {
15968                 ajStrAssignC(&acdReplyPrompt, "N");
15969 
15970                 if(sprompt)
15971                     acdUserGetPrompt(thys, "sreverse",
15972                                      "    Reverse strand", &acdReplyPrompt);
15973 
15974                 okrev = ajStrToBool(acdReplyPrompt, &sreverse);
15975 
15976                 if(!okrev)
15977                     acdBadVal(thys, sprompt,
15978                               "Invalid Y/N value '%S'", acdReplyPrompt);
15979             }
15980 
15981             if(!okrev)
15982                 acdBadRetry(thys);
15983 
15984             if(sreverse)
15985             {
15986                 seqin->Rev = sreverse;
15987                 val->Rev = sreverse;
15988                 acdSetQualDefBool(thys, "sreverse", sreverse);
15989             }
15990         }
15991 
15992         acdLog("sbegin: %d, send: %d, sreverse: %B\n",
15993                sqbegin, sqend, sreverse);
15994 
15995         if(val && aligned)
15996             ajSeqsetFill(val);
15997 
15998         if(val && val->Rev)
15999             ajSeqsetReverse(val);
16000 
16001         /* sequences have special set attributes */
16002 
16003         thys->SAttr = acdAttrListCount(acdCalcSeqset);
16004         thys->SetAttr = &acdCalcSeqset[0];
16005         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
16006 
16007         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqsetGetBegin(val));
16008         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqsetGetEnd(val));
16009         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqsetGetLen(val));
16010         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqsetIsProt(val));
16011         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqsetIsNuc(val));
16012         if(ajStrGetLen(val->Name))
16013             ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME],
16014                          val->Name);
16015         else
16016             ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME],
16017                          ajSeqsetGetseqNameS(val,0));
16018         ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqsetGetUsa(val));
16019         ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT],
16020                        ajSeqsetGetTotweight(val), 3);
16021         ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], ajSeqsetGetSize(val));
16022 
16023         acdInFileSave(acdReply, ajSeqsetGetNameS(val), ajTrue);
16024     }
16025     else
16026     {
16027        /* sequences have special set attributes */
16028 
16029         thys->SAttr = acdAttrListCount(acdCalcSeqset);
16030         thys->SetAttr = &acdCalcSeq[0];
16031         thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
16032 
16033         ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0);
16034         ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0);
16035         ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0);
16036         ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse);
16037         ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse);
16038         ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], "");
16039         ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], "");
16040         ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT],
16041                        0.0, 3);
16042         ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], 0);
16043     }
16044 
16045     thys->Value = val;
16046     ajStrAssignS(&thys->ValStr, acdReply);
16047 
16048     ajSeqinDel(&seqin);
16049     ajStrDel(&typestr);
16050 
16051     return;
16052 }
16053 
16054 
16055 
16056 
16057 /* @func ajAcdGetSeqsetall ****************************************************
16058 **
16059 ** Returns an item of type Seqset array as defined in a named ACD item.
16060 ** The array is terminated by a NULL.
16061 **
16062 ** Called by the application after all ACD values have been set,
16063 ** and simply returns what the ACD item already has.
16064 **
16065 ** @param [r] token [const char*] Text token name
16066 ** @return [AjPSeqset*] Sequence setall object.
16067 **         The sequence was already loaded by
16068 **         acdSetSeqset so this just returns the pointer.
16069 ** @cre failure to find an item with the right name and type aborts.
16070 **
16071 ** @release 2.8.0
16072 ** @@
16073 ******************************************************************************/
16074 
ajAcdGetSeqsetall(const char * token)16075 AjPSeqset* ajAcdGetSeqsetall(const char *token)
16076 {
16077     return acdGetValueRef(token, "seqsetall");
16078 }
16079 
16080 
16081 
16082 
16083 /* @func ajAcdGetSeqsetallSingle **********************************************
16084 **
16085 ** Returns an item of type Seqset as defined in a named ACD item.
16086 ** Called by the application after all ACD values have been set,
16087 ** and simply returns what the ACD item already has.
16088 **
16089 ** @param [r] token [const char*] Text token name
16090 ** @return [AjPSeqset] Sequence set object. The sequence was already loaded by
16091 **         acdSetSeqset so this just returns the pointer.
16092 ** @cre failure to find an item with the right name and type aborts.
16093 **
16094 ** @release 4.0.0
16095 ** @@
16096 ******************************************************************************/
16097 
ajAcdGetSeqsetallSingle(const char * token)16098 AjPSeqset ajAcdGetSeqsetallSingle(const char *token)
16099 {
16100     AjPSeqset *val;
16101     ajint i;
16102 
16103     val = acdGetValueSingle(token, "seqsetall");
16104 
16105     for(i=0; val[i]; i++)
16106 	continue;
16107 
16108     if(i > 1)
16109 	ajWarn("Single list value %s, but can choose %d values",
16110 	       token, i);
16111 
16112     if(i < 1)
16113 	ajWarn("Single list value %s, no value found: returning NULL value",
16114 	       token);
16115 
16116     return val[0];
16117 }
16118 
16119 
16120 
16121 
16122 /* @func ajAcdGetString *******************************************************
16123 **
16124 ** Returns an item of type String as defined in a named ACD item.
16125 ** Called by the application after all ACD values have been set,
16126 ** and simply returns what the ACD item already has.
16127 **
16128 ** @param [r] token [const char*] Text token name
16129 ** @return [AjPStr] String object. The string was already set by
16130 **         acdSetString so this just returns the pointer.
16131 ** @cre failure to find an item with the right name and type aborts.
16132 **
16133 ** @release 1.0.0
16134 ** @@
16135 ******************************************************************************/
16136 
ajAcdGetString(const char * token)16137 AjPStr ajAcdGetString(const char *token)
16138 {
16139     return acdGetValueRef(token, "string");
16140 }
16141 
16142 
16143 
16144 
16145 /* @funcstatic acdSetString ***************************************************
16146 **
16147 ** Using the definition in the ACD file, and any values for the
16148 ** item or its associated qualifiers provided on the command line,
16149 ** prompts the user if necessary (and possible) and
16150 ** sets the actual value for an ACD string item.
16151 **
16152 ** Understands all attributes and associated qualifiers for this item type.
16153 **
16154 ** The default value (if no other is available) is an empty string.
16155 **
16156 ** Attributes for minimum and maximum length are applied with error
16157 ** messages if exceeded.
16158 **
16159 ** @param [u] thys [AcdPAcd] ACD item.
16160 ** @return [void]
16161 ** @see ajFileNewOut
16162 **
16163 ** @release 1.0.0
16164 ** @@
16165 ******************************************************************************/
16166 
acdSetString(AcdPAcd thys)16167 static void acdSetString(AcdPAcd thys)
16168 {
16169     AjPStr val;
16170 
16171     AjBool required = ajFalse;
16172     AjBool ok       = ajFalse;
16173 
16174     AjPStr pattern  = NULL;
16175     AjBool upper;
16176     AjBool lower;
16177     AjBool word;
16178     ajint itry;
16179 
16180     AjPRegexp patexp = NULL;
16181 
16182     ajint minlen;
16183     ajint maxlen;
16184     ajint len;
16185 
16186     val = ajStrNew();			/* set the default value */
16187 
16188     acdAttrToInt(thys, "minlength", 0, &minlen);
16189     acdAttrToInt(thys, "maxlength", INT_MAX, &maxlen);
16190     acdAttrToStr(thys, "pattern", "", &pattern);
16191     acdAttrToBool(thys, "upper", ajFalse, &upper);
16192     acdAttrToBool(thys, "lower", ajFalse, &lower);
16193     acdAttrToBool(thys, "word",  ajFalse, &word);
16194 
16195     if(ajStrGetLen(pattern))
16196 	patexp = ajRegComp(pattern);
16197 
16198     required = acdIsRequired(thys);
16199     acdReplyInitC(thys, "", &acdReplyDef);
16200 
16201     for(itry=acdPromptTry; itry && !ok; itry--)
16202     {
16203 	ok = ajTrue;	   /* accept the default if nothing changes */
16204 
16205 	ajStrAssignS(&acdReply, acdReplyDef);
16206 
16207 	if(required)
16208 	    acdUserGet(thys, &acdReply);
16209 
16210 	len = ajStrGetLen(acdReply);
16211 
16212 	if(len < minlen)
16213 	{
16214 	    acdBadVal(thys, required,
16215 		      "Too short (%S) - minimum length is %d characters",
16216 		      thys->Name, minlen);
16217 	    ok = ajFalse;
16218 	}
16219 
16220 	if(len > maxlen)
16221 	{
16222 	    acdBadVal(thys, required,
16223 		      "Too long (%S) - maximum length is %d characters",
16224 		      thys->Name, maxlen);
16225 	    ok = ajFalse;
16226 	}
16227 
16228 	if(patexp && !ajRegExec(patexp, acdReply))
16229 	{
16230 	    acdBadVal(thys, required,
16231 		      "String does not match pattern '%S'",
16232 		      pattern);
16233 	    ok = ajFalse;
16234 	}
16235 
16236 	if(word && !(ajStrIsWord(acdReply)))
16237 	{
16238 	    acdBadVal(thys, required,
16239 		      "String contains disallowed whitespace characters");
16240 	    ok = ajFalse;
16241 	}
16242     }
16243 
16244     if(!ok)
16245 	acdBadRetry(thys);
16246 
16247     if(patexp)
16248 	ajRegFree(&patexp);
16249 
16250     if(upper)
16251 	ajStrFmtUpper(&val);
16252 
16253     if(lower)
16254 	ajStrFmtLower(&val);
16255 
16256     /* strings have special set attributes */
16257 
16258     thys->SAttr = acdAttrListCount(acdCalcString);
16259     thys->SetAttr = &acdCalcString[0];
16260     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
16261 
16262     ajStrFromInt(&thys->SetStr[0], ajStrGetLen(acdReply));
16263 
16264     ajStrAssignS(&val, acdReply);
16265     thys->Value = val;
16266     ajStrAssignS(&thys->ValStr, val);
16267 
16268     ajStrDel(&pattern);
16269     return;
16270 }
16271 
16272 
16273 
16274 
16275 /* @func ajAcdGetTaxon ********************************************************
16276 **
16277 ** Returns an item of type Taxon as defined in a named ACD item.
16278 ** Called by the application after all ACD values have been set,
16279 ** and simply returns what the ACD item already has.
16280 **
16281 ** @param [r] token [const char*] Text token name
16282 ** @return [AjPTax] Taxon object
16283 ** @cre failure to find an item with the right name and type aborts.
16284 **
16285 ** @release 6.4.0
16286 ** @@
16287 ******************************************************************************/
16288 
ajAcdGetTaxon(const char * token)16289 AjPTax ajAcdGetTaxon(const char *token)
16290 {
16291     AjPTaxall val = acdGetValue(token, "taxon");
16292     if(val->Multi)
16293         ajWarn("ajAcdGetTaxon request single taxon but maxreads > 1");
16294 
16295     val->Returned = ajTrue;
16296 
16297     return val->Tax;
16298 }
16299 
16300 
16301 
16302 
16303 /* @func ajAcdGetTaxonall *****************************************************
16304 **
16305 ** Returns an input stream of an item of type Taxon as defined in a
16306 ** named ACD item.
16307 ** Called by the application after all ACD values have been set,
16308 ** and simply returns what the ACD item already has.
16309 **
16310 ** @param [r] token [const char*] Text token name
16311 ** @return [AjPTaxall] Taxon input stream
16312 ** @cre failure to find an item with the right name and type aborts.
16313 **
16314 ** @release 6.4.0
16315 ** @@
16316 ******************************************************************************/
16317 
ajAcdGetTaxonall(const char * token)16318 AjPTaxall ajAcdGetTaxonall(const char *token)
16319 {
16320     AjPTaxall val = acdGetValueRef(token, "taxon");
16321 
16322     if(!val->Multi)
16323         ajWarn("ajAcdGetTaxonall request taxon input stream but maxreads is 1");
16324 
16325     return val;
16326 }
16327 
16328 
16329 
16330 
16331 /* @funcstatic acdSetTaxon ****************************************************
16332 **
16333 ** Using the definition in the ACD file, and any values for the
16334 ** item or its associated qualifiers provided on the command line,
16335 ** prompts the user if necessary (and possible) and
16336 ** sets the actual value for an ACD taxon input
16337 **
16338 ** Understands all attributes and associated qualifiers for this item type.
16339 **
16340 ** @param [u] thys [AcdPAcd] ACD item.
16341 ** @return [void]
16342 **
16343 ** @release 6.4.0
16344 ** @@
16345 ******************************************************************************/
16346 
acdSetTaxon(AcdPAcd thys)16347 static void acdSetTaxon(AcdPAcd thys)
16348 {
16349     AjPTaxall val;
16350 
16351     AjBool required = ajFalse;
16352     AjBool ok       = ajFalse;
16353     AjBool nullok   = ajFalse;
16354     ajint itry;
16355 
16356     ajint maxreads;
16357 
16358     AjPStr infname = NULL;
16359 
16360     val = ajTaxallNew();        /* set the default value */
16361 
16362     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
16363     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
16364 
16365     acdInFilename(&infname);
16366     required = acdIsRequired(thys);
16367     acdReplyInitS(thys, infname, &acdReplyDef);
16368     ajStrDel(&infname);
16369 
16370     acdAttrToBool(thys, "entry", ajFalse, &val->Taxin->Input->Text);
16371 
16372     for(itry=acdPromptTry; itry && !ok; itry--)
16373     {
16374 	ok = ajTrue;	   /* accept the default if nothing changes */
16375 
16376 	ajStrAssignS(&acdReply, acdReplyDef);
16377 
16378 	if(required)
16379 	    acdUserGet(thys, &acdReply);
16380 
16381 	if(!ajStrGetLen(acdReply) && nullok)
16382         {
16383             ajTaxallDel(&val);
16384 	    break;
16385 	}
16386 
16387 	ajTaxinQryS(val->Taxin, acdReply);
16388 
16389 	acdGetValueAssoc(thys, "iformat", &val->Taxin->Input->Formatstr);
16390 	acdGetValueAssoc(thys, "iquery", &val->Taxin->Input->QryFields);
16391 	acdQualToLong(thys, "ioffset", 0L, &val->Taxin->Input->Fpos,
16392                       &acdTmpStr);
16393 
16394         ok = ajTaxinRead(val->Taxin, val->Tax);
16395     }
16396 
16397     if(!ok)
16398 	acdBadRetry(thys);
16399 
16400     if(maxreads > 1)
16401         val->Multi = ajTrue;
16402 
16403     acdInFileSave(acdReply, ajTaxallGettaxId(val), ajTrue);
16404 
16405     thys->Value = val;
16406     ajStrAssignS(&thys->ValStr, acdReply);
16407 
16408     return;
16409 }
16410 
16411 
16412 
16413 
16414 /* @func ajAcdGetText *********************************************************
16415 **
16416 ** Returns an item of type Text as defined in a named ACD item.
16417 ** Called by the application after all ACD values have been set,
16418 ** and simply returns what the ACD item already has.
16419 **
16420 ** @param [r] token [const char*] Text token name
16421 ** @return [AjPText] Text object
16422 ** @cre failure to find an item with the right name and type aborts.
16423 **
16424 ** @release 6.4.0
16425 ** @@
16426 ******************************************************************************/
16427 
ajAcdGetText(const char * token)16428 AjPText ajAcdGetText(const char *token)
16429 {
16430     AjPTextall val = acdGetValue(token, "text");
16431     if(val->Multi)
16432         ajWarn("ajAcdGetText request single text entry but maxreads > 1");
16433 
16434     val->Returned = ajTrue;
16435 
16436     return val->Text;
16437 }
16438 
16439 
16440 
16441 
16442 /* @func ajAcdGetTextall ******************************************************
16443 **
16444 ** Returns an input stream of an item of type Text as defined in a
16445 ** named ACD item.
16446 ** Called by the application after all ACD values have been set,
16447 ** and simply returns what the ACD item already has.
16448 **
16449 ** @param [r] token [const char*] Text token name
16450 ** @return [AjPTextall] Text input stream
16451 ** @cre failure to find an item with the right name and type aborts.
16452 **
16453 ** @release 6.4.0
16454 ** @@
16455 ******************************************************************************/
16456 
ajAcdGetTextall(const char * token)16457 AjPTextall ajAcdGetTextall(const char *token)
16458 {
16459     AjPTextall val = acdGetValueRef(token, "text");
16460 
16461     if(!val->Multi)
16462         ajWarn("ajAcdGetTextall request text input stream but maxreads is 1");
16463 
16464     return val;
16465 }
16466 
16467 
16468 
16469 
16470 /* @funcstatic acdSetText *****************************************************
16471 **
16472 ** Using the definition in the ACD file, and any values for the
16473 ** item or its associated qualifiers provided on the command line,
16474 ** prompts the user if necessary (and possible) and
16475 ** sets the actual value for an ACD text input
16476 **
16477 ** Understands all attributes and associated qualifiers for this item type.
16478 **
16479 ** @param [u] thys [AcdPAcd] ACD item.
16480 ** @return [void]
16481 **
16482 ** @release 6.4.0
16483 ** @@
16484 ******************************************************************************/
16485 
acdSetText(AcdPAcd thys)16486 static void acdSetText(AcdPAcd thys)
16487 {
16488     AjPTextall val;
16489 
16490     AjBool required = ajFalse;
16491     AjBool ok       = ajFalse;
16492     AjBool nullok   = ajFalse;
16493     ajint itry;
16494 
16495     ajint maxreads;
16496 
16497     AjPStr infname = NULL;
16498 
16499     val = ajTextallNew();        /* set the default value */
16500 
16501     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
16502     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
16503 
16504     acdInFilename(&infname);
16505     required = acdIsRequired(thys);
16506     acdReplyInitS(thys, infname, &acdReplyDef);
16507     ajStrDel(&infname);
16508 
16509     for(itry=acdPromptTry; itry && !ok; itry--)
16510     {
16511 	ok = ajTrue;	   /* accept the default if nothing changes */
16512 
16513 	ajStrAssignS(&acdReply, acdReplyDef);
16514 
16515 	if(required)
16516 	    acdUserGet(thys, &acdReply);
16517 
16518 	if(!ajStrGetLen(acdReply) && nullok)
16519         {
16520             ajTextallDel(&val);
16521 	    break;
16522 	}
16523 
16524 	ajTextinQryS(val->Textin, acdReply);
16525 
16526 	acdGetValueAssoc(thys, "iformat", &val->Textin->Formatstr);
16527 	acdGetValueAssoc(thys, "iquery", &val->Textin->QryFields);
16528 	acdQualToLong(thys, "ioffset", 0L, &val->Textin->Fpos,
16529                       &acdTmpStr);
16530 
16531         ok = ajTextinRead(val->Textin, val->Text);
16532     }
16533 
16534     if(!ok)
16535 	acdBadRetry(thys);
16536 
16537     if(maxreads > 1)
16538         val->Multi = ajTrue;
16539 
16540     acdAttrToBool(thys, "entry", ajFalse, &val->Textin->Text);
16541 
16542     /* acdInFileSave(acdReply, ajTextallGettextId(val), ajTrue); */
16543 
16544     thys->Value = val;
16545     ajStrAssignS(&thys->ValStr, acdReply);
16546 
16547     return;
16548 }
16549 
16550 
16551 
16552 
16553 /* @func ajAcdGetToggle *******************************************************
16554 **
16555 ** Returns an item of type Toggle as defined in a named ACD item. Called by the
16556 ** application after all ACD values have been set, and simply returns
16557 ** what the ACD item already has.
16558 **
16559 ** Toggle is an AjBool that is used to switch (toggle) other ACD types.
16560 **
16561 ** @param [r] token [const char*] Text token name
16562 ** @return [AjBool] Boolean value from ACD item
16563 ** @cre failure to find an item with the right name and type aborts.
16564 **
16565 ** @release 2.9.0
16566 ** @@
16567 ******************************************************************************/
16568 
ajAcdGetToggle(const char * token)16569 AjBool ajAcdGetToggle(const char *token)
16570 {
16571     AjBool* val;
16572 
16573     val = acdGetValue(token, "toggle");
16574 
16575     return *val;
16576 }
16577 
16578 
16579 
16580 
16581 /* @funcstatic acdSetToggle ***************************************************
16582 **
16583 ** Using the definition in the ACD file, and any values for the
16584 ** item or its associated qualifiers provided on the command line,
16585 ** prompts the user if necessary (and possible) and
16586 ** sets the actual value for an ACD toggle item.
16587 **
16588 ** Understands all attributes and associated qualifiers for this item type.
16589 **
16590 ** The default value (if no other available) is "N" for ajFalse.
16591 **
16592 ** @param [u] thys [AcdPAcd] ACD item.
16593 ** @return [void]
16594 ** @see ajStrToBool
16595 **
16596 ** @release 2.9.0
16597 ** @@
16598 ******************************************************************************/
16599 
16600 
acdSetToggle(AcdPAcd thys)16601 static void acdSetToggle(AcdPAcd thys)
16602 {
16603     AjBool* val;
16604 
16605     AjBool required = ajFalse;
16606     AjBool ok       = ajFalse;
16607 
16608     ajint itry;
16609 
16610     AJNEW0(val);		   /* create storage for the result */
16611 
16612     *val = ajFalse;			/* set the default value */
16613 
16614     required = acdIsRequired(thys);
16615     acdReplyInitC(thys, "N", &acdReplyDef);
16616 
16617     acdLog("acdSetToggle -%S def: %S\n", thys->Name, acdReplyDef);
16618 
16619 
16620     for(itry=acdPromptTry; itry && !ok; itry--)
16621     {
16622 	ajStrAssignS(&acdReply, acdReplyDef);
16623 
16624 	if(required)
16625 	    acdUserGet(thys, &acdReply);
16626 
16627 	ok = ajStrToBool(acdReply, val);
16628 
16629 	if(!ok)
16630 	    acdBadVal(thys, required, "Invalid Y/N value '%S'", acdReply);
16631     }
16632 
16633     if(!ok)
16634 	acdBadRetry(thys);
16635 
16636     thys->Value = val;
16637     ajFmtPrintS(&thys->ValStr, "%B", *val);
16638 
16639     acdLog("acdSetToggle -%S val: %B\n", thys->Name, *val);
16640 
16641     if(ajStrMatchC(thys->Name, "help"))
16642 	acdHelp();
16643 
16644     return;
16645 }
16646 
16647 
16648 
16649 
16650 /* @func ajAcdGetTree *********************************************************
16651 **
16652 ** Returns an item of type Tree as defined in a named ACD item.
16653 ** Called by the application after all ACD values have been set,
16654 ** and simply returns what the ACD item already has.
16655 **
16656 ** @param [r] token [const char*] Text token name
16657 ** @return [AjPPhyloTree*] Tree object. The data was already set by
16658 **         acdSetTree so this just returns the pointer.
16659 ** @cre failure to find an item with the right name and type aborts.
16660 **
16661 ** @release 2.8.0
16662 ** @@
16663 ******************************************************************************/
16664 
ajAcdGetTree(const char * token)16665 AjPPhyloTree* ajAcdGetTree(const char *token)
16666 {
16667     return acdGetValueRef(token, "tree");
16668 }
16669 
16670 
16671 
16672 
16673 /* @func ajAcdGetTreeSingle ***************************************************
16674 **
16675 ** Returns an item of type Tree as defined in a named ACD item.
16676 ** Called by the application after all ACD values have been set,
16677 ** and simply returns what the ACD item already has.
16678 **
16679 ** @param [r] token [const char*] Text token name
16680 ** @return [AjPPhyloTree] Tree object. The data was already set by
16681 **         acdSetTree so this just returns the pointer.
16682 ** @cre failure to find an item with the right name and type aborts.
16683 **
16684 ** @release 4.0.0
16685 ** @@
16686 ******************************************************************************/
16687 
ajAcdGetTreeSingle(const char * token)16688 AjPPhyloTree ajAcdGetTreeSingle(const char *token)
16689 {
16690     AjPPhyloTree *val;
16691     ajint i;
16692 
16693     val = acdGetValueSingle(token, "tree");
16694 
16695     for(i=0; val[i]; i++)
16696 	continue;
16697 
16698     if(i > 1)
16699 	ajWarn("Single list value %s, but can choose %d values",
16700 	       token, i);
16701 
16702     if(i < 1)
16703 	ajWarn("Single list value %s, no value found: returning NULL value",
16704 	       token);
16705 
16706     return val[0];
16707 }
16708 
16709 
16710 
16711 
16712 /* @funcstatic acdSetTree *****************************************************
16713 **
16714 ** Using the definition in the ACD file, and any values for the
16715 ** item or its associated qualifiers provided on the command line,
16716 ** prompts the user if necessary (and possible) and
16717 ** sets the actual value for an ACD tree file item.
16718 **
16719 ** Understands all attributes and associated qualifiers for this item type.
16720 **
16721 ** The default value (if no other is available) is an empty string.
16722 **
16723 ** Attributes for number of trees (size) are applied with error
16724 ** messages if exceeded.
16725 **
16726 ** @param [u] thys [AcdPAcd] ACD item.
16727 ** @return [void]
16728 **
16729 ** @release 2.8.0
16730 ** @@
16731 ******************************************************************************/
16732 
acdSetTree(AcdPAcd thys)16733 static void acdSetTree(AcdPAcd thys)
16734 {
16735     AjPPhyloTree *val;
16736 
16737     AjBool required = ajFalse;
16738     AjBool ok       = ajFalse;
16739 
16740     AjPStr infname  = NULL;
16741     ajint itry;
16742     ajint i;
16743 
16744     ajint size;
16745     AjBool nullok = ajFalse;
16746 
16747     val = NULL;
16748 
16749     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
16750     acdAttrToInt(thys, "size", 0, &size);
16751 
16752     acdInFilename(&infname);
16753     required = acdIsRequired(thys);
16754     acdReplyInitS(thys, infname, &acdReplyDef);
16755     acdPromptTree(thys);
16756     ajStrDel(&infname);
16757 
16758     for(itry=acdPromptTry; itry && !ok; itry--)
16759     {
16760 	ok = ajTrue;	   /* accept the default if nothing changes */
16761 
16762 	ajStrAssignS(&acdReply, acdReplyDef);
16763 
16764 	if(required)
16765 	    acdUserGet(thys, &acdReply);
16766 
16767 	if(ajStrGetLen(acdReply))
16768 	{
16769 	    val = ajPhyloTreeRead(acdReply, size);
16770 
16771 	    if(!val)
16772 	    {
16773 		acdBadVal(thys, required,
16774 			  "Unable to read tree data from '%S'",
16775 			  acdReply);
16776 		ok = ajFalse;
16777 	    }
16778 	}
16779 	else
16780 	    if(!nullok)
16781 	    {
16782 		acdBadVal(thys, required,
16783 			  "Input file is required");
16784 		ok = ajFalse;
16785 	    }
16786     }
16787 
16788     if(!ok)
16789 	acdBadRetry(thys);
16790     acdInFileSave(acdReply, NULL, ajTrue);
16791 
16792     /* trees have special set attributes */
16793 
16794     thys->SAttr = acdAttrListCount(acdCalcTree);
16795     thys->SetAttr = &acdCalcTree[0];
16796     thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr));
16797 
16798     if(val)
16799     {
16800 	for(i=0;val[i];i++)
16801 	    continue;
16802 
16803 	ajStrFromInt(&thys->SetStr[0],i); /* number of trees */
16804 	ajStrFromInt(&thys->SetStr[1],val[0]->Size);
16805 	ajStrFromBool(&thys->SetStr[2],val[0]->HasLengths);
16806 	ajStrAssignS(&thys->ValStr, val[0]->Tree);
16807     }
16808     else
16809     {
16810 	ajStrFromInt(&thys->SetStr[0],0); /* number of trees */
16811 	ajStrFromInt(&thys->SetStr[1],0);
16812 	ajStrFromBool(&thys->SetStr[2],ajFalse);
16813 	ajStrAssignClear(&thys->ValStr);
16814     }
16815 
16816     thys->Value = val;
16817 
16818     return;
16819 }
16820 
16821 
16822 
16823 
16824 /* @func ajAcdGetUrl **********************************************************
16825 **
16826 ** Returns an item of type URL as defined in a named ACD item.
16827 ** Called by the application after all ACD values have been set,
16828 ** and simply returns what the ACD item already has.
16829 **
16830 ** @param [r] token [const char*] Text token name
16831 ** @return [AjPUrl] URL object
16832 ** @cre failure to find an item with the right name and type aborts.
16833 **
16834 ** @release 6.4.0
16835 ** @@
16836 ******************************************************************************/
16837 
ajAcdGetUrl(const char * token)16838 AjPUrl ajAcdGetUrl(const char *token)
16839 {
16840     AjPUrlall val = acdGetValue(token, "url");
16841     if(val->Multi)
16842         ajWarn("ajAcdGetUrl request single URL but maxreads > 1");
16843 
16844     val->Returned = ajTrue;
16845 
16846     return val->Url;
16847 }
16848 
16849 
16850 
16851 
16852 /* @func ajAcdGetUrlall *******************************************************
16853 **
16854 ** Returns an input stream of an item of type URL as defined in a
16855 ** named ACD item.
16856 ** Called by the application after all ACD values have been set,
16857 ** and simply returns what the ACD item already has.
16858 **
16859 ** @param [r] token [const char*] Text token name
16860 ** @return [AjPUrlall] URL input stream
16861 ** @cre failure to find an item with the right name and type aborts.
16862 **
16863 ** @release 6.4.0
16864 ** @@
16865 ******************************************************************************/
16866 
ajAcdGetUrlall(const char * token)16867 AjPUrlall ajAcdGetUrlall(const char *token)
16868 {
16869     AjPUrlall val = acdGetValueRef(token, "url");
16870 
16871     if(!val->Multi)
16872         ajWarn("ajAcdGetUrlall request url input stream but maxreads is 1");
16873 
16874     return val;
16875 }
16876 
16877 
16878 
16879 
16880 /* @funcstatic acdSetUrl ******************************************************
16881 **
16882 ** Using the definition in the ACD file, and any values for the
16883 ** item or its associated qualifiers provided on the command line,
16884 ** prompts the user if necessary (and possible) and
16885 ** sets the actual value for an ACD URL input
16886 **
16887 ** Understands all attributes and associated qualifiers for this item type.
16888 **
16889 ** @param [u] thys [AcdPAcd] ACD item.
16890 ** @return [void]
16891 **
16892 ** @release 6.4.0
16893 ** @@
16894 ******************************************************************************/
16895 
acdSetUrl(AcdPAcd thys)16896 static void acdSetUrl(AcdPAcd thys)
16897 {
16898     AjPUrlall val;
16899 
16900     AjBool required = ajFalse;
16901     AjBool ok       = ajFalse;
16902     AjBool nullok   = ajFalse;
16903     ajint itry;
16904 
16905     ajint maxreads;
16906 
16907     AjPStr infname = NULL;
16908 
16909     val = ajUrlallNew();        /* set the default value */
16910 
16911     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
16912     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
16913 
16914     acdInFilename(&infname);
16915     required = acdIsRequired(thys);
16916     acdReplyInitS(thys, infname, &acdReplyDef);
16917     ajStrDel(&infname);
16918 
16919     for(itry=acdPromptTry; itry && !ok; itry--)
16920     {
16921 	ok = ajTrue;	   /* accept the default if nothing changes */
16922 
16923 	ajStrAssignS(&acdReply, acdReplyDef);
16924 
16925 	if(required)
16926 	    acdUserGet(thys, &acdReply);
16927 
16928 	if(!ajStrGetLen(acdReply) && nullok)
16929         {
16930             ajUrlallDel(&val);
16931 	    break;
16932 	}
16933 
16934 	ajUrlinQryS(val->Urlin, acdReply);
16935 
16936         /* these are reset by ajUrlinQryS - can safely set now */
16937         acdQualToBool(thys, "swiss", ajFalse, &val->Urlin->IsSwiss,
16938                       &acdTmpStr);
16939         acdQualToBool(thys, "embl", ajFalse, &val->Urlin->IsEmbl,
16940                       &acdTmpStr);
16941         acdGetValueAssoc(thys, "accession", &val->Urlin->Accession);
16942         acdGetValueAssoc(thys, "identifier", &val->Urlin->IdTypes);
16943 
16944 	acdGetValueAssoc(thys, "iformat", &val->Urlin->Input->Formatstr);
16945 
16946         ok = ajUrlinRead(val->Urlin, val->Url);
16947     }
16948 
16949     if(!ok)
16950 	acdBadRetry(thys);
16951 
16952     if(maxreads > 1)
16953         val->Multi = ajTrue;
16954 
16955     acdAttrToBool(thys, "entry", ajFalse, &val->Urlin->Input->Text);
16956 
16957     acdInFileSave(acdReply, ajUrlallGeturlId(val), ajTrue);
16958 
16959     thys->Value = val;
16960     ajStrAssignS(&thys->ValStr, acdReply);
16961 
16962     return;
16963 }
16964 
16965 
16966 
16967 
16968 /* @func ajAcdGetValue ********************************************************
16969 **
16970 ** Returns the string value of any ACD item
16971 **
16972 ** @param [r] token [const char*] Text token name
16973 ** @return [const AjPStr] String object. The string was already set by
16974 **         acdSetString so this just returns the pointer.
16975 ** @cre failure to find an item with the right name and type aborts.
16976 **
16977 ** @release 4.0.0
16978 ** @@
16979 ******************************************************************************/
16980 
ajAcdGetValue(const char * token)16981 const AjPStr ajAcdGetValue(const char *token)
16982 {
16983     return acdGetValStr(token);
16984 }
16985 
16986 
16987 
16988 
16989 /* @func ajAcdGetValueDefault *************************************************
16990 **
16991 ** Returns the default value of any ACD item
16992 **
16993 ** @param [r] token [const char*] Text token name
16994 ** @return [const AjPStr] Default value.
16995 ** @cre failure to find an item with the right name and type returns NULL.
16996 **
16997 ** @release 6.0.0
16998 ** @@
16999 ******************************************************************************/
17000 
ajAcdGetValueDefault(const char * token)17001 const AjPStr ajAcdGetValueDefault(const char *token)
17002 {
17003     return acdGetValDefault(token);
17004 }
17005 
17006 
17007 
17008 
17009 /* @func ajAcdGetVariation ****************************************************
17010 **
17011 ** Returns an item of type variation loader as defined in a named ACD item.
17012 ** Called by the application after all ACD values have been set,
17013 ** and simply returns what the ACD item already has.
17014 **
17015 ** @param [r] token [const char*] Text token name
17016 ** @return [AjPVarload] Variation loader object
17017 ** @cre failure to find an item with the right name and type aborts.
17018 **
17019 ** @release 6.4.0
17020 ** @@
17021 ******************************************************************************/
17022 
ajAcdGetVariation(const char * token)17023 AjPVarload ajAcdGetVariation(const char *token)
17024 {
17025     AjPVarload val = acdGetValueRef(token, "variation");
17026 
17027     /*if(val->Multi)
17028         ajWarn("ajAcdGetVariation request single variation but maxreads > 1");
17029     */
17030 
17031     val->Returned = ajTrue;
17032 
17033     return val;
17034 }
17035 
17036 
17037 
17038 
17039 /* @funcstatic acdSetVariation ************************************************
17040 **
17041 ** Using the definition in the ACD file, and any values for the
17042 ** item or its associated qualifiers provided on the command line,
17043 ** prompts the user if necessary (and possible) and
17044 ** sets the actual value for an ACD variation input
17045 **
17046 ** Understands all attributes and associated qualifiers for this item type.
17047 **
17048 ** @param [u] thys [AcdPAcd] ACD item.
17049 ** @return [void]
17050 **
17051 ** @release 6.4.0
17052 ** @@
17053 ******************************************************************************/
17054 
acdSetVariation(AcdPAcd thys)17055 static void acdSetVariation(AcdPAcd thys)
17056 {
17057     AjPVarload val;
17058 
17059     AjBool required = ajFalse;
17060     AjBool ok       = ajFalse;
17061     AjBool nullok   = ajFalse;
17062     ajint itry;
17063 
17064     AjPStr infname = NULL;
17065 
17066     val = ajVarloadNew();        /* set the default value */
17067 
17068     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
17069 
17070     acdInFilename(&infname);
17071     required = acdIsRequired(thys);
17072     acdReplyInitS(thys, infname, &acdReplyDef);
17073     ajStrDel(&infname);
17074 
17075     for(itry=acdPromptTry; itry && !ok; itry--)
17076     {
17077 	ok = ajTrue;	   /* accept the default if nothing changes */
17078 
17079 	ajStrAssignS(&acdReply, acdReplyDef);
17080 
17081 	if(required)
17082 	    acdUserGet(thys, &acdReply);
17083 
17084 	if(!ajStrGetLen(acdReply) && nullok)
17085         {
17086             ajVarloadDel(&val);
17087 	    break;
17088 	}
17089 
17090         ajVarinQryS(val->Varin, acdReply);
17091 
17092 	acdGetValueAssoc(thys, "iformat", &val->Varin->Input->Formatstr);
17093 	acdGetValueAssoc(thys, "iquery", &val->Varin->Input->QryFields);
17094 	acdQualToLong(thys, "ioffset", 0L, &val->Varin->Input->Fpos,
17095                       &acdTmpStr);
17096 
17097         ok = ajVarinLoad(val->Varin, val->Var);
17098     }
17099 
17100     if(!ok)
17101 	acdBadRetry(thys);
17102 
17103     acdAttrToBool(thys, "entry", ajFalse, &val->Varin->Input->Text);
17104 
17105     acdInFileSave(acdReply, ajVarloadGetvarId(val), ajTrue);
17106 
17107     thys->Value = val;
17108     ajStrAssignS(&thys->ValStr, acdReply);
17109 
17110     return;
17111 }
17112 
17113 
17114 
17115 
17116 /* @func ajAcdGetXml **********************************************************
17117 **
17118 ** Returns an item of type xml as defined in a named ACD item.
17119 ** Called by the application after all ACD values have been set,
17120 ** and simply returns what the ACD item already has.
17121 **
17122 ** @param [r] token [const char*] Text token name
17123 ** @return [AjPXml] Xml object
17124 ** @cre failure to find an item with the right name and type aborts.
17125 **
17126 ** @release 6.6.0
17127 ** @@
17128 ******************************************************************************/
17129 
ajAcdGetXml(const char * token)17130 AjPXml ajAcdGetXml(const char *token)
17131 {
17132     AjPXml val = acdGetValueRef(token, "xml");
17133 
17134     return val;
17135 }
17136 
17137 
17138 
17139 
17140 /* @func ajAcdGetXmlall *******************************************************
17141 **
17142 ** Returns an input stream of an item of type XML as defined in a
17143 ** named ACD item.
17144 ** Called by the application after all ACD values have been set,
17145 ** and simply returns what the ACD item already has.
17146 **
17147 ** @param [r] token [const char*] Text token name
17148 ** @return [AjPXmlall] URL input stream
17149 ** @cre failure to find an item with the right name and type aborts.
17150 **
17151 ** @release 6.6.0
17152 ** @@
17153 ******************************************************************************/
17154 
ajAcdGetXmlall(const char * token)17155 AjPXmlall ajAcdGetXmlall(const char *token)
17156 {
17157     AjPXmlall val = acdGetValueRef(token, "xml");
17158 
17159     if(!val->Multi)
17160         ajWarn("ajAcdGetXmlall request xml input stream but maxreads is 1");
17161 
17162     return val;
17163 }
17164 
17165 
17166 
17167 
17168 /* @funcstatic acdSetXml ******************************************************
17169 **
17170 ** Using the definition in the ACD file, and any values for the
17171 ** item or its associated qualifiers provided on the command line,
17172 ** prompts the user if necessary (and possible) and
17173 ** sets the actual value for an ACD xml input
17174 **
17175 ** Understands all attributes and associated qualifiers for this item type.
17176 **
17177 ** @param [u] thys [AcdPAcd] ACD item.
17178 ** @return [void]
17179 **
17180 ** @release 6.6.0
17181 ** @@
17182 ******************************************************************************/
17183 
acdSetXml(AcdPAcd thys)17184 static void acdSetXml(AcdPAcd thys)
17185 {
17186     AjPXmlall val;
17187 
17188     AjBool required = ajFalse;
17189     AjBool ok       = ajFalse;
17190     AjBool nullok   = ajFalse;
17191     ajint itry;
17192 
17193     ajint maxreads;
17194 
17195     AjPStr infname = NULL;
17196 
17197     val = ajXmlallNew();        /* set the default value */
17198 
17199     acdAttrToBool(thys, "nullok", ajFalse, &nullok);
17200     acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads);
17201 
17202     acdInFilename(&infname);
17203     required = acdIsRequired(thys);
17204     acdReplyInitS(thys, infname, &acdReplyDef);
17205     ajStrDel(&infname);
17206 
17207     acdAttrToBool(thys, "entry", ajFalse, &val->Xmlin->Input->Text);
17208 
17209     for(itry=acdPromptTry; itry && !ok; itry--)
17210     {
17211 	ok = ajTrue;	   /* accept the default if nothing changes */
17212 
17213 	ajStrAssignS(&acdReply, acdReplyDef);
17214 
17215 	if(required)
17216 	    acdUserGet(thys, &acdReply);
17217 
17218 	if(!ajStrGetLen(acdReply) && nullok)
17219         {
17220             ajXmlallDel(&val);
17221 	    break;
17222 	}
17223 
17224 	ajXmlinQryS(val->Xmlin, acdReply);
17225 
17226 	acdGetValueAssoc(thys, "iformat", &val->Xmlin->Input->Formatstr);
17227 	acdGetValueAssoc(thys, "iquery", &val->Xmlin->Input->QryFields);
17228 	acdQualToLong(thys, "ioffset", 0L, &val->Xmlin->Input->Fpos,
17229                       &acdTmpStr);
17230 
17231         ok = ajXmlinRead(val->Xmlin, val->Xml);
17232     }
17233 
17234     if(!ok)
17235 	acdBadRetry(thys);
17236 
17237     if(maxreads > 1)
17238         val->Multi = ajTrue;
17239 
17240     acdInFileSave(acdReply, NULL, ajTrue);
17241 
17242     thys->Value = val;
17243     ajStrAssignS(&thys->ValStr, acdReply);
17244 
17245     return;
17246 }
17247 
17248 
17249 
17250 
17251 /* @func ajAcdGetpathC ********************************************************
17252 **
17253 ** Returns the full path of an application defined in an external: attribute
17254 ** within the application definition. If the application was defined by an
17255 ** EMBOSS_appname environment variable this will use the substitution made
17256 ** when the external attribute was validated.
17257 **
17258 ** @param [r] token [const char*] External application name
17259 ** @return [const AjPStr] Executable application name
17260 **
17261 ** @release 6.2.0
17262 ** @@
17263 ******************************************************************************/
17264 
ajAcdGetpathC(const char * token)17265 const AjPStr ajAcdGetpathC(const char* token)
17266 {
17267     const AjPStr value;	       /* not static - copy of a table text */
17268     AjPStr tmpname = NULL;
17269 
17270     ajStrAssignC(&tmpname, token);
17271 
17272     value = ajAcdGetpathS(tmpname);
17273 
17274     ajStrDel(&tmpname);
17275 
17276     return value;
17277 }
17278 
17279 
17280 
17281 
17282 /* @func ajAcdGetpathS ********************************************************
17283 **
17284 ** Returns the full path of an application defined in an external: attribute
17285 ** within the application definition. If the application was defined by an
17286 ** EMBOSS_appname environment variable this will use the substitution made
17287 ** when the external attribute was validated.
17288 **
17289 ** @param [r] strtoken [const AjPStr] External application name
17290 ** @return [const AjPStr] Executable application name
17291 **
17292 ** @release 6.2.0
17293 ** @@
17294 ******************************************************************************/
17295 
ajAcdGetpathS(const AjPStr strtoken)17296 const AjPStr ajAcdGetpathS(const AjPStr strtoken)
17297 {
17298     const AjPStr value;
17299 
17300     value = ajTableFetchS(acdExternalTable, strtoken);
17301 
17302     if(!value)
17303         ajWarn("Cannot find '%S', no ACD external definition found", strtoken);
17304 
17305     return value;
17306 }
17307 
17308 
17309 
17310 
17311 /* @func ajAcdIsUserdefinedC **************************************************
17312 **
17313 ** Tests whether an ACD item has a value set by the user.
17314 **
17315 ** @param [r] token [const char*] Text token name
17316 ** @return [AjBool] True if token is not found as an ACD object name
17317 **
17318 ** @cre failure to find an item with the right name gives an error message
17319 ** and continues
17320 **
17321 ** @release 6.2.0
17322 ** @@
17323 ******************************************************************************/
17324 
ajAcdIsUserdefinedC(const char * token)17325 AjBool ajAcdIsUserdefinedC(const char *token)
17326 {
17327     AcdPAcd acd;
17328     ajint pnum = 0;		   /* need to get from end of token */
17329     AjPStr tmpstr = NULL;
17330 
17331     tmpstr = ajStrNewC(token);
17332 
17333     acdTokenToLowerS(&tmpstr, &pnum);
17334 
17335     acd = acdFindAcd(tmpstr, tmpstr);
17336 
17337     if(!acd)
17338     {
17339         ajErr("Qualifier '-%s' not found", token);
17340         return ajFalse;
17341     }
17342 
17343     ajStrDel(&tmpstr);
17344 
17345     return acd->UserDefined;
17346 }
17347 
17348 
17349 
17350 
17351 /* @func ajAcdIsUserdefinedS **************************************************
17352 **
17353 ** Tests whether an ACD item has a value set by the user.
17354 **
17355 ** @param [r] strtoken [const AjPStr] Text token name
17356 ** @return [AjBool] True if token is not found as an ACD object name
17357 **
17358 ** @cre failure to find an item with the right name gives an error message
17359 ** and continues
17360 **
17361 ** @release 6.2.0
17362 ** @@
17363 ******************************************************************************/
17364 
ajAcdIsUserdefinedS(const AjPStr strtoken)17365 AjBool ajAcdIsUserdefinedS(const AjPStr strtoken)
17366 {
17367     AcdPAcd acd;
17368     ajint pnum = 0;		   /* need to get from end of token */
17369     AjPStr tmpstr = NULL;
17370 
17371     tmpstr = ajStrNewS(strtoken);
17372 
17373     acdTokenToLowerS(&tmpstr, &pnum);
17374 
17375     acd = acdFindAcd(tmpstr, tmpstr);
17376 
17377     if(!acd)
17378     {
17379         ajErr("Qualifier '-%S' not found", strtoken);
17380         return ajFalse;
17381     }
17382 
17383     ajStrDel(&tmpstr);
17384 
17385     return acd->UserDefined;
17386 }
17387 
17388 
17389 
17390 
17391 /* @funcstatic acdAttrCount ***************************************************
17392 **
17393 ** Simply counts all attributes for a numbered ACD type,
17394 **
17395 ** @param [r] itype [ajint] Numbered type as returned by acdFindType
17396 ** @return [ajint] number of attributes defined.
17397 **
17398 ** @release 1.0.0
17399 ** @@
17400 ******************************************************************************/
17401 
acdAttrCount(ajint itype)17402 static ajint acdAttrCount(ajint itype)
17403 {
17404     AcdPAttr attr = acdType[itype].Attr;
17405 
17406     return acdAttrListCount(attr);
17407 }
17408 
17409 
17410 
17411 
17412 /* @funcstatic acdAttrKeyCount ************************************************
17413 **
17414 ** Simply counts all attributes for a numbered ACD keyword,
17415 **
17416 ** @param [r] ikey [ajint] Numbered type as returned by acdFindKey
17417 ** @return [ajint] number of attributes defined.
17418 **
17419 ** @release 1.0.0
17420 ** @@
17421 ******************************************************************************/
17422 
acdAttrKeyCount(ajint ikey)17423 static ajint acdAttrKeyCount(ajint ikey)
17424 {
17425     AcdPAttr attr = acdKeywords[ikey].Attr;
17426 
17427     return acdAttrListCount(attr);
17428 }
17429 
17430 
17431 
17432 
17433 /* @funcstatic acdAttrListCount ***********************************************
17434 **
17435 ** Simply counts all attributes for an attribute list.
17436 **
17437 ** @param [r] attr [const AcdPAttr] Attribute list
17438 ** @return [ajint] number of attributes defined.
17439 **
17440 ** @release 1.0.0
17441 ** @@
17442 ******************************************************************************/
17443 
acdAttrListCount(const AcdPAttr attr)17444 static ajint acdAttrListCount(const AcdPAttr attr)
17445 {
17446     static ajint i;
17447 
17448     i = 0;
17449 
17450     while(attr[i].Name)
17451 	i++;
17452 
17453     return i;
17454 }
17455 
17456 
17457 
17458 
17459 /* @funcstatic acdGetValue ****************************************************
17460 **
17461 ** Picks up a token by name and tests the type.
17462 ** The value is returned as type "void*", to be cast by the calling
17463 ** routine which is supposed to know what to expect. For example, only
17464 ** ajAcdGetInt should call with a type of "integer".
17465 **
17466 ** @param [r] token [const char*] Token name, optionally including a
17467 **                                numeric suffix.
17468 ** @param [r] type [const char*] Type.
17469 ** @return [void*] Value.
17470 **
17471 **
17472 ** @release 1.0.0
17473 ******************************************************************************/
17474 
acdGetValue(const char * token,const char * type)17475 static void* acdGetValue(const char *token, const char* type)
17476 {
17477     void *ret;
17478     ajint pnum = 0;		   /* need to get from end of token */
17479     AjPStr tmpstr = NULL;
17480 
17481     tmpstr = ajStrNewC(token);
17482 
17483     acdLog("acdGetValue '%s' (%s)\n", token, type);
17484 
17485     acdTokenToLowerS(&tmpstr, &pnum);
17486 
17487     ret = acdGetValueNumS(tmpstr, type, pnum, REF_NONE);
17488 
17489     acdLog("acdGetValue '%s' result %x\n", token, ret);
17490 
17491     ajStrDel(&tmpstr);
17492 
17493     return ret;
17494 }
17495 
17496 
17497 
17498 
17499 /* @funcstatic acdGetValueRef *************************************************
17500 **
17501 ** Picks up a token by name and tests the type.
17502 ** The value is returned as type "void*", to be cast by the calling
17503 ** routine which is supposed to know what to expect. For example, only
17504 ** ajAcdGetInt should call with a type of "integer".
17505 **
17506 ** The value reference is passed up to the original caller who now
17507 ** 'owns' the pointer. Some values will remain owned by ACD. Examples
17508 ** include integers and booleans, but also lists of options where only
17509 ** the first option is returned.
17510 **
17511 ** @param [r] token [const char*] Token name, optionally including a
17512 **                                numeric suffix.
17513 ** @param [r] type [const char*] Type.
17514 ** @return [void*] Value.
17515 **
17516 **
17517 ** @release 4.0.0
17518 ******************************************************************************/
17519 
acdGetValueRef(const char * token,const char * type)17520 static void* acdGetValueRef(const char *token, const char* type)
17521 {
17522     void *ret;
17523     ajint pnum = 0;		   /* need to get from end of token */
17524     AjPStr tmpstr = NULL;
17525 
17526     tmpstr = ajStrNewC(token);
17527 
17528     acdLog("acdGetValue '%s' (%s)\n", token, type);
17529 
17530     acdTokenToLowerS(&tmpstr, &pnum);
17531 
17532     ret = acdGetValueNumS(tmpstr, type, pnum, REF_ALL);
17533 
17534     acdLog("acdGetValueRef '%s' result %x\n", token, ret);
17535 
17536     ajStrDel(&tmpstr);
17537 
17538     return ret;
17539 }
17540 
17541 
17542 
17543 
17544 /* @funcstatic acdGetValueSingle **********************************************
17545 **
17546 ** Picks up a token by name and tests the type.
17547 ** The value is returned as type "void*", to be cast by the calling
17548 ** routine which is supposed to know what to expect. For example, only
17549 ** ajAcdGetInt should call with a type of "integer".
17550 **
17551 ** The value reference is passed up to the original caller who now
17552 ** 'owns' the pointer to the first data value, but the value array will
17553 ** need to be freed on exit.
17554 **
17555 ** @param [r] token [const char*] Token name, optionally including a
17556 **                                numeric suffix.
17557 ** @param [r] type [const char*] Type.
17558 ** @return [void*] Value.
17559 **
17560 **
17561 ** @release 4.0.0
17562 ******************************************************************************/
17563 
acdGetValueSingle(const char * token,const char * type)17564 static void* acdGetValueSingle(const char *token, const char* type)
17565 {
17566     void *ret;
17567     ajint pnum = 0;		   /* need to get from end of token */
17568     AjPStr tmpstr = NULL;
17569 
17570     tmpstr = ajStrNewC(token);
17571 
17572     acdLog("acdGetValue '%s' (%s)\n", token, type);
17573 
17574     acdTokenToLowerS(&tmpstr, &pnum);
17575 
17576     ret = acdGetValueNumS(tmpstr, type, pnum, REF_SINGLE);
17577 
17578     acdLog("acdGetValueSingle '%s' result %x\n", token, ret);
17579 
17580     ajStrDel(&tmpstr);
17581 
17582     return ret;
17583 }
17584 
17585 
17586 
17587 
17588 /* @funcstatic acdGetValStr ***************************************************
17589 **
17590 ** Picks up a token by name and tests the type.
17591 ** The string value is returned for any data type.
17592 **
17593 ** @param [r] token [const char*] Token name, optionally including
17594 **                                a numeric suffix.
17595 ** @return [const AjPStr] String.
17596 **
17597 **
17598 ** @release 1.0.0
17599 ******************************************************************************/
17600 
acdGetValStr(const char * token)17601 static const AjPStr acdGetValStr(const char *token)
17602 {
17603     AcdPAcd acd;
17604     ajint pnum = 0;		   /* need to get from end of token */
17605     AjPStr tmpstr = NULL;
17606 
17607     tmpstr = ajStrNewC(token);
17608 
17609     acdLog("acdGetValStr '%s' (%s)\n", token);
17610 
17611     acdTokenToLowerS(&tmpstr, &pnum);
17612 
17613     acd = acdFindAcd(tmpstr, tmpstr);
17614     ajStrDel(&tmpstr);
17615 
17616     if(!acd)
17617         return NULL;
17618 
17619     return acd->ValStr;
17620 }
17621 
17622 
17623 
17624 
17625 /* @funcstatic acdGetValDefault ***********************************************
17626 **
17627 ** Picks up a token by name and tests the type.
17628 ** The default string value is returned for any data type.
17629 **
17630 ** @param [r] token [const char*] Token name, optionally including
17631 **                                a numeric suffix.
17632 ** @return [const AjPStr] String.
17633 **
17634 **
17635 ** @release 6.0.0
17636 ******************************************************************************/
17637 
acdGetValDefault(const char * token)17638 static const AjPStr acdGetValDefault(const char *token)
17639 {
17640     AcdPAcd acd;
17641     ajint pnum = 0;		   /* need to get from end of token */
17642     AjPStr tmpstr = NULL;
17643 
17644     tmpstr = ajStrNewC(token);
17645 
17646     acdLog("acdGetValStr '%s' (%s)\n", token);
17647 
17648     acdTokenToLowerS(&tmpstr, &pnum);
17649 
17650     acd = acdFindAcd(tmpstr, tmpstr);
17651     ajStrDel(&tmpstr);
17652 
17653     if(!acd)
17654         return NULL;
17655 
17656     return acd->DefStr[DEF_DEFAULT];
17657 }
17658 
17659 
17660 
17661 
17662 /* @funcstatic acdGetValueAssoc ***********************************************
17663 **
17664 ** Picks up the value for an associated qualifier as a string.
17665 **
17666 ** @param [r] thys [const AcdPAcd] ACD item for the master parameter/qualifier
17667 ** @param [r] token [const char*] Token name, optionally including a
17668 **                                numeric suffix.
17669 ** @param [w] result [AjPStr*] String for the resulting value.
17670 ** @return [AjBool] ajTrue if found.
17671 ** @cre Aborts if not found.
17672 **
17673 **
17674 ** @release 1.0.0
17675 ******************************************************************************/
17676 
acdGetValueAssoc(const AcdPAcd thys,const char * token,AjPStr * result)17677 static AjBool acdGetValueAssoc(const AcdPAcd thys, const char *token,
17678                                       AjPStr *result)
17679 {
17680     ajint pnum = 0;		   /* need to get from end of token */
17681     AcdPAcd pa;
17682     AjPStr tmpstr = NULL;
17683 
17684     tmpstr = ajStrNewC(token);
17685     acdLog("acdGetValueAssocDefault '%s' (%S)\n", token, thys->Name);
17686 
17687     acdTokenToLowerS(&tmpstr, &pnum);
17688     ajStrDel(&tmpstr);
17689 
17690     if(pnum)
17691 	acdErrorAcd(thys,
17692 		    "associated token '%s' is numbered - not allowed\n",
17693 		    token);
17694 
17695     for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next)
17696 	if(ajStrMatchC(pa->Token, token))
17697 	{
17698 	    ajStrAssignS(result, pa->ValStr);
17699 	    return pa->Defined;
17700 	}
17701 
17702     acdErrorAcd(thys,
17703 		"Token '%s' not found\n",
17704 		token);
17705 
17706     return ajFalse;
17707 }
17708 
17709 
17710 
17711 
17712 /* @funcstatic acdGetValueAssocDefault ****************************************
17713 **
17714 ** Picks up the default value for an associated qualifier as a string.
17715 **
17716 ** @param [r] thys [const AcdPAcd] ACD item for the master parameter/qualifier
17717 ** @param [r] token [const char*] Token name, optionally including a
17718 **                                numeric suffix.
17719 ** @param [w] result [AjPStr*] String for the resulting value.
17720 ** @return [AjBool] ajTrue if found.
17721 ** @cre Aborts if not found.
17722 **
17723 **
17724 ** @release 6.4.0
17725 ******************************************************************************/
17726 
acdGetValueAssocDefault(const AcdPAcd thys,const char * token,AjPStr * result)17727 static AjBool acdGetValueAssocDefault(const AcdPAcd thys, const char *token,
17728                                       AjPStr *result)
17729 {
17730     ajint pnum = 0;		   /* need to get from end of token */
17731     AcdPAcd pa;
17732     AjPStr tmpstr = NULL;
17733 
17734     tmpstr = ajStrNewC(token);
17735     acdLog("acdGetValueAssocDefault '%s' (%S)\n", token, thys->Name);
17736 
17737     acdTokenToLowerS(&tmpstr, &pnum);
17738     ajStrDel(&tmpstr);
17739 
17740     if(pnum)
17741 	acdErrorAcd(thys,
17742 		    "associated token '%s' is numbered - not allowed\n",
17743 		    token);
17744 
17745     for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next)
17746 	if(ajStrMatchC(pa->Token, token))
17747 	{
17748 	    ajStrAssignS(result, pa->DefStr[DEF_DEFAULT]);
17749 	    return pa->Defined;
17750 	}
17751 
17752     acdErrorAcd(thys,
17753 		"Token '%s' not found\n",
17754 		token);
17755 
17756     return ajFalse;
17757 }
17758 
17759 
17760 
17761 
17762 /* @funcstatic acdGetValueNumC ************************************************
17763 **
17764 ** Picks up the value by name, type and number.
17765 **
17766 ** @param [r] token [const char*] Token name
17767 ** @param [r] type [const char*] ACD type
17768 ** @param [r] pnum [ajint] parameter number, or 0 for a general qualifier.
17769 ** @param [r] reftype [ajint] Reference passing type.
17770 **                            REF_NONE means ACD still owns the value,
17771 **                            REF_ALL means the caller owns the value,
17772 **                            REF_SINGLE means the caller owns one value,
17773 **                            but ACD owns the array
17774 ** @return [void*] Value of unknown type.
17775 ** @cre Aborts if not found.
17776 **
17777 **
17778 ** @release 4.0.0
17779 ******************************************************************************/
17780 
acdGetValueNumC(const char * token,const char * type,ajint pnum,ajint reftype)17781 static void* acdGetValueNumC(const char *token, const char* type,
17782 			     ajint pnum, ajint reftype)
17783 {
17784     AcdPAcd pa;
17785     AcdPAcd ret = NULL;
17786 
17787     ajint itype  = 0;
17788     ajint ifound = 0;
17789 
17790     AjPStr ambigList = NULL;
17791 
17792     ambigList = ajStrNew();
17793 
17794     if(type)
17795 	itype = acdFindTypeC(type);
17796 
17797     for(pa=acdList; pa; pa=pa->Next)
17798     {
17799 	if(acdIsStype(pa))
17800             continue;
17801 
17802 	if(ajStrMatchC(pa->Token, token))
17803 	{
17804 	    acdLog("Found pa->Token '%S' pa->Type %d itype: %d\n",
17805 		   pa->Token, pa->Type, itype);
17806 
17807 	    if(pa->Level != ACD_QUAL && pa->Level != ACD_PARAM )
17808 		ajDie("Unknown qualifier '-%S'", pa->Token);
17809 
17810 	    if((itype>=0) && (pa->Type != itype)) /* program source error */
17811 		ajDie("Value for '-%S' is not of type %s (found type %s)",
17812                       pa->Token, type, acdType[pa->Type].Name);
17813 
17814 	    if(pa->PNum == pnum)
17815 	    {
17816 		acdLog("found %S [%d] '%S'\n",
17817 		       pa->Name, pa->PNum, pa->ValStr);
17818 
17819 		if(pa->Used & USED_GET)
17820 		    ajWarn("Value for '-%S' used more than once", pa->Token);
17821 
17822 		pa->Used |= USED_GET;
17823 		ajStrDel(&ambigList);
17824 		pa->RefPassed = reftype;
17825 
17826 		return pa->Value;
17827 	    }
17828 	    else if(!pnum) /* matches any if no number, so count them */
17829 	    {
17830 		ifound++;
17831 		ret = pa;
17832 		acdAmbigApp(&ambigList, pa->Token);
17833 	    }
17834 	}
17835     }
17836 
17837     if(ifound > 1)
17838     {
17839 	ajWarn("Ambiguous qualifier '-%s' (%S)", token, ambigList);
17840 	ajStrDel(&ambigList);
17841     }
17842 
17843     if(ifound == 1)
17844     {
17845 	acdLog("found %S [%d] '%S'\n",
17846 	       ret->Name, ret->PNum, ret->ValStr);
17847 	ret->Used |= USED_GET;
17848 	if (acdDoValid)
17849 	    acdWarn("Abbreviated qualifier '%S' (%S)", token, ambigList);
17850 	ajStrDel(&ambigList);
17851 	ret->RefPassed = reftype;
17852 
17853 	return ret->Value;
17854     }
17855 
17856     ajStrDel(&ambigList);
17857 
17858     /* program source error */
17859     ajDie("Qualifier '-%s' not found", token);
17860 
17861     return NULL;
17862 }
17863 
17864 
17865 
17866 
17867 /* @funcstatic acdGetValueNumS ************************************************
17868 **
17869 ** Picks up the value by name, type and number.
17870 **
17871 ** @param [r] token [const AjPStr] Token name
17872 ** @param [r] type [const char*] ACD type
17873 ** @param [r] pnum [ajint] parameter number, or 0 for a general qualifier.
17874 ** @param [r] reftype [ajint] Reference passing type.
17875 **                            REF_NONE means ACD still owns the value,
17876 **                            REF_ALL means the caller owns the value,
17877 **                            REF_SINGLE means the caller owns one value,
17878 **                            but ACD owns the array
17879 ** @return [void*] Value of unknown type.
17880 ** @cre Aborts if not found.
17881 **
17882 **
17883 ** @release 4.0.0
17884 ******************************************************************************/
17885 
acdGetValueNumS(const AjPStr token,const char * type,ajint pnum,ajint reftype)17886 static void* acdGetValueNumS(const AjPStr token, const char* type,
17887                              ajint pnum, ajint reftype)
17888 {
17889     return acdGetValueNumC(ajStrGetPtr(token), type,
17890 			   pnum, reftype);
17891 }
17892 
17893 
17894 
17895 
17896 /* @funcstatic acdHelp ********************************************************
17897 **
17898 ** Reports on program options if acdDoHelp is set, either by
17899 ** -help on the command line or by the prefix_HELP variable..
17900 **
17901 ** @return [void]
17902 **
17903 ** @release 1.0.0
17904 ** @@
17905 ******************************************************************************/
17906 
acdHelp(void)17907 static void acdHelp(void)
17908 {
17909     AcdPAcd pa;
17910     static AjPStr helpReq = NULL;
17911     static AjPStr helpOpt = NULL;
17912     static AjPStr helpAdv = NULL;
17913     static AjPStr helpAss = NULL;
17914     static AjPStr helpGen = NULL;
17915     static AjPStr helpStr = NULL;
17916 
17917     enum
17918     {
17919 	HELP_UNK, HELP_APP, HELP_REQ, HELP_OPT,
17920 	HELP_ADV, HELP_ASS, HELP_GEN
17921     } helpType;
17922 
17923     AjPStr* def;
17924     AjBool tmpBool;
17925     char hlpFlag;
17926     ajint iattr = 0;
17927     ajlong igrp = 0;
17928     AjPStr groupname = NULL;
17929     AjPStr tmpstr = NULL;
17930     AjPStr applversion = NULL;
17931 
17932     AjBool flagReq = ajFalse;
17933     AjBool flagOpt = ajFalse;
17934 
17935     AjPList reqlist = NULL;
17936     AjPList optlist = NULL;
17937     AjPList advlist = NULL;
17938     AjPList genlist = NULL;
17939     AjPList asslist = NULL;
17940     AjPList inlist = NULL;
17941     AjPList outlist = NULL;
17942 
17943     acdLog("acdHelp %B\n", acdDoHelp);
17944 
17945     if(!acdDoHelp)
17946         return;
17947 
17948     if(acdDoTable)
17949     {
17950 	reqlist = ajListNew();
17951 	optlist = ajListNew();
17952 	advlist = ajListNew();
17953 	genlist = ajListNew();
17954 	if(acdVerbose)
17955 	    asslist = ajListNew();
17956 	ajUserDumpC("<table border cellspacing=0 cellpadding=3 "
17957 	       "bgcolor=\"#ccccff\">");
17958 	/* was #f5f5ff */
17959     }
17960 
17961     if(acdDoXsd || acdDoGalaxy)
17962     {
17963         inlist = ajListNew();
17964         outlist = ajListNew();
17965     }
17966 
17967     acdLog("++ acdHelp\n");
17968 
17969     for(pa=acdList; pa; pa=pa->Next)
17970     {
17971 	if(acdIsStype(pa))
17972             continue;
17973 
17974 	hlpFlag = ' ';
17975 	acdLog("++ Name %S Level %d Assoc %B AssocQuals %x\n",
17976 	       pa->Name, pa->Level, pa->Assoc, pa->AssocQuals);
17977 	helpType = HELP_ADV;
17978 
17979 	if(pa->Level == ACD_APPL)
17980 	    helpType = HELP_APP;
17981 	else
17982 	    if(!acdIsQtype(pa))
17983                 continue;
17984 
17985 	def = pa->DefStr;
17986 
17987 	if(def && ajStrGetLen(def[DEF_ADDITIONAL]))
17988 	{
17989 	    if(acdHelpVarResolve(&helpStr, def[DEF_ADDITIONAL]))
17990 	    {
17991 		if(!ajStrToBool(helpStr, &tmpBool))
17992 		    acdErrorAcd(pa, "Bad additional flag %S\n",
17993 				def[DEF_ADDITIONAL]);
17994 	    }
17995 	    else
17996 	    {
17997 		tmpBool = ajTrue;
17998 		hlpFlag = '*';
17999 		flagOpt = ajTrue;
18000 	    }
18001 
18002 	    if(tmpBool)
18003 		helpType = HELP_OPT;
18004 	}
18005 
18006 	if(def && ajStrGetLen(def[DEF_STANDARD]))
18007 	{
18008 	    if(acdHelpVarResolve(&helpStr, def[DEF_STANDARD]))
18009 	    {
18010 		if(!ajStrToBool( helpStr, &tmpBool))
18011 		    acdErrorAcd(pa, "Bad standard flag %S\n",
18012 				def[DEF_STANDARD]);
18013 	    }
18014 	    else
18015 	    {
18016 		tmpBool = ajTrue;
18017 		hlpFlag = '*';
18018 		flagReq = ajTrue;
18019 	    }
18020 
18021 	    if(tmpBool)
18022 		helpType = HELP_REQ;
18023 	}
18024 
18025 	if(pa->Assoc)
18026             helpType = HELP_ASS;
18027 
18028 	acdLog("++ helpType %d\n", helpType);
18029 
18030 	switch(helpType)
18031 	{
18032             case HELP_APP:			/* application, do nothing */
18033                 iattr = acdFindAttrC(acdAttrAppl, "groups");
18034                 ajStrAssignS(&groupname, pa->AttrStr[iattr]);
18035                 iattr = acdFindAttrC(acdAttrAppl, "documentation");
18036                 ajStrAssignS(&acdAppldoc, pa->AttrStr[iattr]);
18037 
18038                 igrp = ajStrFindAnyC(groupname, ",|");
18039 
18040                 if(igrp != -1)
18041 		  ajStrTruncateLen(&groupname, (size_t) igrp);
18042 
18043                 ajStrFmtLower(&groupname);
18044                 ajStrExchangeKK(&groupname, ':', '_');
18045                 ajStrExchangeKK(&groupname, ' ', '_');
18046 
18047                 if(acdDoGalaxy)
18048                 {
18049                     ajUser("<tool id=\"EMBOSS64: %S1\" name=\"%S\" "
18050                            "version=\"%S\">\n"
18051                            "  <description>%S</description>\n"
18052                            "  <requirements>"
18053                            "<requirement type=\"package\" version=\"%S\">"
18054                            "emboss</requirement></requirements>\n"
18055                            "  <version_command>embossversion -auto"
18056                            "</version_command>",
18057                            acdProgram, acdProgram,
18058                            ajNamValueVersion(), acdAppldoc,
18059                            ajNamValueVersion());
18060 
18061                 }
18062 
18063                 if(acdDoXsd)
18064                 {
18065                     ajUserDumpC("<?xml version=\"1.0\" encoding=\"UTF-8\" "
18066                                 "standalone=\"yes\"?>");
18067                     ajUser("<xs:schema version=\"1.0\" "
18068                            "targetNamespace=\"http://embossws.ebi/%S\"",
18069                            acdProgram);
18070                     ajUser("  xmlns:tns=\"http://embossws.ebi/%S\"",
18071                            acdProgram);
18072                     ajUser("  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"");
18073                     ajUser("  xmlns:emboss=\"http://embossws.ebi/common\">");
18074                 }
18075                 break;
18076 
18077             case HELP_REQ:
18078                 acdHelpAppend(pa, &helpReq, hlpFlag);
18079                 acdHelpTable(pa, reqlist);
18080                 break;
18081 
18082             case HELP_OPT:
18083                 acdHelpAppend(pa, &helpOpt, hlpFlag);
18084                 acdHelpTable(pa, optlist);
18085                 break;
18086 
18087             case HELP_ADV:
18088                 acdHelpAppend(pa, &helpAdv, hlpFlag);
18089                 acdHelpTable(pa, advlist);
18090                 break;
18091 
18092             case HELP_ASS:	   /* associated - process after the master */
18093                 break;
18094 
18095             case HELP_GEN:	   /* associated - process after the app    */
18096                 break;
18097 
18098             default:
18099                 acdErrorAcd(pa, "unknown qualifier type %d in acdHelp",
18100                             helpType);
18101 	}
18102 
18103 	if(acdType[pa->Type].Section == acdSecOutput)
18104         {
18105             if(acdDoXsd)
18106                 acdHelpXsd(pa, outlist);
18107             else if(acdDoGalaxy)
18108                 acdHelpGalaxy(pa, outlist);
18109         }
18110         else if(pa->Level != ACD_APPL)
18111         {
18112             if(acdDoXsd)
18113                 acdHelpXsd(pa, inlist);
18114             else if(acdDoGalaxy)
18115                 acdHelpGalaxy(pa, inlist);
18116         }
18117 
18118 	if(pa->AssocQuals)
18119 	{
18120 	    if(helpType == HELP_APP)
18121 	    {
18122 		if(acdVerbose)
18123 		    acdHelpAssoc(pa, &helpGen, NULL);
18124 		else
18125 		    acdHelpAssoc(pa, &helpGen, "help");
18126 
18127                 acdHelpAssocTable(pa, genlist);
18128 	    }
18129 	    else
18130 	    {
18131 		if(acdVerbose)
18132 		{
18133 		    acdHelpAssoc(pa, &helpAss, NULL);
18134 		    acdHelpAssocTable(pa, asslist);
18135 		}
18136 	    }
18137 	}
18138     }
18139 
18140     if(!acdDoXsd && !acdDoGalaxy)
18141     {
18142         /*
18143         ** report 1-line documentation
18144         ** report version (s)
18145          */
18146 
18147         acdAttrResolve(acdApplAcd, "documentation", &tmpstr);
18148 
18149         if(!acdAuto && !acdDoTable && ajStrGetLen(tmpstr))
18150         {
18151             ajStrFmtWrap(&tmpstr, 75);
18152             ajUserDumpS(tmpstr);
18153         }
18154 
18155         ajFmtPrintS(&tmpstr, "EMBOSS:%s", VERSION);
18156 
18157         if(ajStrGetLen(tmpstr) < 14)
18158             ajStrAppendC(&tmpstr, ".0");
18159 
18160         if(ajStrGetLen(acdPackVersion))
18161             ajFmtPrintAppS(&tmpstr, " %S:%S", acdPackName, acdPackVersion);
18162 
18163         acdAttrResolve(acdApplAcd, "versionnumber", &applversion);
18164 
18165         if(ajStrGetLen(applversion))
18166         {
18167             ajFmtPrintAppS(&tmpstr, " %S:%S", acdApplAcd->Name, applversion);
18168             ajStrDel(&applversion);
18169         }
18170 
18171         if(!acdDoTable)
18172             ajUser("Version: %S\n", tmpstr);
18173         ajStrDel(&tmpstr);
18174         ajStrDel(&applversion);
18175 
18176         if(flagReq)
18177             acdHelpShow(helpReq,
18178                         "Standard (Mandatory) qualifiers "
18179                         "(* if not always prompted)");
18180         else
18181             acdHelpShow(helpReq, "Standard (Mandatory) qualifiers");
18182 
18183         acdHelpTableShow(NULL, "");
18184         acdHelpTableShow(reqlist, "Standard (Mandatory) qualifiers");
18185 
18186         if(flagOpt)
18187             acdHelpShow(helpOpt,
18188                         "Additional (Optional) qualifiers "
18189                         "(* if not always prompted)");
18190         else
18191             acdHelpShow(helpOpt, "Additional (Optional) qualifiers");
18192 
18193         acdHelpTableShow(optlist, "Additional (Optional) qualifiers");
18194         acdHelpShow(helpAdv, "Advanced (Unprompted) qualifiers");
18195         acdHelpTableShow(advlist, "Advanced (Unprompted) qualifiers");
18196 
18197         if(acdVerbose) acdHelpShow
18198                            (helpAss, "Associated qualifiers");
18199 
18200         acdHelpShow(helpGen, "General qualifiers");
18201 
18202         if(acdVerbose && acdDoTable)
18203             acdHelpTableShow(asslist, "Associated qualifiers");
18204 
18205         if(acdVerbose && acdDoTable)
18206             acdHelpTableShow(genlist, "General qualifiers");
18207     }
18208 
18209     if(acdDoXsd)
18210     {
18211         acdHelpXsdShow(inlist, outlist);
18212         ajUserDumpC("</xs:schema>");
18213     }
18214     else if(acdDoGalaxy)
18215     {
18216         acdHelpGalaxyShow(inlist, outlist);
18217         ajUserDumpC("");
18218     }
18219     else if(acdDoTable)
18220         ajUserDumpC("</table>");
18221 
18222     ajExit();
18223 
18224     return;
18225 }
18226 
18227 
18228 
18229 
18230 /* @funcstatic acdHelpAssoc ***************************************************
18231 **
18232 ** Processes all associated qualifiers for a qualifier or for the application.
18233 **
18234 ** If a qualifier name is given (e.g. "help") then only that qualifier
18235 ** is processed.
18236 **
18237 ** @param [r] thys [const AcdPAcd]  ACD object
18238 ** @param [u] str [AjPStr*] Help text being built
18239 ** @param [r] name [const char*] Single name to process
18240 ** @return [void]
18241 **
18242 ** @release 1.0.0
18243 ** @@
18244 ******************************************************************************/
18245 
acdHelpAssoc(const AcdPAcd thys,AjPStr * str,const char * name)18246 static void acdHelpAssoc(const AcdPAcd thys, AjPStr *str, const char* name)
18247 {
18248     static AjPStr line  = NULL;
18249     static AjPStr qname = NULL;
18250     static AjPStr qtype = NULL;
18251     static AjPStr text  = NULL;
18252     AcdPQual quals;
18253     ajint i;
18254 
18255     acdLog("++ acdHelpAssoc %S\n", thys->Name);
18256 
18257     if(thys->Level == ACD_APPL)
18258 	quals = acdQualAppl;
18259     else
18260     {
18261 	ajFmtPrintS(&line, "\n   \"-%S\" associated qualifiers\n",
18262 		    thys->Name);
18263 	ajStrAppendS(str, line);
18264 	quals = acdType[thys->Type].Quals;
18265     }
18266 
18267     acdLog("++ type %d quals %x\n", thys->Type, quals);
18268 
18269     if(quals)
18270     {
18271 	for(i=0; quals[i].Name; i++)
18272 	{
18273 	    acdLog("++ quals[%d].Name %s\n", i, quals[i].Name);
18274 
18275 	    if(name && strcmp(name, quals[i].Name))
18276 		continue;
18277 
18278 	    if(thys->PNum)
18279 		ajFmtPrintS(&qname, " -%s%d",
18280 			    quals[i].Name, thys->PNum);
18281 	    else
18282 		ajFmtPrintS(&qname, " -%s", quals[i].Name);
18283 
18284 	    ajStrAssignC(&qtype, quals[i].Type);
18285 	    ajFmtPrintS(&line, "  %-20S %-10S ",
18286 			qname,  qtype);
18287 	    ajStrAssignC(&text, quals[i].Help);
18288 	    acdTextFormat(&text);
18289 	    ajStrFmtWrapLeft(&text, 45, 34, 0);
18290 	    ajStrCutStart(&text, 34);
18291 	    ajStrAppendS(&line, text);
18292 	    ajStrAppendC(&line, "\n");
18293 	    ajStrAppendS(str, line);
18294 	}
18295     }
18296 
18297     return;
18298 }
18299 
18300 
18301 
18302 
18303 /* @funcstatic acdHelpAppend **************************************************
18304 **
18305 ** Appends a qualifier and its help text to a help category string.
18306 **
18307 ** @param [r] thys [const AcdPAcd]  ACD object
18308 ** @param [u] str [AjPStr*] Help text being built
18309 ** @param [r] flag [char] Flag character. Usually blank, but an asterisk
18310 **                         is used if the status (optional/required) is
18311 **                         uncertain.
18312 ** @return [void]
18313 **
18314 ** @release 1.0.0
18315 ** @@
18316 ******************************************************************************/
18317 
acdHelpAppend(const AcdPAcd thys,AjPStr * str,char flag)18318 static void acdHelpAppend(const AcdPAcd thys, AjPStr *str, char flag)
18319 {
18320     static AjPStr name    = NULL;
18321     static AjPStr valstr  = NULL;
18322     static AjPStr nostr   = NULL;
18323     static AjPStr nullstr = NULL;
18324     static AjPStr text    = NULL;
18325     static AjPStr line    = NULL;
18326     static AjPStr type    = NULL;
18327     AjBool boolval;
18328 
18329     AjPStr defstr;
18330 
18331     nullstr = ajStrNew();
18332 
18333     if(ajCharMatchC("list", acdType[thys->Type].Name))
18334 	ajStrAssignC(&type, "menu");
18335     else
18336 	ajStrAssignC(&type, acdType[thys->Type].Name);
18337 
18338     if(thys->DefStr)
18339 	defstr = thys->OrigStr;
18340     else
18341 	defstr = nullstr;
18342 
18343     ajStrAssignClear(&nostr);
18344 
18345     if(acdIsQtype(thys) &&
18346        (ajCharMatchC("boolean", acdType[thys->Type].Name) ||
18347 	ajCharMatchC("toggle", acdType[thys->Type].Name) ))
18348     {
18349 	if(ajStrToBool(defstr, &boolval) && boolval)
18350 	    ajStrAssignC(&nostr, "[no]");
18351 	defstr = nullstr;
18352     }
18353 
18354     ajStrAssignS(&valstr, defstr);
18355 
18356     /*
18357      **  warning - don't try acdVarResolve here because we have not yet
18358      **  read in the data and things like calculated attributes do not exist
18359      */
18360 
18361     if(thys->Level == ACD_PARAM)
18362 	ajFmtPrintS(&name, "[-%S%S]", nostr, thys->Name);
18363     else
18364 	ajFmtPrintS(&name, " -%S%S", nostr, thys->Name);
18365 
18366     ajFmtPrintS(&line, "%c %-20S %-10S ", flag, name, type);
18367 
18368     if(!acdDoTable)
18369     {
18370 	acdHelpExpect(thys, ajFalse, &text);
18371 
18372 	if(ajStrGetLen(text))
18373 	{
18374 	    ajStrInsertC(&text, 0, "[");
18375 	    ajStrAppendC(&text, "] ");
18376 	}
18377     }
18378 
18379     acdHelpText(thys, &text);
18380 
18381     if(ajStrGetLen(text))
18382        ajStrAppendC(&text, " ");
18383 
18384     if(!acdDoTable)
18385 	acdHelpValid(thys, ajFalse, &text);
18386 
18387     ajStrRemoveWhiteSpaces(&text);
18388     acdTextFormat(&text);
18389     ajStrFmtWrapLeft(&text, 45, 34, 0);
18390     ajStrCutStart(&text, 34);
18391     ajStrAppendS(&line, text);
18392     ajStrAppendC(&line, "\n");
18393     ajStrAppendS(str, line);
18394 
18395     ajStrDel(&name);
18396     ajStrDel(&valstr);
18397     ajStrDel(&nostr);
18398     ajStrDel(&nullstr);
18399     ajStrDel(&text);
18400     ajStrDel(&line);
18401     ajStrDel(&type);
18402 
18403     return;
18404 }
18405 
18406 
18407 
18408 
18409 /* @funcstatic acdHelpValidAlign **********************************************
18410 **
18411 ** Generates valid description for a alignment output
18412 **
18413 ** @param [r] thys [const AcdPAcd] ACD object
18414 ** @param [r] table [AjBool] True if writing acdtable HTML table
18415 ** @param [w] str [AjPStr*] Help text (if any) generated
18416 ** @return [void]
18417 **
18418 ** @release 6.4.0
18419 ** @@
18420 ******************************************************************************/
18421 
acdHelpValidAlign(const AcdPAcd thys,AjBool table,AjPStr * str)18422 static void acdHelpValidAlign(const AcdPAcd thys, AjBool table, AjPStr* str)
18423 {
18424     AjPStr fmt = NULL;
18425 
18426     if(!thys)
18427         return;
18428 
18429     acdGetValueAssocDefault(thys, "aformat", &fmt);
18430 
18431     if(ajStrGetLen(fmt))
18432         ajFmtPrintAppS(str, "(default -aformat %S)", fmt);
18433 
18434     else if(table)
18435 	ajStrAssignClear(str);
18436 
18437     ajStrDel(&fmt);
18438 
18439     return;
18440 }
18441 
18442 
18443 
18444 
18445 /* @funcstatic acdHelpValidReport *********************************************
18446 **
18447 ** Generates valid description for a report output
18448 **
18449 ** @param [r] thys [const AcdPAcd] ACD object
18450 ** @param [r] table [AjBool] True if writing acdtable HTML table
18451 ** @param [w] str [AjPStr*] Help text (if any) generated
18452 ** @return [void]
18453 **
18454 ** @release 6.4.0
18455 ** @@
18456 ******************************************************************************/
18457 
acdHelpValidReport(const AcdPAcd thys,AjBool table,AjPStr * str)18458 static void acdHelpValidReport(const AcdPAcd thys, AjBool table, AjPStr* str)
18459 {
18460     AjPStr fmt = NULL;
18461 
18462     if(!thys)
18463         return;
18464 
18465     acdGetValueAssocDefault(thys, "rformat", &fmt);
18466 
18467     if(ajStrGetLen(fmt))
18468         ajFmtPrintAppS(str, "(default -rformat %S)", fmt);
18469 
18470     else if(table)
18471 	ajStrAssignClear(str);
18472 
18473     ajStrDel(&fmt);
18474 
18475     return;
18476 }
18477 
18478 
18479 
18480 
18481 /* @funcstatic acdHelpValidSeq ************************************************
18482 **
18483 ** Generates valid description for an input sequence type.
18484 **
18485 ** @param [r] thys [const AcdPAcd] ACD object
18486 ** @param [r] table [AjBool] True if writing acdtable HTML table
18487 ** @param [w] str [AjPStr*] Help text (if any) generated
18488 ** @return [void]
18489 **
18490 ** @release 1.0.0
18491 ** @@
18492 ******************************************************************************/
18493 
acdHelpValidSeq(const AcdPAcd thys,AjBool table,AjPStr * str)18494 static void acdHelpValidSeq(const AcdPAcd thys, AjBool table, AjPStr* str)
18495 {
18496     if(!thys)
18497         return;
18498 
18499     if(table)
18500 	ajStrAssignClear(str);
18501 
18502     return;
18503 }
18504 
18505 
18506 
18507 
18508 /* @funcstatic acdHelpValidSeqout *********************************************
18509 **
18510 ** Generates valid description for an output sequence type.
18511 **
18512 ** @param [r] thys [const AcdPAcd] ACD object
18513 ** @param [r] table [AjBool] True if writing acdtable HTML table
18514 ** @param [w] str [AjPStr*] Help text (if any) generated
18515 ** @return [void]
18516 **
18517 ** @release 1.0.0
18518 ** @@
18519 ******************************************************************************/
18520 
acdHelpValidSeqout(const AcdPAcd thys,AjBool table,AjPStr * str)18521 static void acdHelpValidSeqout(const AcdPAcd thys, AjBool table, AjPStr* str)
18522 {
18523     if(!thys)
18524         return;
18525 
18526     if(table)
18527 	ajStrAssignClear(str);
18528 
18529     return;
18530 }
18531 
18532 
18533 
18534 
18535 /* @funcstatic acdHelpValidOut ************************************************
18536 **
18537 ** Generates valid description for an outfile type.
18538 **
18539 ** @param [r] thys [const AcdPAcd] ACD object
18540 ** @param [r] table [AjBool] True if writing acdtable HTML table
18541 ** @param [w] str [AjPStr*] Help text (if any) generated
18542 ** @return [void]
18543 **
18544 ** @release 1.0.0
18545 ** @@
18546 ******************************************************************************/
18547 
acdHelpValidOut(const AcdPAcd thys,AjBool table,AjPStr * str)18548 static void acdHelpValidOut(const AcdPAcd thys, AjBool table, AjPStr* str)
18549 {
18550     if(!thys)
18551         return;
18552 
18553     if(table)
18554 	ajStrAssignClear(str);
18555 
18556     return;
18557 }
18558 
18559 
18560 
18561 
18562 /* @funcstatic acdHelpValidIn *************************************************
18563 **
18564 ** Generates valid description for an infile type.
18565 **
18566 ** @param [r] thys [const AcdPAcd] ACD object
18567 ** @param [r] table [AjBool] True if writing acdtable HTML table
18568 ** @param [w] str [AjPStr*] Help text (if any) generated
18569 ** @return [void]
18570 **
18571 ** @release 1.0.0
18572 ** @@
18573 ******************************************************************************/
18574 
acdHelpValidIn(const AcdPAcd thys,AjBool table,AjPStr * str)18575 static void acdHelpValidIn(const AcdPAcd thys, AjBool table, AjPStr* str)
18576 {
18577     if(!thys)
18578         return;
18579 
18580     if(table)
18581 	ajStrAssignClear(str);
18582 
18583     return;
18584 }
18585 
18586 
18587 
18588 
18589 /* @funcstatic acdHelpValidData ***********************************************
18590 **
18591 ** Generates valid description for a datafile type.
18592 **
18593 ** @param [r] thys [const AcdPAcd] ACD object
18594 ** @param [r] table [AjBool] True if writing acdtable HTML table
18595 ** @param [w] str [AjPStr*] Help text (if any) generated
18596 ** @return [void]
18597 **
18598 ** @release 1.0.0
18599 ** @@
18600 ******************************************************************************/
18601 
acdHelpValidData(const AcdPAcd thys,AjBool table,AjPStr * str)18602 static void acdHelpValidData(const AcdPAcd thys, AjBool table, AjPStr* str)
18603 {
18604     if(!thys)
18605         return;
18606 
18607     if(table)
18608 	ajStrAssignClear(str);
18609 
18610     return;
18611 }
18612 
18613 
18614 
18615 
18616 /* @funcstatic acdHelpValidInt ************************************************
18617 **
18618 ** Generates valid description for an integer type.
18619 **
18620 ** @param [r] thys [const AcdPAcd] ACD object
18621 ** @param [r] table [AjBool] True if writing acdtable HTML table
18622 ** @param [w] str [AjPStr*] Help text (if any) generated
18623 ** @return [void]
18624 **
18625 ** @release 1.0.0
18626 ** @@
18627 ******************************************************************************/
18628 
acdHelpValidInt(const AcdPAcd thys,AjBool table,AjPStr * str)18629 static void acdHelpValidInt(const AcdPAcd thys, AjBool table, AjPStr* str)
18630 {
18631     ajint imin;
18632     ajint imax;
18633 
18634     acdAttrValueStr(thys, "minimum", "$", &acdTmpStr);
18635     if(!ajStrToInt(acdTmpStr, &imin))
18636 	imin = INT_MIN;
18637 
18638     acdAttrValueStr(thys, "maximum", "$", &acdTmpStr);
18639     if(!ajStrToInt(acdTmpStr, &imax))
18640 	imax = INT_MAX;
18641 
18642     if(table)
18643 	ajStrAssignClear(str);
18644     else
18645 	ajStrAppendC(str, " (");
18646 
18647     if(imax != INT_MAX)
18648     {
18649 	if(imin != INT_MIN)
18650 	    ajFmtPrintAppS(str, "Integer from %d to %d", imin, imax);
18651 	else
18652 	    ajFmtPrintAppS(str, "Integer up to %d", imax);
18653     }
18654     else
18655     {
18656 	if(imin != INT_MIN)
18657 	    ajFmtPrintAppS(str, "Integer %d or more", imin);
18658 	else
18659 	    ajFmtPrintAppS(str, "Any integer value");
18660     }
18661 
18662     if(!table)
18663 	ajStrAppendC(str, ")");
18664 
18665     return;
18666 }
18667 
18668 
18669 
18670 
18671 /* @funcstatic acdHelpValidFloat **********************************************
18672 **
18673 ** Generates valid description for a floating point type.
18674 **
18675 ** @param [r] thys [const AcdPAcd] ACD object
18676 ** @param [r] table [AjBool] True if writing acdtable HTML table
18677 ** @param [w] str [AjPStr*] Help text (if any) generated
18678 ** @return [void]
18679 **
18680 ** @release 1.0.0
18681 ** @@
18682 ******************************************************************************/
18683 
acdHelpValidFloat(const AcdPAcd thys,AjBool table,AjPStr * str)18684 static void acdHelpValidFloat(const AcdPAcd thys, AjBool table, AjPStr* str)
18685 {
18686     float vfmin;
18687     float vfmax;
18688     ajint iprec;
18689 
18690     acdAttrValueStr(thys, "minimum", "$", &acdTmpStr);
18691 
18692     if(!ajStrToFloat(acdTmpStr, &vfmin))
18693 	vfmin = -FLT_MAX;
18694 
18695     acdAttrValueStr(thys, "maximum", "$", &acdTmpStr);
18696 
18697     if(!ajStrToFloat(acdTmpStr, &vfmax))
18698 	vfmax = FLT_MAX;
18699 
18700     acdAttrValueStr(thys, "precision", "$", &acdTmpStr);
18701 
18702     if(!ajStrToInt(acdTmpStr, &iprec))
18703 	iprec = 3;
18704 
18705     if(table)
18706 	ajStrAssignClear(str);
18707     else
18708 	ajStrAppendC(str, " (");
18709 
18710     if(vfmax != FLT_MAX)
18711     {
18712 	if(vfmin != -FLT_MAX)
18713 	    ajFmtPrintAppS(str, "Number from %.*f to %.*f",
18714 			iprec, vfmin, iprec, vfmax);
18715 	else
18716 	    ajFmtPrintAppS(str, "Number up to %.*f", iprec, vfmax);
18717     }
18718     else
18719     {
18720 	if(vfmin != -FLT_MAX)
18721 	    ajFmtPrintAppS(str, "Number %.*f or more", iprec, vfmin);
18722 	else
18723 	    ajFmtPrintAppS(str, "Any numeric value");
18724     }
18725 
18726     if(!table)
18727 	ajStrAppendC(str, ")");
18728 
18729     return;
18730 }
18731 
18732 
18733 
18734 
18735 /* @funcstatic acdHelpValidCodon **********************************************
18736 **
18737 ** Generates valid description for a codon usage table type.
18738 **
18739 ** @param [r] thys [const AcdPAcd] ACD object
18740 ** @param [r] table [AjBool] True if writing acdtable HTML table
18741 ** @param [w] str [AjPStr*] Help text (if any) generated
18742 ** @return [void]
18743 **
18744 ** @release 1.0.0
18745 ** @@
18746 ******************************************************************************/
18747 
acdHelpValidCodon(const AcdPAcd thys,AjBool table,AjPStr * str)18748 static void acdHelpValidCodon(const AcdPAcd thys, AjBool table, AjPStr* str)
18749 {
18750     if(!thys)
18751         return;
18752 
18753     if(table)
18754 	ajStrAssignClear(str);
18755 
18756     return;
18757 }
18758 
18759 
18760 
18761 
18762 /* @funcstatic acdHelpValidDirlist ********************************************
18763 **
18764 ** Generates valid description for a dirlist type.
18765 **
18766 ** @param [r] thys [const AcdPAcd] ACD object
18767 ** @param [r] table [AjBool] True if writing acdtable HTML table
18768 ** @param [w] str [AjPStr*] Help text (if any) generated
18769 ** @return [void]
18770 **
18771 ** @release 1.9.0
18772 ** @@
18773 ******************************************************************************/
18774 
acdHelpValidDirlist(const AcdPAcd thys,AjBool table,AjPStr * str)18775 static void acdHelpValidDirlist(const AcdPAcd thys, AjBool table, AjPStr* str)
18776 {
18777     if(!thys)
18778         return;
18779 
18780     if(table)
18781 	ajStrAssignClear(str);
18782 
18783     return;
18784 }
18785 
18786 
18787 
18788 
18789 /* @funcstatic acdHelpValidFilelist *******************************************
18790 **
18791 ** Generates valid description for a filelist type.
18792 **
18793 ** @param [r] thys [const AcdPAcd] ACD object
18794 ** @param [r] table [AjBool] True if writing acdtable HTML table
18795 ** @param [w] str [AjPStr*] Help text (if any) generated
18796 ** @return [void]
18797 **
18798 ** @release 2.5.0
18799 ** @@
18800 ******************************************************************************/
18801 
acdHelpValidFilelist(const AcdPAcd thys,AjBool table,AjPStr * str)18802 static void acdHelpValidFilelist(const AcdPAcd thys, AjBool table, AjPStr* str)
18803 {
18804     if(!thys)
18805         return;
18806 
18807     if(table)
18808 	ajStrAssignClear(str);
18809 
18810     return;
18811 }
18812 
18813 
18814 
18815 
18816 /* @funcstatic acdHelpValidMatrix *********************************************
18817 **
18818 ** Generates valid description for a comparison matrix type.
18819 **
18820 ** @param [r] thys [const AcdPAcd] ACD object
18821 ** @param [r] table [AjBool] True if writing acdtable HTML table
18822 ** @param [w] str [AjPStr*] Help text (if any) generated
18823 ** @return [void]
18824 **
18825 ** @release 1.0.0
18826 ** @@
18827 ******************************************************************************/
18828 
acdHelpValidMatrix(const AcdPAcd thys,AjBool table,AjPStr * str)18829 static void acdHelpValidMatrix(const AcdPAcd thys, AjBool table, AjPStr* str)
18830 {
18831     if(!thys)
18832         return;
18833 
18834     if(table)
18835 	ajStrAssignClear(str);
18836 
18837     return;
18838 }
18839 
18840 
18841 
18842 
18843 /* @funcstatic acdHelpValidFeatout ********************************************
18844 **
18845 ** Generates valid description for a feature output type.
18846 **
18847 ** @param [r] thys [const AcdPAcd] ACD object
18848 ** @param [r] table [AjBool] True if writing acdtable HTML table
18849 ** @param [w] str [AjPStr*] Help text (if any) generated
18850 ** @return [void]
18851 **
18852 ** @release 1.0.0
18853 ** @@
18854 ******************************************************************************/
18855 
acdHelpValidFeatout(const AcdPAcd thys,AjBool table,AjPStr * str)18856 static void acdHelpValidFeatout(const AcdPAcd thys, AjBool table, AjPStr* str)
18857 {
18858     if(!thys)
18859         return;
18860 
18861     if(table)
18862 	ajStrAssignClear(str);
18863 
18864     return;
18865 }
18866 
18867 
18868 
18869 
18870 /* @funcstatic acdHelpValidFeatures *******************************************
18871 **
18872 ** Generates valid description for an input feature type.
18873 **
18874 ** @param [r] thys [const AcdPAcd] ACD object
18875 ** @param [r] table [AjBool] True if writing acdtable HTML table
18876 ** @param [w] str [AjPStr*] Help text (if any) generated
18877 ** @return [void]
18878 **
18879 ** @release 6.0.0
18880 ** @@
18881 ******************************************************************************/
18882 
acdHelpValidFeatures(const AcdPAcd thys,AjBool table,AjPStr * str)18883 static void acdHelpValidFeatures(const AcdPAcd thys, AjBool table, AjPStr* str)
18884 {
18885     if(!thys)
18886         return;
18887 
18888     if(table)
18889 	ajStrAssignClear(str);
18890 
18891     return;
18892 }
18893 
18894 
18895 
18896 
18897 /* @funcstatic acdHelpValidRange **********************************************
18898 **
18899 ** Generates valid description for a sequence range.
18900 **
18901 ** @param [r] thys [const AcdPAcd] ACD object
18902 ** @param [r] table [AjBool] True if writing acdtable HTML table
18903 ** @param [w] str [AjPStr*] Help text (if any) generated
18904 ** @return [void]
18905 **
18906 ** @release 1.0.0
18907 ** @@
18908 ******************************************************************************/
18909 
acdHelpValidRange(const AcdPAcd thys,AjBool table,AjPStr * str)18910 static void acdHelpValidRange(const AcdPAcd thys, AjBool table, AjPStr* str)
18911 {
18912     if(!thys)
18913         return;
18914 
18915     if(table)
18916 	ajStrAssignClear(str);
18917 
18918     return;
18919 }
18920 
18921 
18922 
18923 
18924 /* @funcstatic acdHelpValidGraph **********************************************
18925 **
18926 ** Generates valid description for a graphics device type.
18927 **
18928 ** @param [r] thys [const AcdPAcd] ACD object
18929 ** @param [r] table [AjBool] True if writing acdtable HTML table
18930 ** @param [w] str [AjPStr*] Help text (if any) generated
18931 ** @return [void]
18932 **
18933 ** @release 1.0.0
18934 ** @@
18935 ******************************************************************************/
18936 
acdHelpValidGraph(const AcdPAcd thys,AjBool table,AjPStr * str)18937 static void acdHelpValidGraph(const AcdPAcd thys, AjBool table, AjPStr* str)
18938 {
18939     AjPList list;
18940     AjPStr name = NULL;
18941     ajint i     = 0;
18942 
18943     if(!thys)
18944         return;
18945 
18946     list = ajListstrNew();
18947 
18948     ajGraphicsListDevices(list);
18949 
18950     if(table)
18951 	ajFmtPrintAppS(str, "EMBOSS has a list of known devices, including ");
18952     else
18953 	ajFmtPrintAppS(str, " (");
18954 
18955     while(ajListstrPop(list, &name))
18956     {
18957 	if(i)
18958 	    ajFmtPrintAppS(str, ", ");
18959 
18960 	ajFmtPrintAppS(str, "%S", name);
18961 	ajStrDel(&name);
18962 	i++;
18963     }
18964 
18965     if(!table)
18966 	ajFmtPrintAppS(str, ")");
18967 
18968     ajListFree(&list);
18969 
18970     return;
18971 }
18972 
18973 
18974 
18975 
18976 /* @funcstatic acdHelpValidString *********************************************
18977 **
18978 ** Generates valid description for a string type.
18979 **
18980 ** @param [r] thys [const AcdPAcd] ACD object
18981 ** @param [r] table [AjBool] True if writing acdtable HTML table
18982 ** @param [w] str [AjPStr*] Help text (if any) generated
18983 ** @return [void]
18984 **
18985 ** @release 1.0.0
18986 ** @@
18987 ******************************************************************************/
18988 
acdHelpValidString(const AcdPAcd thys,AjBool table,AjPStr * str)18989 static void acdHelpValidString(const AcdPAcd thys, AjBool table, AjPStr* str)
18990 {
18991     ajint minlen;
18992     ajint maxlen;
18993     AjBool  word;
18994 
18995     acdAttrValueStr(thys, "minlength", "0", &acdTmpStr);
18996 
18997     if(!ajStrToInt(acdTmpStr, &minlen))
18998 	minlen = 0;
18999     acdAttrValueStr(thys, "maxlength", "0", &acdTmpStr);
19000 
19001     if(!ajStrToInt(acdTmpStr, &maxlen))
19002 	maxlen = 0;
19003     acdAttrValueStr(thys, "word", "0", &acdTmpStr);
19004 
19005     if(!ajStrToBool(acdTmpStr, &word))
19006 	ajFatal("Bad boolean value");
19007 
19008     if(table)
19009 	ajStrAssignClear(str);
19010     else
19011 	ajStrAppendC(str, " (");
19012 
19013     if(word)
19014 	ajFmtPrintAppS(str, "Any word");
19015     else
19016     	ajFmtPrintAppS(str, "Any string");
19017 
19018     if(maxlen > 0)
19019     {
19020 	if(minlen > 0)
19021 	    ajFmtPrintAppS(str, " from %d to %d characters",
19022 			   minlen, maxlen);
19023 	else
19024 	    ajFmtPrintAppS(str, " up to %d characters", maxlen);
19025     }
19026     else
19027     {
19028 	if(minlen > 0)
19029 	    ajFmtPrintAppS(str, " of at least %d characters", minlen);
19030     }
19031 
19032 
19033     acdAttrValueStr(thys, "pattern", "", &acdTmpStr);
19034 
19035     if(ajStrGetLen(acdTmpStr))
19036 	ajFmtPrintAppS(str, ", matching regular expression /%S/", acdTmpStr);
19037 
19038     if(!table)
19039 	ajStrAppendC(str, ")");
19040 
19041     return;
19042 }
19043 
19044 
19045 
19046 
19047 /* @funcstatic acdHelpValidRegexp *********************************************
19048 **
19049 ** Generates valid description for a regular expression type.
19050 **
19051 ** @param [r] thys [const AcdPAcd] ACD object
19052 ** @param [r] table [AjBool] True if writing acdtable HTML table
19053 ** @param [w] str [AjPStr*] Help text (if any) generated
19054 ** @return [void]
19055 **
19056 ** @release 1.0.0
19057 ** @@
19058 ******************************************************************************/
19059 
acdHelpValidRegexp(const AcdPAcd thys,AjBool table,AjPStr * str)19060 static void acdHelpValidRegexp(const AcdPAcd thys, AjBool table, AjPStr* str)
19061 {
19062     ajint minlen;
19063     ajint maxlen;
19064 
19065     acdAttrValueStr(thys, "minlength", "0", &acdTmpStr);
19066 
19067     if(!ajStrToInt(acdTmpStr, &minlen))
19068 	minlen = 0;
19069 
19070     acdAttrValueStr(thys, "maxlength", "0", &acdTmpStr);
19071 
19072     if(!ajStrToInt(acdTmpStr, &maxlen))
19073 	maxlen = 0;
19074 
19075     if(table)
19076 	ajStrAssignClear(str);
19077     else
19078 	ajStrAppendC(str, " (");
19079 
19080     if(maxlen > 0)
19081     {
19082 	if(minlen > 0)
19083 	    ajFmtPrintS(str,
19084 			"A regular expression pattern from %d to "
19085 			"%d characters",
19086 			minlen, maxlen);
19087 	else
19088 	    ajFmtPrintS(str,
19089 			"A regular expression pattern up to %d characters",
19090 			maxlen);
19091     }
19092     else
19093     {
19094 	if(minlen > 0)
19095 	    ajFmtPrintS(str,
19096 			"A regular expression pattern of at least "
19097 			"%d characters",
19098 			minlen);
19099 	else
19100 	    ajStrAssignC(str,
19101 		      "Any regular expression pattern is accepted");
19102     }
19103 
19104     if(!table)
19105 	ajStrAppendC(str, ")");
19106 
19107     return;
19108 }
19109 
19110 
19111 
19112 
19113 /* @funcstatic acdHelpValidList ***********************************************
19114 **
19115 ** Generates valid description for a list type.
19116 **
19117 ** @param [r] thys [const AcdPAcd] ACD object
19118 ** @param [r] table [AjBool] True if writing acdtable HTML table
19119 ** @param [w] str [AjPStr*] Help text (if any) generated
19120 ** @return [void]
19121 **
19122 ** @release 1.0.0
19123 ** @@
19124 ******************************************************************************/
19125 
acdHelpValidList(const AcdPAcd thys,AjBool table,AjPStr * str)19126 static void acdHelpValidList(const AcdPAcd thys, AjBool table, AjPStr* str)
19127 {
19128     AjPStr codedelim   = NULL;
19129     AjPStr delim       = NULL;
19130     AjPStr value       = NULL;
19131 
19132     AjPStrTok handle;
19133     AjPStrTok codehandle;
19134 
19135     static AjPStr code = NULL;
19136     static AjPStr desc = NULL;
19137     static AjPStr line = NULL;
19138 
19139     acdAttrValueStr(thys, "delimiter", ";", &delim);
19140 
19141     acdAttrValueStr(thys, "value", "", &value);
19142 
19143     if(!ajStrGetLen(value))
19144 	if(!acdKnownValueList(thys, &value))
19145 	    acdError("No value defined for list");
19146 
19147     handle = ajStrTokenNewS(value, delim);
19148 
19149     if(table)
19150 	ajFmtPrintAppS(str, "<table>");
19151     else
19152 	ajFmtPrintAppS(str, " (Values: ");
19153 
19154     acdAttrValueStr(thys, "codedelimiter", ":", &codedelim);
19155 
19156     while(ajStrTokenNextFind(handle, &line))
19157     {
19158 	codehandle = ajStrTokenNewS(line, codedelim);
19159 	ajStrTokenNextParse(codehandle, &code);
19160 	ajStrTokenNextParseS(codehandle, delim, &desc);
19161 	acdTextTrim(&code);
19162 	acdTextTrim(&desc);
19163 	if(table)
19164 	    ajFmtPrintAppS(str, "<tr><td>%S</td> <td><i>(%S)</i></td></tr>",
19165 			   code, desc);
19166 	else
19167 	    ajFmtPrintAppS(str, "%S (%S); ",
19168 			   code, desc);
19169 	ajStrTokenDel(&codehandle);
19170     }
19171 
19172     if(table)
19173 	ajFmtPrintAppS(str, "</table>");
19174     else
19175     {
19176 	ajStrCutEnd(str, 2);
19177 	ajStrAppendC(str, ")");
19178     }
19179 
19180     ajStrTokenDel(&handle);
19181 
19182     return;
19183 }
19184 
19185 
19186 
19187 
19188 /* @funcstatic acdHelpValidSelect *********************************************
19189 **
19190 ** Generates valid description for a select type.
19191 **
19192 ** @param [r] thys [const AcdPAcd] ACD object
19193 ** @param [r] table [AjBool] True if writing acdtable HTML table
19194 ** @param [w] str [AjPStr*] Help text (if any) generated
19195 ** @return [void]
19196 **
19197 ** @release 1.0.0
19198 ** @@
19199 ******************************************************************************/
19200 
acdHelpValidSelect(const AcdPAcd thys,AjBool table,AjPStr * str)19201 static void acdHelpValidSelect(const AcdPAcd thys, AjBool table, AjPStr* str)
19202 {
19203     AjPStr delim       = NULL;
19204     AjPStr value       = NULL;
19205     AjPStrTok handle;
19206     static AjPStr desc = NULL;
19207     static const char* white = " \t\n\r";
19208 
19209     acdAttrValueStr(thys, "delimiter", ";", &delim);
19210 
19211     acdAttrValueStr(thys, "value", "", &value);
19212 
19213     if(!ajStrGetLen(value))
19214 	if(!acdKnownValueSelect(thys, &value))
19215 	    acdError("No value defined for selection");
19216 
19217     handle = ajStrTokenNewS(value, delim);
19218 
19219     while(ajStrTokenNextFind(handle, &desc))
19220     {
19221 	ajStrTrimC(&desc, white);
19222 	if(table)
19223 	    ajFmtPrintAppS(str, "%S<br>", desc);
19224 	else
19225 	{
19226 	    if(ajStrGetLen(*str))
19227 		ajStrAppendK(str, ' ');
19228 	    ajFmtPrintAppS(str, "%S", desc);
19229 	}
19230     }
19231 
19232     ajStrTokenDel(&handle);
19233 
19234     return;
19235 }
19236 
19237 
19238 
19239 
19240 /* @funcstatic acdHelpValid ***************************************************
19241 **
19242 ** Generates help text for an ACD object using the help, info, prompt
19243 ** and code settings.
19244 **
19245 ** @param [r] thys [const AcdPAcd] ACD object
19246 ** @param [r] table [AjBool] True if writing acdtable HTML table
19247 ** @param [w] str [AjPStr*] Help text (if any) generated. Only written to if
19248 **                          initially empty
19249 ** @return [void]
19250 **
19251 ** @release 1.0.0
19252 ** @@
19253 ******************************************************************************/
19254 
acdHelpValid(const AcdPAcd thys,AjBool table,AjPStr * str)19255 static void acdHelpValid(const AcdPAcd thys, AjBool table, AjPStr* str)
19256 {
19257     ajint i;
19258     AjPStr tmpstr = NULL;
19259 
19260     if(table && ajStrGetLen(*str))
19261 	return;
19262 
19263     if(acdAttrValueStr(thys, "valid", "", &tmpstr))
19264     {
19265 	if(table)
19266 	    ajStrAppendS(str, tmpstr);
19267 	else
19268 	    ajFmtPrintAppS(str, "(%S)", tmpstr);
19269 
19270 	return;
19271     }
19272 
19273     /* special processing for sequences, outseq, outfile */
19274 
19275     for(i=0; acdValue[i].Name; i++)
19276 	if(ajCharMatchC(acdType[thys->Type].Name, acdValue[i].Name))
19277 	{
19278 	    /* Calling funclist acdValue() */
19279 	    if(acdValue[i].Valid)
19280 		(*acdValue[i].Valid)(thys, table, str);
19281 	    break;
19282 	}
19283 
19284     if(ajStrGetLen(*str))
19285 	return;
19286 
19287     ajStrAppendC(str, acdType[thys->Type].Valid);
19288 
19289     return;
19290 }
19291 
19292 
19293 
19294 
19295 /* @funcstatic acdHelpExpectSeq ***********************************************
19296 **
19297 ** Generates expected value description for an input sequence type.
19298 **
19299 ** @param [r] thys [const AcdPAcd] ACD object
19300 ** @param [r] table [AjBool] True if writing acdtable HTML table
19301 ** @param [w] str [AjPStr*] Help text (if any) generated
19302 ** @return [void]
19303 **
19304 ** @release 1.0.0
19305 ** @@
19306 ******************************************************************************/
19307 
acdHelpExpectSeq(const AcdPAcd thys,AjBool table,AjPStr * str)19308 static void acdHelpExpectSeq(const AcdPAcd thys, AjBool table, AjPStr* str)
19309 {
19310     if(!thys)
19311         return;
19312 
19313     if(table)
19314 	ajFmtPrintAppS(str, "<b>Required</b>");
19315 
19316     return;
19317 }
19318 
19319 
19320 
19321 
19322 /* @funcstatic acdHelpExpectSeqout ********************************************
19323 **
19324 ** Generates expected value description for an output sequence type.
19325 **
19326 ** @param [r] thys [const AcdPAcd] ACD object
19327 ** @param [r] table [AjBool] True if writing acdtable HTML table
19328 ** @param [w] str [AjPStr*] Help text (if any) generated
19329 ** @return [void]
19330 **
19331 ** @release 1.0.0
19332 ** @@
19333 ******************************************************************************/
19334 
acdHelpExpectSeqout(const AcdPAcd thys,AjBool table,AjPStr * str)19335 static void acdHelpExpectSeqout(const AcdPAcd thys, AjBool table, AjPStr* str)
19336 {
19337     if(!thys)
19338         return;
19339 
19340     if(table)
19341 	ajFmtPrintAppS(str, "<i>&lt;*&gt;</i>.<i>format</i>");
19342     else
19343 	ajFmtPrintAppS(str, "<sequence>.<format>");
19344 
19345     return;
19346 }
19347 
19348 
19349 
19350 
19351 /* @funcstatic acdHelpExpectOut ***********************************************
19352 **
19353 ** Generates expected value description for an outfile type.
19354 **
19355 ** @param [r] thys [const AcdPAcd] ACD object
19356 ** @param [r] table [AjBool] True if writing acdtable HTML table
19357 ** @param [w] str [AjPStr*] Help text (if any) generated
19358 ** @return [void]
19359 **
19360 ** @release 1.0.0
19361 ** @@
19362 ******************************************************************************/
19363 
acdHelpExpectOut(const AcdPAcd thys,AjBool table,AjPStr * str)19364 static void acdHelpExpectOut(const AcdPAcd thys, AjBool table, AjPStr* str)
19365 {
19366     if(!thys)
19367         return;
19368 
19369     if(table)
19370 	ajFmtPrintAppS(str, "<i>&lt;*&gt;</i>.%S", acdProgram);
19371     else
19372 	ajFmtPrintAppS(str, "*.%S", acdProgram);
19373 
19374     return;
19375 }
19376 
19377 
19378 
19379 
19380 /* @funcstatic acdHelpExpectInt ***********************************************
19381 **
19382 ** Generates expected value description for an integer type.
19383 **
19384 ** @param [r] thys [const AcdPAcd] ACD object
19385 ** @param [r] table [AjBool] True if writing acdtable HTML table
19386 ** @param [w] str [AjPStr*] Help text (if any) generated
19387 ** @return [void]
19388 **
19389 ** @release 1.0.0
19390 ** @@
19391 ******************************************************************************/
19392 
acdHelpExpectInt(const AcdPAcd thys,AjBool table,AjPStr * str)19393 static void acdHelpExpectInt(const AcdPAcd thys, AjBool table, AjPStr* str)
19394 {
19395     ajint i;
19396 
19397     acdAttrValueStr(thys, "default", "0", &acdTmpStr);
19398 
19399     if(ajStrToInt(acdTmpStr, &i))
19400 	ajFmtPrintAppS(str, "%d", i);
19401     else
19402     {
19403 	if(table)
19404 	    ajFmtPrintAppS(str, "<i>calculated value</i>");
19405     }
19406 
19407     return;
19408 }
19409 
19410 
19411 
19412 
19413 /* @funcstatic acdHelpExpectFloat *********************************************
19414 **
19415 ** Generates expected value description for a floating point type.
19416 **
19417 ** @param [r] thys [const AcdPAcd] ACD object
19418 ** @param [r] table [AjBool] True if writing acdtable HTML table
19419 ** @param [w] str [AjPStr*] Help text (if any) generated
19420 ** @return [void]
19421 **
19422 ** @release 1.0.0
19423 ** @@
19424 ******************************************************************************/
19425 
acdHelpExpectFloat(const AcdPAcd thys,AjBool table,AjPStr * str)19426 static void acdHelpExpectFloat(const AcdPAcd thys, AjBool table, AjPStr* str)
19427 {
19428     float f;
19429     ajint iprec;
19430 
19431     acdAttrValueStr(thys, "default", "0.0", &acdTmpStr);
19432 
19433     if(!ajStrToFloat(acdTmpStr, &f))
19434 	f = 0.0;
19435 
19436     acdAttrValueStr (thys, "precision", "3", &acdTmpStr);
19437     if(!ajStrToInt(acdTmpStr, &iprec))
19438 	iprec = 3;
19439 
19440     if(table)
19441 	ajFmtPrintAppS(str, "%.*f", iprec, f);
19442     else
19443 	ajFmtPrintAppS(str, "%.*f", iprec, f);
19444 
19445     return;
19446 }
19447 
19448 
19449 
19450 
19451 /* @funcstatic acdHelpExpectIn ************************************************
19452 **
19453 ** Generates expected value description for an infile type.
19454 **
19455 ** @param [r] thys [const AcdPAcd] ACD object
19456 ** @param [r] table [AjBool] True if writing acdtable HTML table
19457 ** @param [w] str [AjPStr*] Help text (if any) generated
19458 ** @return [void]
19459 **
19460 ** @release 1.0.0
19461 ** @@
19462 ******************************************************************************/
19463 
acdHelpExpectIn(const AcdPAcd thys,AjBool table,AjPStr * str)19464 static void acdHelpExpectIn(const AcdPAcd thys, AjBool table, AjPStr* str)
19465 {
19466     if(!thys)
19467         return;
19468 
19469     if(table)
19470 	ajFmtPrintS(str, "<b>Required</b>");
19471 
19472     return;
19473 }
19474 
19475 
19476 
19477 
19478 /* @funcstatic acdHelpExpectData **********************************************
19479 **
19480 ** Generates expected value description for a datafile type.
19481 **
19482 ** @param [r] thys [const AcdPAcd] ACD object
19483 ** @param [r] table [AjBool] True if writing acdtable HTML table
19484 ** @param [w] str [AjPStr*] Help text (if any) generated
19485 ** @return [void]
19486 **
19487 ** @release 1.0.0
19488 ** @@
19489 ******************************************************************************/
19490 
acdHelpExpectData(const AcdPAcd thys,AjBool table,AjPStr * str)19491 static void acdHelpExpectData(const AcdPAcd thys, AjBool table, AjPStr* str)
19492 {
19493     if(!thys)
19494         return;
19495 
19496     if(table)
19497 	ajFmtPrintS(str, "<i>File in the data file path</i>");
19498 
19499     return;
19500 }
19501 
19502 
19503 
19504 
19505 /* @funcstatic acdHelpExpectCodon *********************************************
19506 **
19507 ** Generates expected value description for a codon usage table type.
19508 **
19509 ** @param [r] thys [const AcdPAcd] ACD object
19510 ** @param [r] table [AjBool] True if writing acdtable HTML table
19511 ** @param [w] str [AjPStr*] Help text (if any) generated
19512 ** @return [void]
19513 **
19514 ** @release 1.0.0
19515 ** @@
19516 ******************************************************************************/
19517 
acdHelpExpectCodon(const AcdPAcd thys,AjBool table,AjPStr * str)19518 static void acdHelpExpectCodon(const AcdPAcd thys, AjBool table, AjPStr* str)
19519 {
19520     AjPStr tmpstr = NULL;
19521 
19522     if(!thys)
19523         return;
19524 
19525     acdAttrResolve(thys, "name", &tmpstr);
19526     if(ajStrGetLen(tmpstr))
19527     {
19528 	if(table)
19529 	    ajStrAppendS(str, tmpstr);
19530 	else
19531 	    ajStrAppendS(str, tmpstr);
19532 	ajStrDel(&tmpstr);
19533 
19534 	return;
19535     }
19536 
19537     return;
19538 }
19539 
19540 
19541 
19542 
19543 /* @funcstatic acdHelpExpectDirlist *******************************************
19544 **
19545 ** Generates expected value description for a dirlist type.
19546 **
19547 ** @param [r] thys [const AcdPAcd] ACD object
19548 ** @param [r] table [AjBool] True if writing acdtable HTML table
19549 ** @param [w] str [AjPStr*] Help text (if any) generated
19550 ** @return [void]
19551 **
19552 ** @release 1.9.0
19553 ** @@
19554 ******************************************************************************/
19555 
acdHelpExpectDirlist(const AcdPAcd thys,AjBool table,AjPStr * str)19556 static void acdHelpExpectDirlist(const AcdPAcd thys, AjBool table, AjPStr* str)
19557 {
19558     AjPStr tmpstr = NULL;
19559 
19560     if(!thys)
19561         return;
19562 
19563     acdAttrResolve(thys, "default", &tmpstr);
19564 
19565     if(ajStrGetLen(tmpstr))
19566     {
19567 	if(table)
19568 	    ajStrAppendS(str, tmpstr);
19569 	else
19570 	    ajStrAppendS(str, tmpstr);
19571 	ajStrDel(&tmpstr);
19572 
19573 	return;
19574     }
19575 
19576     if(table)
19577 	ajStrAssignC(str, DEFDLIST);
19578     else
19579 	ajStrAssignC(str, DEFDLIST);
19580 
19581     return;
19582 }
19583 
19584 
19585 
19586 
19587 /* @funcstatic acdHelpExpectFilelist ******************************************
19588 **
19589 ** Generates expected value description for a filelist type.
19590 **
19591 ** @param [r] thys [const AcdPAcd] ACD object
19592 ** @param [r] table [AjBool] True if writing acdtable HTML table
19593 ** @param [w] str [AjPStr*] Help text (if any) generated
19594 ** @return [void]
19595 **
19596 ** @release 2.5.0
19597 ** @@
19598 ******************************************************************************/
19599 
acdHelpExpectFilelist(const AcdPAcd thys,AjBool table,AjPStr * str)19600 static void acdHelpExpectFilelist(const AcdPAcd thys, AjBool table,
19601 				  AjPStr* str)
19602 {
19603     if(!thys)
19604         return;
19605 
19606     if(table)
19607 	ajStrAppendC(str, "<i>comma-separated file list</i>");
19608 
19609     return;
19610 }
19611 
19612 
19613 
19614 
19615 /* @funcstatic acdHelpExpectMatrix ********************************************
19616 **
19617 ** Generates expected value description for a comparison matrix type.
19618 **
19619 ** @param [r] thys [const AcdPAcd] ACD object
19620 ** @param [r] table [AjBool] True if writing acdtable HTML table
19621 ** @param [w] str [AjPStr*] Help text (if any) generated
19622 ** @return [void]
19623 **
19624 ** @release 1.0.0
19625 ** @@
19626 ******************************************************************************/
19627 
acdHelpExpectMatrix(const AcdPAcd thys,AjBool table,AjPStr * str)19628 static void acdHelpExpectMatrix(const AcdPAcd thys, AjBool table, AjPStr* str)
19629 {
19630     if(!thys)
19631         return;
19632 
19633     if(table)
19634 	ajStrAppendC(str, "EBLOSUM62 for protein<br>EDNAFULL for DNA");
19635     else
19636 	ajStrAppendC(str, "EBLOSUM62 for protein, EDNAFULL for DNA");
19637 
19638     return;
19639 }
19640 
19641 
19642 
19643 
19644 /* @funcstatic acdHelpExpectFeatout *******************************************
19645 **
19646 ** Generates expected value description for a feature output type.
19647 **
19648 ** @param [r] thys [const AcdPAcd] ACD object
19649 ** @param [r] table [AjBool] True if writing acdtable HTML table
19650 ** @param [w] str [AjPStr*] Help text (if any) generated
19651 ** @return [void]
19652 **
19653 ** @release 1.0.0
19654 ** @@
19655 ******************************************************************************/
19656 
acdHelpExpectFeatout(const AcdPAcd thys,AjBool table,AjPStr * str)19657 static void acdHelpExpectFeatout(const AcdPAcd thys, AjBool table, AjPStr* str)
19658 {
19659     if(!thys)
19660         return;
19661 
19662     if(table)
19663 	ajStrAppendC(str, "<i>unknown.gff</i>");
19664     else
19665 	ajStrAppendC(str, "unknown.gff");
19666 
19667     return;
19668 }
19669 
19670 
19671 
19672 
19673 /* @funcstatic acdHelpExpectFeatures ******************************************
19674 **
19675 ** Generates expected value description for an input feature type.
19676 **
19677 ** @param [r] thys [const AcdPAcd] ACD object
19678 ** @param [r] table [AjBool] True if writing acdtable HTML table
19679 ** @param [w] str [AjPStr*] Help text (if any) generated
19680 ** @return [void]
19681 **
19682 ** @release 6.0.0
19683 ** @@
19684 ******************************************************************************/
19685 
acdHelpExpectFeatures(const AcdPAcd thys,AjBool table,AjPStr * str)19686 static void acdHelpExpectFeatures(const AcdPAcd thys, AjBool table, AjPStr* str)
19687 {
19688     if(!thys)
19689         return;
19690 
19691     if(table)
19692 	ajFmtPrintAppS(str, "<b>Required</b>");
19693 
19694     return;
19695 }
19696 
19697 
19698 
19699 
19700 /* @funcstatic acdHelpExpectRange *********************************************
19701 **
19702 ** Generates expected value description for a sequence range type.
19703 **
19704 ** @param [r] thys [const AcdPAcd] ACD object
19705 ** @param [r] table [AjBool] True if writing acdtable HTML table
19706 ** @param [w] str [AjPStr*] Help text (if any) generated
19707 ** @return [void]
19708 **
19709 ** @release 1.0.0
19710 ** @@
19711 ******************************************************************************/
19712 
acdHelpExpectRange(const AcdPAcd thys,AjBool table,AjPStr * str)19713 static void acdHelpExpectRange(const AcdPAcd thys, AjBool table, AjPStr* str)
19714 {
19715     if(!thys)
19716         return;
19717 
19718     if(table)
19719 	ajStrAppendC(str, "<i>full sequence</i>");
19720     else
19721 	ajStrAppendC(str, "(full sequence)");
19722 
19723     return;
19724 }
19725 
19726 
19727 
19728 
19729 /* @funcstatic acdHelpExpectGraph *********************************************
19730 **
19731 ** Generates expected value description for a graphics device type.
19732 **
19733 ** @param [r] thys [const AcdPAcd] ACD object
19734 ** @param [r] table [AjBool] True if writing acdtable HTML table
19735 ** @param [w] str [AjPStr*] Help text (if any) generated
19736 ** @return [void]
19737 **
19738 ** @release 1.0.0
19739 ** @@
19740 ******************************************************************************/
19741 
acdHelpExpectGraph(const AcdPAcd thys,AjBool table,AjPStr * str)19742 static void acdHelpExpectGraph(const AcdPAcd thys, AjBool table, AjPStr* str)
19743 {
19744 #ifndef WIN32
19745 #ifndef X_DISPLAY_MISSING /* X11 is available */
19746     const char* defdev = "x11";
19747 #else
19748 #ifdef PLD_png          /* if png/gd/zlib libraries available for png driver */
19749     const char* defdev = "png";
19750 #else
19751     const char* defdev = "ps";
19752 #endif
19753 #endif
19754 #else
19755     const char* defdev = "win3";
19756 #endif
19757 
19758     if(!thys)
19759         return;
19760 
19761     if(table)
19762 	ajFmtPrintAppS(str, "<i>EMBOSS_GRAPHICS</i> value, or %s", defdev);
19763     else
19764 	ajFmtPrintAppS(str, "$EMBOSS_GRAPHICS value, or %s", defdev);
19765     return;
19766 }
19767 
19768 
19769 
19770 
19771 /* @funcstatic acdHelpExpectRegexp ********************************************
19772 **
19773 ** Generates expected value description for a regular expression type.
19774 **
19775 ** @param [r] thys [const AcdPAcd] ACD object
19776 ** @param [r] table [AjBool] True if writing acdtable HTML table
19777 ** @param [w] str [AjPStr*] Help text (if any) generated
19778 ** @return [void]
19779 **
19780 ** @release 1.0.0
19781 ** @@
19782 ******************************************************************************/
19783 
acdHelpExpectRegexp(const AcdPAcd thys,AjBool table,AjPStr * str)19784 static void acdHelpExpectRegexp(const AcdPAcd thys, AjBool table, AjPStr* str)
19785 {
19786     ajint minlen;
19787 
19788     acdAttrValueStr(thys, "min", "1", &acdTmpStr);
19789 
19790     if(!ajStrToInt(acdTmpStr, &minlen))
19791 	minlen = 0;
19792 
19793     if(minlen > 0)
19794     {
19795 	if(table)
19796 	    ajStrAppendC(str, "<b>Required</b>");
19797     }
19798     else
19799     {
19800 	if(table)
19801 	    ajStrAppendC(str,
19802 			 "<i>An empty regular expression is accepted</i>");
19803     }
19804 
19805     return;
19806 }
19807 
19808 
19809 
19810 
19811 /* @funcstatic acdHelpExpectString ********************************************
19812 **
19813 ** Generates expected value description for a string type.
19814 **
19815 ** @param [r] thys [const AcdPAcd] ACD object
19816 ** @param [r] table [AjBool] True if writing acdtable HTML table
19817 ** @param [w] str [AjPStr*] Help text (if any) generated
19818 ** @return [void]
19819 **
19820 ** @release 1.0.0
19821 ** @@
19822 ******************************************************************************/
19823 
acdHelpExpectString(const AcdPAcd thys,AjBool table,AjPStr * str)19824 static void acdHelpExpectString(const AcdPAcd thys, AjBool table, AjPStr* str)
19825 {
19826     ajint minlen;
19827 
19828     acdAttrValueStr(thys, "min", "0", &acdTmpStr);
19829 
19830     if(!ajStrToInt(acdTmpStr, &minlen))
19831 	minlen = 0;
19832 
19833     if(minlen > 0)
19834     {
19835 	if(table)
19836 	    ajStrAppendC(str, "<b>Required</b>");
19837     }
19838     else
19839     {
19840 	if(table)
19841 	    ajStrAppendC(str, "&nbsp;");
19842     }
19843 
19844     return;
19845 }
19846 
19847 
19848 
19849 
19850 /* @funcstatic acdHelpExpect **************************************************
19851 **
19852 ** Generates expected value text for an ACD object code settings.
19853 **
19854 ** @param [r] thys [const AcdPAcd] ACD object
19855 ** @param [r] table [AjBool] True if writing acdtable HTML table
19856 ** @param [w] str [AjPStr*] Help text (if any) generated
19857 ** @return [void]
19858 **
19859 ** @release 1.0.0
19860 ** @@
19861 ******************************************************************************/
19862 
acdHelpExpect(const AcdPAcd thys,AjBool table,AjPStr * str)19863 static void acdHelpExpect(const AcdPAcd thys, AjBool table, AjPStr* str)
19864 {
19865     ajint i;
19866     AjPStr tmpstr = NULL;
19867 
19868     if(ajStrGetLen(*str))
19869 	return;
19870 
19871     if(!thys->AssocQuals && !acdDoGalaxy)
19872 	if(acdAttrValueStr(thys, "expected", "", str))
19873 	    return;
19874 
19875     if(acdAttrValueStr(thys, "default", "", str))
19876     {
19877         if(acdDoGalaxy)
19878         {
19879             tmpstr = ajStrNewS(*str);
19880 
19881             if(!acdVarSimpleResolve(tmpstr, str))
19882                 ajStrAssignS(str, tmpstr);
19883 
19884             ajStrDel(&tmpstr);
19885         }
19886 
19887         return;
19888     }
19889 
19890     /* special processing for sequences, outseq, outfile */
19891 
19892     for(i=0; acdValue[i].Name; i++)
19893 	if(ajCharMatchC(acdType[thys->Type].Name, acdValue[i].Name))
19894 	{
19895 	    /* Calling funclist acdValue() */
19896 	    if(acdValue[i].Expect)
19897 		(*acdValue[i].Expect)(thys, table, str);
19898 	    break;
19899 	}
19900 
19901 
19902     if(ajStrGetLen(*str))
19903 	return;
19904 
19905     ajStrAppendS(str, thys->DefStr[DEF_DEFAULT]);
19906 
19907     if(ajStrGetLen(*str))
19908 	return;
19909 
19910     if(table)
19911 	ajStrAppendC(str, "&nbsp;");
19912 
19913     return;
19914 }
19915 
19916 
19917 
19918 
19919 /* @funcstatic acdHelpText ****************************************************
19920 **
19921 ** Generates help text for an ACD object using the help, info, prompt
19922 ** and code settings.
19923 **
19924 ** @param [r] thys [const AcdPAcd] ACD object
19925 ** @param [w] str [AjPStr*] Help text (if any) generated
19926 ** @return [void]
19927 **
19928 ** @release 1.0.0
19929 ** @@
19930 ******************************************************************************/
19931 
acdHelpText(const AcdPAcd thys,AjPStr * str)19932 static void acdHelpText(const AcdPAcd thys, AjPStr* str)
19933 {
19934     AjPStr prompt;
19935     AjPStr info;
19936     AjPStr code;
19937     AjPStr help;
19938     static AjPStr msg = NULL;
19939 
19940     if(thys->DefStr)
19941     {
19942 	prompt = thys->DefStr[DEF_PROMPT];
19943 	info = thys->DefStr[DEF_INFO];
19944 	code = thys->DefStr[DEF_CODE];
19945 	help = thys->DefStr[DEF_HELP];
19946 
19947 	if(ajStrGetLen(help))
19948 	    ajStrAssignS(&msg, help);
19949 	else if(ajStrGetLen(code))
19950 	    acdCodeGet(code, &msg);
19951 	else if(ajStrGetLen(info))
19952 	    ajStrAssignS(&msg, info);
19953 	else if(ajStrGetLen(prompt))
19954 	    ajStrAssignS(&msg, prompt);
19955 	else if(acdType[thys->Type].HelpSet)
19956 	    (*acdType[thys->Type].HelpSet)(thys, &msg);
19957 	else
19958 	{
19959 	    if(!acdHelpCodeDef(thys, &msg))
19960 	    {
19961 		ajStrAssignResC(&msg, 512, "");
19962 		if(thys->Assoc)
19963 		    ajFmtPrintS(&msg, "%s value",
19964 				acdType[thys->Type].Name);
19965 		else
19966 		    ajFmtPrintS(&msg, "(no help text) %s value",
19967 				acdType[thys->Type].Name);
19968 	    }
19969 	}
19970 
19971 	acdVarResolve(&msg);
19972 	ajStrAppendS(str, msg);
19973 	ajStrDel(&msg);
19974     }
19975 
19976     return;
19977 }
19978 
19979 
19980 
19981 
19982 /* @funcstatic acdHelpShow ****************************************************
19983 **
19984 ** Prints the qualifier category and the help for any
19985 ** qualifiers in that category (or "(none)" if there are none).
19986 **
19987 ** @param [r] str [const AjPStr] Help text (if any)
19988 ** @param [r] title [const char*] Title line for this call
19989 ** @return [void]
19990 **
19991 ** @release 1.0.0
19992 ** @@
19993 ******************************************************************************/
19994 
acdHelpShow(const AjPStr str,const char * title)19995 static void acdHelpShow(const AjPStr str, const char* title)
19996 {
19997     if(acdDoTable)
19998 	return;
19999 
20000     if(!ajStrGetLen(str))
20001     {
20002 	ajUser("   %s: (none)", title);
20003 	return;
20004     }
20005 
20006     ajUser("   %s:", title);
20007     ajUserDumpS(str);
20008 
20009     return;
20010 }
20011 
20012 
20013 
20014 
20015 /* @funcstatic acdHelpTableShow ***********************************************
20016 **
20017 ** Prints the qualifier category and the help for any
20018 ** qualifiers in that category (or "(none)" if there are none).
20019 **
20020 ** @param [r] tablist [const AjPList] Help text (if any).
20021 ** @param [r] title [const char*] Title line for this call
20022 ** @return [void]
20023 **
20024 ** @release 1.0.0
20025 ** @@
20026 ******************************************************************************/
20027 
acdHelpTableShow(const AjPList tablist,const char * title)20028 static void acdHelpTableShow(const AjPList tablist, const char* title)
20029 {
20030     AcdPTableItem item;
20031     AjIList iter = NULL;
20032     ajuint nitem = 0;
20033 
20034     if(!acdDoTable)
20035 	return;
20036 
20037     if(!tablist)
20038     {
20039         ajUserDumpC("<tr bgcolor=\"#FFFFCC\">"); /* was #FFFFD0 */
20040         ajUserDumpC("<th align=\"left\">Qualifier</th>");
20041         ajUserDumpC("<th align=\"left\">Type</th>");
20042         ajUserDumpC("<th align=\"left\">Description</th>");
20043         ajUserDumpC("<th align=\"left\">Allowed values</th>");
20044         ajUserDumpC("<th align=\"left\">Default</th>");
20045         ajUserDumpC("</tr>\n");
20046         return;
20047     }
20048 
20049     /* new section */
20050 
20051     if(title){
20052         ajUserDumpC("<tr bgcolor=\"#FFFFCC\">"); /* was #FFFFD0 */
20053         ajUser("<th align=\"left\" colspan=5>%s</th>", title);
20054         ajUserDumpC("</tr>\n");
20055     }
20056 
20057     iter = ajListIterNewread(tablist);
20058     while((item = ajListIterGet(iter)))
20059     {
20060         ajUserDumpC("<tr bgcolor=\"#FFFFCC\">");
20061         if(ajStrGetLen(item->Title))
20062         {
20063             ajUser("<td align=\"left\" colspan=5>%S</td>", item->Title);
20064         }
20065         else
20066         {
20067             nitem++;
20068             acdTextTrim(&item->Help);
20069             ajUser("<td>%S</td>", item->Qual);
20070             ajUser("<td>%S</td>", item->Type);
20071             ajUser("<td>%S</td>", item->Help);
20072             ajUser("<td>%S</td>", item->Valid);
20073             ajUser("<td>%S</td>", item->Expect);
20074         }
20075         ajUserDumpC("</tr>\n");
20076     }
20077 
20078     if(!nitem || !ajListGetLength(tablist))
20079     {
20080         ajUserDumpC("<tr>");
20081         ajUserDumpC("<td colspan=5>(none)</td>");
20082         ajUserDumpC("</tr>\n");
20083     }
20084 
20085     ajListIterDel(&iter);
20086 
20087     return;
20088 }
20089 
20090 
20091 
20092 
20093 /* @funcstatic acdHelpXsdShow *************************************************
20094 **
20095 ** Prints the qualifier category and the help for any
20096 ** qualifiers in that category (or "(none)" if there are none).
20097 **
20098 ** @param [r] inlist [const AjPList] Help text (if any).
20099 ** @param [r] outlist [const AjPList] Help text (if any).
20100 ** @return [void]
20101 **
20102 ** @release 6.1.0
20103 ** @@
20104 ******************************************************************************/
20105 
acdHelpXsdShow(const AjPList inlist,const AjPList outlist)20106 static void acdHelpXsdShow(const AjPList inlist, const AjPList outlist)
20107 {
20108     AcdPXsdItem item;
20109     AjIList iter = NULL;
20110     AjPStrTok handle = NULL;
20111     AjPStr rest = NULL;
20112     AjPStr word = NULL;
20113     AjPStr tmpstr = NULL;
20114 
20115     if(!acdDoXsd)
20116 	return;
20117 
20118     ajUserDumpC("  <xs:import namespace=\"http://embossws.ebi/common\"");
20119     ajUserDumpC("    schemaLocation=\"sequence_input.xsd\" />");
20120     ajUserDumpC("  <xs:complexType name=\"appInputs\">");
20121     ajUserDumpC("    <xs:sequence>");
20122 
20123     if(ajListGetLength(inlist))
20124     {
20125         iter = ajListIterNewread(inlist);
20126         while((item = ajListIterGet(iter)))
20127         {
20128             acdTextTrim(&item->Annotation);
20129 
20130             /* Need specific strings for each datatype */
20131             /* add a block here as a temporary solution */
20132 
20133             /*
20134             ** Later create a functions for each datatype
20135             ** and a default function for general datatypes
20136             */
20137 
20138             /*
20139             ** Datatypes with more than one value - sequences see above, others
20140             ** may explicitly write their choices
20141             */
20142 #if 0
20143             /*
20144             //ajUser("      <xs:choice id=\"%S\" "
20145             //        "minOccurs=\"0\" maxOccurs=\"1\">",
20146             //        item->Qual);
20147             //ajUser("      </xs:choice>");
20148             */
20149 #endif
20150 
20151             /*
20152             ** sequences: 1 for required values - e.g. parameters - 0 for
20153             ** others
20154             */
20155 
20156             if (ajStrMatchC(item->Type, "long"))
20157             {
20158                 ajUser("      <xs:element name=\"%S\"",
20159                        item->Qual);
20160                 if(ajStrGetLen(item->Relation))
20161                 {
20162                     handle = ajStrTokenNewC(item->Relation, "|");
20163                     while(ajStrTokenNextParse(handle, &tmpstr))
20164                     {
20165                         ajStrExtractWord(tmpstr, &rest, &word);
20166                         ajUser("    sawsdl:modelReference="
20167                                "\"http://purl.org%S\"",
20168                                word);
20169                     }
20170                     ajStrTokenDel(&handle);
20171                 }
20172                 ajUser("        minOccurs=\"1\">");
20173                 ajUser("        <xs:annotation>");
20174                 ajUser("          <xs:documentation>");
20175                 ajUser("            %S", item->Annotation);
20176                 ajUser("          </xs:documentation>");
20177                 ajUser("        </xs:annotation>");
20178                 ajUser("        <xs:simpleType>");
20179                 ajUser("          <xs:restriction base=\"xs:long\">");
20180                 ajUser("            <xs:minInclusive value=\"1\">");
20181                 /* TODO actual min value */
20182                 ajUser("            </xs:minInclusive>");
20183                 ajUser("          </xs:restriction>");
20184                 ajUser("        </xs:simpleType>");
20185             }
20186             else if (ajStrMatchC(item->Type, "seqall")){
20187                 ajUser("      <xs:element name=\"%S\" type=\"emboss:"
20188                        "sequenceInput\"",
20189                         item->Qual);
20190                 if(ajStrGetLen(item->Relation))
20191                 {
20192                     handle = ajStrTokenNewC(item->Relation, "|");
20193                     while(ajStrTokenNextParse(handle, &tmpstr))
20194                     {
20195                         ajStrExtractWord(tmpstr, &rest, &word);
20196                         ajUser("    sawsdl:modelReference="
20197                                "\"http://purl.org%S\"",
20198                                word);
20199                     }
20200                     ajStrTokenDel(&handle);
20201                 }
20202                 ajUser("        minOccurs=\"1\">");
20203                 ajUser("        <xs:annotation>");
20204                 ajUser("          <xs:documentation>");
20205                 ajUser("            %S", item->Annotation);
20206                 ajUser("          </xs:documentation>");
20207                 ajUser("        </xs:annotation>");
20208             }
20209             else
20210             {
20211                 ajUser("      <xs:element name=\"%S\" type=\"xs:%S\"",
20212                        item->Qual, item->Type);
20213 
20214                 if(ajStrGetLen(item->Relation))
20215                 {
20216                     handle = ajStrTokenNewC(item->Relation, "|");
20217                     while(ajStrTokenNextParse(handle, &tmpstr))
20218                     {
20219                         ajStrExtractWord(tmpstr, &rest, &word);
20220                         ajUser("    sawsdl:modelReference="
20221                                "\"http://purl.org%S\"",
20222                                word);
20223                     }
20224                     ajStrTokenDel(&handle);
20225                 }
20226                 ajUser("        minOccurs=\"1\">");
20227                 ajUser("        <xs:annotation>");
20228                 ajUser("          <xs:documentation>");
20229                 ajUser("            %S", item->Annotation);
20230                 ajUser("          </xs:documentation>");
20231                 ajUser("        </xs:annotation>");
20232             }
20233             ajUser("      </xs:element>");
20234         }
20235     }
20236 
20237     ajListIterDel(&iter);
20238     ajUserDumpC("    </xs:sequence>");
20239     ajUserDumpC("  </xs:complexType>");
20240 
20241     ajUserDumpC("  <xs:complexType name=\"appResults\">");
20242     ajUserDumpC("    <xs:sequence>");
20243 
20244     if(ajListGetLength(outlist))
20245     {
20246         iter = ajListIterNewread(outlist);
20247 
20248         while((item = ajListIterGet(iter)))
20249         {
20250             if (ajStrMatchC(item->Type, "seqoutall"))
20251             {
20252                 ajUser("      <xs:element name=\"%S\" type=\"xs:string\"",
20253                        item->Qual, item->Type);
20254             }
20255             else
20256             {
20257                 ajUser("      <xs:element name=\"%S\" type=\"xs:%S\"",
20258                        item->Qual, item->Type);
20259             }
20260 
20261             if(ajStrGetLen(item->Relation))
20262             {
20263                 ajUser("relation: '%S'", item->Relation);
20264                 handle = ajStrTokenNewC(item->Relation, "|");
20265                 while(ajStrTokenNextParse(handle, &tmpstr))
20266                 {
20267                     ajStrExtractWord(tmpstr, &rest, &word);
20268                     ajUser("    sawsdl:modelReference=\"http://purl.org%S\"",
20269                            word);
20270                 }
20271                 ajStrTokenDel(&handle);
20272             }
20273             ajUser("        minOccurs=\"1\">");
20274             ajUser("        <xs:annotation>");
20275             ajUser("          <xs:documentation>");
20276             ajUser("            %S", item->Annotation);
20277             ajUser("          </xs:documentation>");
20278             ajUser("        </xs:annotation>");
20279             ajUser("    </xs:element>");
20280         }
20281     }
20282 
20283     ajUserDumpC("    </xs:sequence>");
20284     ajUserDumpC("  </xs:complexType>");
20285 
20286     ajListIterDel(&iter);
20287     ajStrDel(&tmpstr);
20288     ajStrDel(&rest);
20289     ajStrDel(&word);
20290 
20291     return;
20292 }
20293 
20294 
20295 
20296 
20297 /* @funcstatic acdHelpGalaxyShow **********************************************
20298 **
20299 ** Prints the qualifier category and the help for any
20300 ** qualifiers in that category (or "(none)" if there are none).
20301 **
20302 ** @param [r] inlist [const AjPList] Help text (if any).
20303 ** @param [r] outlist [const AjPList] Help text (if any).
20304 ** @return [void]
20305 **
20306 ** @release 6.3.0
20307 ** @@
20308 ******************************************************************************/
20309 
acdHelpGalaxyShow(const AjPList inlist,const AjPList outlist)20310 static void acdHelpGalaxyShow(const AjPList inlist, const AjPList outlist)
20311 {
20312     AcdPGalaxyItem item;
20313     AjIList iter = NULL;
20314 /*    AjPStrTok handle = NULL;*/
20315     AjPStr rest = NULL;
20316     AjPStr word = NULL;
20317     AjPStr tmpstr = NULL;
20318     AjPStr galaxyvar = NULL;
20319     ajuint ninputs = 0;
20320     ajuint noutputs = 0;
20321     ajuint i;
20322     AjPStrTok handle = NULL;
20323 
20324     AjPStr galaxyin = NULL;
20325     AjPStr galaxyout = NULL;
20326     AjPStr fmtname = NULL;
20327     AjPStr fmtdesc = NULL;
20328 
20329     const char* acdinputs[] = {
20330         "sequence", "seqall", "seqset", "seqsetall",
20331         "features",
20332         NULL
20333     };
20334 
20335     const char* acdoutputs[] = {
20336         "seqout", "seqoutall", "seqoutset",
20337         "align", "report", "featout",
20338         "graph", "xygraph",
20339         NULL
20340     };
20341 
20342     const char* acdoutformats[] = {
20343         "seqout", "seqoutall", "seqoutset",
20344         "align",
20345         "gff:GFF,pir:PIR,swiss:SWISS,excel:Excel (TAB Delimited)",
20346         "featout",
20347         "png:PNG", "png:PNG",
20348         NULL
20349     };
20350 
20351     const char* acdoutfmtqual[] = {
20352         "format", "format", "format",
20353         "aformat",
20354         "rformat",
20355         "fformat",
20356         "", "",
20357         NULL
20358     };
20359 
20360     if(!acdDoGalaxy)
20361 	return;
20362 
20363     if(!acdGalaxyCmdStr)
20364         acdGalaxyCmdStr = ajStrNewS(acdProgram);
20365 
20366     if(ajListGetLength(inlist))
20367     {
20368         iter = ajListIterNewread(inlist);
20369         while((item = ajListIterGet(iter)))
20370         {
20371             acdTextTrim(&item->Annotation);
20372 
20373 /*
20374             ajUser("AcdSGalaxyItem input");
20375             ajUser("        qual: '%S'", item->Qual);
20376             ajUser("        type: '%S'", item->Type);
20377             ajUser("  annotation: '%S'", item->Annotation);
20378             ajUser("    relation: '%S'", item->Relation);
20379             ajUser("       valid: '%S'", item->Valid);
20380             ajUser("      expect: '%S'", item->Expect);
20381             ajUser("    required: '%B'", item->Required);
20382             ajUser("    optional: '%B'", item->Optional);
20383 */
20384 
20385 /*
20386 ** test Type
20387 ** use to select format, input1/output1 name, type
20388 ** need for output format (note: this is an input!)
20389 ** set size=4 for int or float
20390 ** type text for string, integer for int, float for float
20391 */
20392             for(i=0; acdinputs[i]; i++)
20393                 if(ajStrMatchC(item->Type, acdinputs[i])) break;
20394 
20395             if(acdinputs[i])
20396             {
20397                 ajFmtPrintAppS(&galaxyin,
20398                                "    <param format=\"data\" name=\"input%u\" "
20399                                "type=\"data\">\n",
20400                                ++ninputs);
20401                 ajFmtPrintAppS(&galaxyin,
20402                                "      <label>On query</label>\n");
20403                 ajFmtPrintAppS(&galaxyin,
20404                                "    </param>\n");
20405                 ajFmtPrintAppS(&acdGalaxyCmdStr,
20406                                " -%S $input%u",
20407                                item->Qual, ninputs);
20408             }
20409             else if(ajStrMatchC(item->Expect, "<b>Required</b>"))
20410             {
20411                 ajFmtPrintAppS(&galaxyin,
20412                                "    <param format=\"data\" name=\"%S\" "
20413                                "type=\"data\">\n",
20414                                item->Qual);
20415                 ajFmtPrintAppS(&galaxyin,
20416                                "      <label>On query</label>\n");
20417                 ajFmtPrintAppS(&galaxyin,
20418                                "    </param>\n");
20419                 ajFmtPrintAppS(&acdGalaxyCmdStr,
20420                                " -%S $%S",
20421                                item->Qual, item->Qual);
20422             }
20423             else
20424             {
20425                 if(ajStrMatchC(item->Type, "string"))
20426                     ajFmtPrintAppS(&galaxyin,
20427                                    "    <param name=\"%S\" size=\"50\" "
20428                                    "type=\"text\" value=\"%S\">\n",
20429                                    item->Qual, item->Expect);
20430                 else if(ajStrMatchC(item->Type, "boolean") ||
20431                         ajStrMatchC(item->Type, "toggle"))
20432                 {
20433                      ajFmtPrintAppS(&galaxyin,
20434                                        "    <param name=\"%S\" "
20435                                        "type=\"boolean\" value=\"%S\">\n",
20436                                        item->Qual, item->Expect);
20437                 }
20438                 else if(ajStrMatchC(item->Type, "float") ||
20439                         ajStrMatchC(item->Type, "double"))
20440                     ajFmtPrintAppS(&galaxyin,
20441                                    "    <param name=\"%S\" "
20442                                    "type=\"float\" value=\"%S\">\n",
20443                                    item->Qual, item->Expect);
20444                 else if(ajStrMatchC(item->Type, "integer") ||
20445                         ajStrMatchC(item->Type, "long"))
20446                     ajFmtPrintAppS(&galaxyin,
20447                                    "    <param name=\"%S\" "
20448                                    "type=\"integer\" value=\"%S\">\n",
20449                                    item->Qual, item->Expect);
20450                 else if(ajStrMatchC(item->Type, "select") ||
20451                         ajStrMatchC(item->Type, "list"))
20452                     ajFmtPrintAppS(&galaxyin,
20453                                    "    <param name=\"%S\" "
20454                                    "type=\"select\" value=\"%S\">\n",
20455                                    item->Qual, item->Expect);
20456                 else
20457                     ajFmtPrintAppS(&galaxyin,
20458                                    "    <param name=\"%S\" size=\"50\" "
20459                                    "type=\"text\" value=\"%S\">\n",
20460                                    item->Qual, item->Expect);
20461 
20462                 ajFmtPrintAppS(&galaxyin,
20463                                "      <label>%S</label>\n",
20464                                item->Prompt);
20465                 ajFmtPrintAppS(&galaxyin,
20466                                "    </param>\n");
20467 
20468                 ajStrDel(&galaxyvar);
20469 
20470                 if(!ajStrGetLen(galaxyvar))
20471                     galaxyvar = item->Qual;
20472 
20473                 ajFmtPrintAppS(&acdGalaxyCmdStr,
20474                                " -%S $%S",
20475                                item->Qual, galaxyvar);
20476             }
20477 
20478 
20479 
20480             /* Need specific strings for each datatype */
20481             /* add a block here as a temporary solution */
20482 
20483             /*
20484             ** sequences: 1 for required values - e.g. parameters - 0 for
20485             ** others
20486             */
20487 
20488             /*
20489             if (ajStrMatchC(item->Type, "long"))
20490             {
20491                 ajUserDumpC("long");
20492             }
20493             else if (ajStrMatchC(item->Type, "seqall")){
20494                 ajUserDumpC("seqall");
20495             }
20496             else
20497             {
20498                 ajUserDumpC("other");
20499             }
20500             ajUserDumpC("...initemdone");
20501             */
20502         }
20503     }
20504 
20505     ajListIterDel(&iter);
20506     if(ajListGetLength(outlist))
20507     {
20508         iter = ajListIterNewread(outlist);
20509 
20510         while((item = ajListIterGet(iter)))
20511         {
20512             for(i=0; acdoutputs[i]; i++)
20513                 if(ajStrMatchC(item->Type, acdoutputs[i])) break;
20514 
20515             if(acdoutputs[i])
20516             {
20517                 if(ajCharMatchC(acdoutputs[i], "graph") ||
20518                    ajCharMatchC(acdoutputs[i], "xygraph"))
20519                 {
20520                     ajFmtPrintAppS(&acdGalaxyCmdStr,
20521                                    " -%S png -goutfile $goutfile",
20522                                    item->Qual);
20523                     ajFmtPrintAppS(&galaxyout,
20524                                "    <data format=\"%s\" "
20525                                    "name=\"goutfile%u\"/>\n",
20526                                acdoutformats[i], acdProgram, ++noutputs);
20527                 }
20528                 else if(ajCharMatchC(acdoutputs[i], "report"))
20529                 {
20530                     ajFmtPrintAppS(&galaxyout,
20531                                "    <data format=\"%S\" name=\"outfile%u\"/>\n",
20532                                acdProgram, ++noutputs);
20533                     if(ajCharMatchC(acdoutputs[i], "report"))
20534                     {
20535                         ajFmtPrintAppS(&galaxyin,
20536                                        "    <param name=\"out_format%u\" "
20537                                        "type=\"select\">\n",
20538                                        noutputs);
20539                         ajFmtPrintAppS(&galaxyin,
20540                                        "      <label>Output format</label>\n");
20541 
20542 
20543                         ajStrTokenAssigncharC(&handle, acdoutformats[i], ":,");
20544                         while(ajStrTokenNextParse(handle, &fmtname))
20545                         {
20546                             ajStrTokenNextParse(handle, &fmtdesc);
20547                             if(ajStrMatchC(fmtname, "gff2"))
20548                                 ajFmtPrintAppS(&galaxyin,
20549                                                "      <option value=\"%S\" "
20550                                                "selected=\"true\">%S</option>"
20551                                                "\n",
20552                                            fmtname, fmtdesc);
20553                             else
20554                                 ajFmtPrintAppS(&galaxyin,
20555                                                "      <option value=\"%S\">"
20556                                                "%S</option>\n",
20557                                                fmtname, fmtdesc);
20558                         }
20559 
20560                         ajFmtPrintAppS(&galaxyin,
20561                                        "    </param>");
20562                         ajFmtPrintAppS(&acdGalaxyCmdStr,
20563                                        " -rformat $out_format%u",
20564                                        noutputs);
20565                     }
20566                 }
20567                 else
20568                 {
20569                     ajFmtPrintAppS(&galaxyout,
20570                                "    <data format=\"%S\" name=\"outfile%u\"/>\n",
20571                                acdProgram, ++noutputs);
20572                     if(ajCharMatchC(acdoutputs[i], "report"))
20573                     {
20574                         ajFmtPrintAppS(&galaxyin,
20575                                        "    <param name=\"out_format%u\" "
20576                                        "type=\"select\">\n",
20577                                        noutputs);
20578                         ajFmtPrintAppS(&galaxyin,
20579                                        "      <label>Output format</label>\n");
20580 
20581 
20582                         ajStrTokenAssigncharC(&handle, acdoutformats[i], ":,");
20583                         while(ajStrTokenNextParse(handle, &fmtname))
20584                         {
20585                             ajStrTokenNextParse(handle, &fmtdesc);
20586                             if(ajStrMatchS(fmtname, item->Expect))
20587                                 ajFmtPrintAppS(&galaxyin,
20588                                                "      <option value=\"%s\" "
20589                                                "selected=\"true\">%s</option>"
20590                                                "\n",
20591                                            fmtname, fmtdesc);
20592                             else
20593                                 ajFmtPrintAppS(&galaxyin,
20594                                                "      <option value=\"%s\">"
20595                                                "%s</option>\n",
20596                                                fmtname, fmtdesc);
20597                         }
20598 
20599                         ajFmtPrintAppS(&galaxyin,
20600                                        "    </param>");
20601                         ajFmtPrintAppS(&acdGalaxyCmdStr, " -%s $out_format%u",
20602                                        acdoutfmtqual[i], noutputs);
20603                     }
20604                 }
20605             }
20606             else
20607             {
20608                 /* use type=file or type=data (which?) */
20609                 ajFmtPrintAppS(&galaxyout,
20610                                "    <param format=\"%S\" name=\"%S1\" "
20611                                "type=\"file\">\n"
20612                                "      <label>%S</label>\n"
20613                                "    </param>\n",
20614                                item->Qual, item->Qual,
20615                                item->Annotation);
20616             }
20617 
20618 /*
20619             ajUser("AcdSGalaxyItem output\n");
20620             ajUser("        qual: '%S'", item->Qual);
20621             ajUser("        type: '%S'", item->Type);
20622             ajUser("  annotation: '%S'", item->Annotation);
20623             ajUser("    relation: '%S'", item->Relation);
20624             ajUser("       valid: '%S'", item->Valid);
20625             ajUser("      expect: '%S'", item->Expect);
20626             ajUser("    required: '%B'", item->Required);
20627             ajUser("    optional: '%B'", item->Optional);
20628 */
20629 
20630 /*
20631             if (ajStrMatchC(item->Type, "seqoutall"))
20632             {
20633                 ajUserDumpC("seqoutall");
20634             }
20635             else
20636             {
20637                  ajUserDumpC("other");
20638             }
20639 
20640             if(ajStrGetLen(item->Relation))
20641             {
20642                 handle = ajStrTokenNewC(item->Relation, "|");
20643                 while(ajStrTokenNextParse(handle, &tmpstr))
20644                 {
20645                     ajStrExtractWord(tmpstr, &rest, &word);
20646                     ajUserDumpC("");
20647                 }
20648                 ajStrTokenDel(&handle);
20649             }
20650             ajUserDumpC("...outitemdone");
20651 */
20652         }
20653     }
20654 
20655 
20656     ajUser("  <command>%S -auto</command>", acdGalaxyCmdStr);
20657 
20658     ajUserDumpC("  <inputs>");
20659     ajUserDumpS(galaxyin);
20660     ajUserDumpC("  </inputs>");
20661 
20662     ajUserDumpC("  <outputs>");
20663     ajUserDumpS(galaxyout);
20664     ajUserDumpC("  </outputs>");
20665 
20666     /*
20667     ajUser("  <tests>");
20668     */
20669     /* for each QA test: */
20670 
20671     /*ajUser("    <test>\n"
20672            "      <param name=\"input1\" value=\"2.fasta\"/>\n"
20673            "      <param name=\"minlen\" value=\"6\"/>\n"
20674            "      <param name=\"out_format1\" value=\"excel\"/>\n"
20675            "      <output name=\"out_file1\" "
20676            "file=\"emboss_antigenic_out.tabular\"/>\n"
20677            "    </test>"
20678            );
20679     */
20680 
20681     /* end of QA tests */
20682 
20683 /*
20684   ajUser("  </tests>\n");
20685 */
20686 
20687     ajUser("  <code file=\"emboss_format_corrector.py\" />\n"
20688            "  <help>\n"
20689            "\n"
20690            "    You can view the original documentation here_.\n"
20691            "\n"
20692            "    .. _here: http://emboss.sourceforge.net/apps/release/6.4/"
20693            "emboss/apps/%S.html\n"
20694            "  </help>\n"
20695            "</tool>",
20696            acdProgram);
20697 
20698     ajListIterDel(&iter);
20699 
20700     ajStrDel(&tmpstr);
20701     ajStrDel(&rest);
20702     ajStrDel(&word);
20703     ajStrDel(&fmtname);
20704     ajStrDel(&fmtdesc);
20705 
20706     ajStrTokenDel(&handle);
20707 
20708     return;
20709 }
20710 
20711 
20712 
20713 
20714 /* @funcstatic acdHelpAssocTable **********************************************
20715 **
20716 ** Appends an associated qualifier and its help text to the table list.
20717 **
20718 ** @param [r] thys [const AcdPAcd]  ACD object
20719 ** @param [u] tablist [AjPList] Help text list being built
20720 ** @return [void]
20721 **
20722 ** @release 1.0.0
20723 ** @@
20724 ******************************************************************************/
20725 
acdHelpAssocTable(const AcdPAcd thys,AjPList tablist)20726 static void acdHelpAssocTable(const AcdPAcd thys, AjPList tablist)
20727 {
20728     AcdPTableItem item;
20729 
20730     AcdPQual quals;
20731     ajint i;
20732     AcdPAcd pa;
20733 
20734    if(!acdDoTable)
20735 	return;
20736 
20737     acdLog("++ acdHelpAssocTable %S\n", thys->Name);
20738 
20739     if(thys->Level == ACD_APPL)
20740     {
20741         quals = acdQualAppl;
20742     }
20743     else
20744     {
20745         AJNEW0(item);
20746         ajFmtPrintS(&item->Title, "\"-%S\" associated %s qualifiers\n",
20747 		    thys->Name,acdType[thys->Type].Name);
20748         ajListPushAppend(tablist, item);
20749 	quals = acdType[thys->Type].Quals;
20750     }
20751 
20752     acdLog("++ type %d quals %x\n", thys->Type, quals);
20753 
20754     if(quals)
20755     {
20756         i=0;
20757         for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next)
20758 	{
20759             acdLog("++ assoc[%d].Name %s\n", i, quals[i].Name);
20760             AJNEW0(item);
20761 
20762             if(thys->PNum)
20763                 ajFmtPrintS(&item->Qual, " -%s%d<br>-%s_%S",
20764                             quals[i].Name, pa->PNum,
20765                             quals[i].Name, thys->Name);
20766             else
20767                 ajFmtPrintS(&item->Qual, " -%s", quals[i].Name);
20768 
20769             ajStrAssignC(&item->Type, quals[i].Type);
20770             ajStrAssignC(&item->Help, quals[i].Help);
20771             acdHelpValid(pa, ajTrue, &item->Valid);
20772             acdHelpExpect(pa, ajTrue, &item->Expect);
20773             ajListPushAppend(tablist, item);
20774             i++;
20775         }
20776     }
20777 
20778     return;
20779 }
20780 
20781 
20782 
20783 
20784 /* @funcstatic acdHelpTable ***************************************************
20785 **
20786 ** Appends a qualifier and its help text to the table list.
20787 **
20788 ** @param [r] thys [const AcdPAcd]  ACD object
20789 ** @param [u] tablist [AjPList] Help text list being built
20790 ** @return [void]
20791 **
20792 ** @release 1.0.0
20793 ** @@
20794 ******************************************************************************/
20795 
acdHelpTable(const AcdPAcd thys,AjPList tablist)20796 static void acdHelpTable(const AcdPAcd thys, AjPList tablist)
20797 {
20798     AcdPTableItem item;
20799 
20800     static AjPStr nostr   = NULL;
20801     static AjPStr nullstr = NULL;
20802     static AjPStr type    = NULL;
20803     AjBool boolval;
20804 
20805     AjPStr defstr;
20806 
20807     if(!acdDoTable)
20808 	return;
20809 
20810     AJNEW0(item);
20811 
20812     if(!nullstr)
20813 	nullstr = ajStrNew();
20814 
20815     if(thys->DefStr)
20816 	defstr = thys->OrigStr;
20817     else
20818 	defstr = nullstr;
20819 
20820     ajStrAssignClear(&nostr);
20821     if(acdIsQtype(thys) &&
20822        (ajCharMatchC("boolean", acdType[thys->Type].Name) ||
20823 	ajCharMatchC("toggle", acdType[thys->Type].Name) ))
20824     {
20825 	if(ajStrToBool(defstr, &boolval))
20826 	{
20827 	    if(boolval)
20828 		ajStrAssignC(&nostr, "[no]");
20829 
20830 	    ajFmtPrintS(&item->Expect, "%B", boolval);
20831 	}
20832 	else
20833 	    if(!ajStrGetLen(defstr))
20834 		ajFmtPrintS(&item->Expect, "%B", ajFalse);
20835 
20836 	defstr = nullstr;
20837     }
20838 
20839     if(thys->Level == ACD_PARAM)
20840 	ajFmtPrintS(&item->Qual, "[-%S%S]<br>(Parameter %d)",
20841 		    nostr, thys->Name, thys->PNum);
20842     else
20843 	ajFmtPrintS(&item->Qual, "-%S%S", nostr, thys->Name);
20844 
20845     ajStrAssignC(&type, acdType[thys->Type].Name);
20846 
20847     acdHelpExpect(thys, ajTrue, &item->Expect);
20848 
20849     /*
20850      **  warning - don't try acdVarResolve here because we have not yet
20851      **  read in the data and things like calculated attributes do not exist
20852      */
20853 
20854     ajStrAssignC(&item->Type, acdType[thys->Type].Name);
20855     acdHelpValid(thys, ajTrue, &item->Valid);
20856     acdHelpText(thys, &item->Help);
20857 
20858     ajListPushAppend(tablist, item);
20859 
20860     return;
20861 }
20862 
20863 
20864 
20865 
20866 /* @funcstatic acdHelpXsd *****************************************************
20867 **
20868 ** Appends a qualifier and its help text to the XSD list.
20869 **
20870 ** @param [r] thys [const AcdPAcd]  ACD object
20871 ** @param [u] tablist [AjPList] Xsd list being built
20872 ** @return [void]
20873 **
20874 ** @release 6.1.0
20875 ** @@
20876 ******************************************************************************/
20877 
acdHelpXsd(const AcdPAcd thys,AjPList tablist)20878 static void acdHelpXsd(const AcdPAcd thys, AjPList tablist)
20879 {
20880     AcdPXsdItem item;
20881 
20882     static AjPStr nostr   = NULL;
20883     static AjPStr nullstr = NULL;
20884     AjBool boolval;
20885     AjBool tmpBool;
20886     AjPStr helpStr = NULL;
20887 
20888     AjPStr defstr = NULL;
20889     AjPStr* def = NULL;
20890 
20891     if(!acdDoXsd)
20892 	return;
20893 
20894     /* skip associated qualifiers:
20895     ** handled separatedly in XSD for types that use them
20896     ** Note: this also excludes application associated general qualifiers
20897     **       -auto -verbose -filter and so on
20898     */
20899 
20900     if(thys->Assoc)
20901         return;
20902 
20903     AJNEW0(item);
20904     if(!nullstr)
20905 	nullstr = ajStrNew();
20906 
20907     if(thys->DefStr)
20908 	defstr = thys->OrigStr;
20909     else
20910 	defstr = nullstr;
20911 
20912     ajStrAssignClear(&nostr);
20913     if(acdIsQtype(thys))
20914     {
20915         if((ajCharMatchC("boolean", acdType[thys->Type].Name) ||
20916             ajCharMatchC("toggle", acdType[thys->Type].Name) ))
20917         {
20918             if(ajStrToBool(defstr, &boolval))
20919             {
20920                 if(boolval)
20921                     ajStrAssignC(&nostr, "no");
20922 
20923                 ajFmtPrintS(&item->Expect, "%B", boolval);
20924             }
20925             else
20926                 if(!ajStrGetLen(defstr))
20927                     ajFmtPrintS(&item->Expect, "%B", ajFalse);
20928         }
20929 
20930 	def = thys->DefStr;
20931 
20932 	if(def && ajStrGetLen(def[DEF_ADDITIONAL]))
20933 	{
20934 	    if(acdHelpVarResolve(&helpStr, def[DEF_ADDITIONAL]))
20935 	    {
20936 		if(!ajStrToBool(helpStr, &tmpBool))
20937 		    acdErrorAcd(thys, "Bad additional flag %S\n",
20938 				def[DEF_ADDITIONAL]);
20939 	    }
20940 	    else
20941 	    {
20942 		tmpBool = ajTrue;
20943 	    }
20944 
20945 	    if(tmpBool)
20946 		item->Optional = ajTrue;
20947 	}
20948 
20949 	if(def && ajStrGetLen(def[DEF_STANDARD]))
20950 	{
20951 	    if(acdHelpVarResolve(&helpStr, def[DEF_STANDARD]))
20952 	    {
20953 		if(!ajStrToBool( helpStr, &tmpBool))
20954 		    acdErrorAcd(thys, "Bad standard flag %S\n",
20955 				def[DEF_STANDARD]);
20956 	    }
20957 	    else
20958 		tmpBool = ajTrue;
20959 
20960 	    if(tmpBool)
20961 		item->Required = ajTrue;
20962 	}
20963 
20964     }
20965 
20966     ajStrAssignC(&item->Type, acdType[thys->Type].Name);
20967     ajStrAssignS(&item->Qual, thys->Name);
20968     acdHelpExpect(thys, ajTrue, &item->Expect);
20969 
20970     /*
20971      **  warning - don't try acdVarResolve here because we have not yet
20972      **  read in the data and things like calculated attributes do not exist
20973      */
20974 
20975     acdHelpValid(thys, ajTrue, &item->Valid);
20976     acdHelpText(thys, &item->Annotation);
20977     acdAttrToStr(thys, "relation", "", &item->Relation);
20978     ajListPushAppend(tablist, item);
20979     ajStrDel (&helpStr);
20980 
20981     return;
20982 }
20983 
20984 
20985 
20986 
20987 /* @funcstatic acdHelpGalaxy **************************************************
20988 **
20989 ** Appends a qualifier and its help text to the Galaxy list.
20990 **
20991 ** @param [u] thys [AcdPAcd]  ACD object, may have prompt set
20992 ** @param [u] tablist [AjPList] Galaxy list being built
20993 ** @return [void]
20994 **
20995 ** @release 6.3.0
20996 ** @@
20997 ******************************************************************************/
20998 
acdHelpGalaxy(AcdPAcd thys,AjPList tablist)20999 static void acdHelpGalaxy(AcdPAcd thys, AjPList tablist)
21000 {
21001     AcdPGalaxyItem item;
21002 
21003     static AjPStr nostr   = NULL;
21004     static AjPStr nullstr = NULL;
21005     AjBool boolval;
21006     AjBool tmpBool;
21007     AjPStr helpStr = NULL;
21008     const AjPStr prompt = NULL;
21009     AjPStr defstr = NULL;
21010     AjPStr* def = NULL;
21011     ajuint itype;
21012     AjPStr galaxyExpectStr = NULL;
21013 
21014     ajint ipos;
21015     ajint cpos;
21016     ajint bpos;
21017     ajint qpos;
21018 
21019     if(!acdDoGalaxy)
21020 	return;
21021 
21022     /* associated qualifiers:*/
21023        if(thys->Assoc)
21024            return;
21025 
21026     AJNEW0(item);
21027     if(!nullstr)
21028 	nullstr = ajStrNew();
21029 
21030     if(thys->DefStr)
21031 	defstr = thys->OrigStr;
21032     else
21033 	defstr = nullstr;
21034 
21035     ajStrAssignClear(&nostr);
21036     if(acdIsQtype(thys))
21037     {
21038         if((ajCharMatchC("boolean", acdType[thys->Type].Name) ||
21039             ajCharMatchC("toggle", acdType[thys->Type].Name) ))
21040         {
21041             if(ajStrToBool(defstr, &boolval))
21042             {
21043                 if(boolval)
21044                     ajStrAssignC(&item->Expect, "Yes");
21045                 else
21046                     ajStrAssignC(&item->Expect, "No");
21047             }
21048             else
21049                 if(!ajStrGetLen(defstr))
21050                     ajFmtPrintS(&item->Expect, "%B", ajFalse);
21051         }
21052 
21053 	def = thys->DefStr;
21054 
21055 	if(def && ajStrGetLen(def[DEF_ADDITIONAL]))
21056 	{
21057 	    if(acdHelpVarResolve(&helpStr, def[DEF_ADDITIONAL]))
21058 	    {
21059 		if(!ajStrToBool(helpStr, &tmpBool))
21060 		    acdErrorAcd(thys, "Bad additional flag %S\n",
21061 				def[DEF_ADDITIONAL]);
21062 	    }
21063 	    else
21064 	    {
21065 		tmpBool = ajTrue;
21066 	    }
21067 
21068 	    if(tmpBool)
21069 		item->Optional = ajTrue;
21070 	}
21071 
21072 	if(def && ajStrGetLen(def[DEF_STANDARD]))
21073 	{
21074 	    if(acdHelpVarResolve(&helpStr, def[DEF_STANDARD]))
21075 	    {
21076 		if(!ajStrToBool( helpStr, &tmpBool))
21077 		    acdErrorAcd(thys, "Bad standard flag %S\n",
21078 				def[DEF_STANDARD]);
21079 	    }
21080 	    else
21081 		tmpBool = ajTrue;
21082 
21083 	    if(tmpBool)
21084 		item->Required = ajTrue;
21085 	}
21086 
21087     }
21088 
21089     ajStrAssignC(&item->Type, acdType[thys->Type].Name);
21090     ajStrAssignS(&item->Qual, thys->Name);
21091     acdHelpExpect(thys, ajTrue, &item->Expect);
21092 
21093     ipos = (ajint) ajStrFindC(item->Expect, " for protein<br>");
21094 
21095     if(ipos >= 0)               /* matrix expected value */
21096     {
21097         ajStrExchangeCC(&item->Expect, " for DNA", "");
21098         if(acdDoGalaxyProt)
21099         {
21100             ajStrAssignSubS(&galaxyExpectStr, item->Expect, 0, ipos-1);
21101         }
21102         else if(acdDoGalaxyNuc)
21103         {
21104             ajStrAssignSubS(&galaxyExpectStr, item->Expect, ipos+16, -1);
21105         }
21106         else
21107         {
21108             ajStrAssignSubS(&galaxyExpectStr, item->Expect, ipos+16, -1);
21109         }
21110         ajStrTrimWhite(&galaxyExpectStr);
21111         ajStrAssignS(&item->Expect, galaxyExpectStr);
21112     }
21113 
21114     ajStrExchangeCC(&item->Expect, "&nbsp;", "");
21115     ajStrExchangeCC(&item->Expect, " for any sequence type", "");
21116     ajStrExchangeCC(&item->Expect, " for any sequence", "");
21117     ajStrExchangeCC(&item->Expect, "<i>full sequence</i>", "");
21118 
21119     if(ajStrFindC(item->Expect, ".end)") >= 0)
21120         ajStrAssignC(&item->Expect, "-1");
21121 
21122     if(ajStrFindC(item->Expect, ".begin)") >= 0)
21123         ajStrAssignC(&item->Expect, "00");
21124 
21125     if(ajStrFindC(item->Expect, "@($(acdprotein)") >= 0)
21126     {
21127         qpos = (ajint) ajStrFindAnyK(item->Expect, '?');
21128         cpos = (ajint) ajStrFindAnyK(item->Expect, ':');
21129         bpos = (ajint) ajStrFindlastK(item->Expect, ')');
21130         if(acdDoGalaxyProt)
21131         {
21132             ajStrAssignSubS(&galaxyExpectStr, item->Expect, qpos+1, cpos-1);
21133         }
21134         else if(acdDoGalaxyNuc)
21135         {
21136             ajStrAssignSubS(&galaxyExpectStr, item->Expect, cpos+1, bpos-1);
21137         }
21138         else
21139         {
21140             ajStrAssignSubS(&galaxyExpectStr, item->Expect, cpos+1, bpos-1);
21141         }
21142         ajStrTrimWhite(&galaxyExpectStr);
21143         ajStrAssignS(&item->Expect, galaxyExpectStr);
21144     }
21145     else if(ajStrFindC(item->Expect, "@(!$(acdprotein)") >= 0)
21146     {
21147         qpos = (ajint) ajStrFindAnyK(item->Expect, '?');
21148         cpos = (ajint) ajStrFindAnyK(item->Expect, ':');
21149         bpos = (ajint) ajStrFindlastK(item->Expect, ')');
21150         if(acdDoGalaxyProt)
21151         {
21152             ajStrAssignSubS(&galaxyExpectStr, item->Expect, cpos+1, bpos-1);
21153         }
21154         else if(acdDoGalaxyNuc)
21155         {
21156             ajStrAssignSubS(&galaxyExpectStr, item->Expect, qpos+1, cpos-1);
21157         }
21158         else
21159         {
21160             ajStrAssignSubS(&galaxyExpectStr, item->Expect, qpos+1, cpos-1);
21161         }
21162         ajStrTrimWhite(&galaxyExpectStr);
21163         ajStrAssignS(&item->Expect, galaxyExpectStr);
21164     }
21165 
21166     prompt = acdAttrValue(thys, "code");
21167     if(!ajStrGetLen(prompt))
21168         prompt = acdAttrValue(thys, "prompt");
21169     if(!ajStrGetLen(prompt))
21170         prompt = acdAttrValue(thys, "information");
21171     if(!ajStrGetLen(prompt))
21172     {
21173         for (itype=0; acdType[itype].Name; itype++)
21174             if (ajStrMatchC(item->Type, acdType[itype].Name))
21175                 break;
21176         if(acdType[itype].Prompt)
21177             (*acdType[itype].Prompt)(thys);
21178         prompt = thys->StdPrompt;
21179     }
21180     if(!ajStrGetLen(prompt))
21181         prompt = acdAttrValue(thys, "help");
21182 
21183     ajStrAssignS(&item->Prompt, prompt);
21184 
21185     /*
21186      **  warning - don't try acdVarResolve here because we have not yet
21187      **  read in the data and things like calculated attributes do not exist
21188      */
21189 
21190     acdHelpValid(thys, ajTrue, &item->Valid);
21191     acdHelpText(thys, &item->Annotation);
21192     acdAttrToStr(thys, "relation", "", &item->Relation);
21193     ajListPushAppend(tablist, item);
21194     ajStrDel (&helpStr);
21195 
21196     return;
21197 }
21198 
21199 
21200 
21201 
21202 /* @funcstatic acdListReport **************************************************
21203 **
21204 ** Reports the current status of the ACD internal structures, converting
21205 ** values to a printable form as appropriate.
21206 **
21207 ** @param [r] title [const char*] Title line for this call
21208 ** @return [void]
21209 **
21210 ** @release 1.0.0
21211 ** @@
21212 ******************************************************************************/
21213 
acdListReport(const char * title)21214 static void acdListReport(const char* title)
21215 {
21216     AcdPAcd pa;
21217 
21218     ajint i = 0;
21219     ajint j = 0;
21220     char underline[256];
21221 
21222 
21223     if(!acdDoLog)
21224 	return;
21225 
21226     j = strlen(title);
21227     if(j > 255)
21228 	j = 255;
21229 
21230     memset(underline, '=', j);
21231     underline[j] = '\0';
21232 
21233     acdLog("\n");
21234     acdLog("%s\n", title);
21235     acdLog("%s\n", underline);
21236     acdLog("\n");
21237 
21238     for(pa=acdList; pa; pa=pa->Next)
21239     {
21240 	acdLog("ACD %d\n", i);
21241 
21242 	if(pa->PNum)
21243 	{
21244 	    acdLog("       Name: '%S[%d]'\n", pa->Name, pa->PNum);
21245 	    acdLog("      Token: '%S[%d]'\n", pa->Token, pa->PNum);
21246 	}
21247 	else
21248 	{
21249 	    acdLog("       Name: '%S'\n", pa->Name);
21250 	    acdLog("      Token: '%S'\n", pa->Token);
21251 	}
21252 	acdLog("      Param: %d\n", pa->PNum);
21253 	acdLog("      Level: %d   (%s)\n", pa->Level, acdLevel[pa->Level]);
21254 
21255 	if(acdIsQtype(pa))
21256 	    acdLog("  Qual Type: %d   (%s)\n", pa->Type,
21257 		   acdType[pa->Type].Name);
21258 	else
21259 	    acdLog("   Key Type: %d   (%s)\n", pa->Type,
21260 		   acdKeywords[pa->Type].Name);
21261 	acdLog("      NAttr: %d\n", pa->NAttr);
21262 	acdLog("      Assoc: %B\n", pa->Assoc);
21263 
21264 	if(pa->AssocQuals)
21265 	    acdLog(" AssocQuals: %S\n", pa->AssocQuals->Name);
21266 	else
21267 	    acdLog(" AssocQuals: <undefined>\n");
21268 	acdLog("    Defined: %B\n", pa->Defined);
21269 	acdLog("    Userdefined: %B\n", pa->UserDefined);
21270 	acdLog("Orig. Value: '%S'\n", pa->OrigStr);
21271 
21272 	if(pa->ValStr)
21273 	    acdLog("      Value: '%S'\n", pa->ValStr);
21274 	else
21275 	    acdLog("      Value: <undefined>\n");
21276 	acdLog("\n");
21277 
21278 	if(pa->DefStr)
21279 	{
21280 	    acdLog("      Default Attributes:\n");
21281 	    acdListAttr(acdAttrDef, pa->DefStr, nDefAttr);
21282 	    acdLog("\n");
21283 	}
21284 	acdLog("      Attributes:\n");
21285 
21286 	if(acdIsQtype(pa))
21287 	    acdListAttr(acdType[pa->Type].Attr, pa->AttrStr, pa->NAttr);
21288 	else
21289 	    acdListAttr(acdKeywords[pa->Type].Attr, pa->AttrStr, pa->NAttr);
21290 
21291 	acdLog("\n");
21292 	i++;
21293     }
21294 
21295     return;
21296 }
21297 
21298 
21299 
21300 
21301 /* @funcstatic acdListAttr ****************************************************
21302 **
21303 ** Reports all attributes for an ACD attribute list.
21304 **
21305 ** @param [r] attr [const AcdPAttr] Attribute list
21306 ** @param [r] valstr [const AjPPStr] Array of string attribute values
21307 ** @param [r] nattr [ajint] Number of attributes in list
21308 ** @return [void]
21309 **
21310 ** @release 1.0.0
21311 ** @@
21312 ******************************************************************************/
21313 
acdListAttr(const AcdPAttr attr,const AjPPStr valstr,ajint nattr)21314 static void acdListAttr(const AcdPAttr attr, const AjPPStr valstr, ajint nattr)
21315 {
21316     ajint i;
21317 
21318     if(!valstr)
21319 	return;
21320 
21321     for(i=0; i < nattr; i++)
21322     {
21323 	if(valstr[i])
21324 	    acdLog(" %15.15s: '%S'\n", attr[i].Name, valstr[i] );
21325 	else
21326 	    acdLog(" %15.15s: <null>\n", attr[i].Name);
21327     }
21328 
21329     return;
21330 }
21331 
21332 
21333 
21334 
21335 /* @funcstatic acdSet *********************************************************
21336 **
21337 ** Sets an attribute or associated qualifier value for an ACD item.
21338 **
21339 ** All attributes, of whatever type, are treated as strings at this stage.
21340 **
21341 ** @param [r] thys [const AcdPAcd] ACD item.
21342 ** @param [u] attrib [AjPStr*] Attribute name - converted to full name
21343 ** @param [r] value [const AjPStr] Attribute value
21344 ** @return [AjBool] ajTrue if attribute is valid.
21345 ** @cre Aborts if attribute is not found.
21346 **
21347 ** @release 1.0.0
21348 ** @@
21349 ******************************************************************************/
21350 
acdSet(const AcdPAcd thys,AjPStr * attrib,const AjPStr value)21351 static AjBool acdSet(const AcdPAcd thys, AjPStr* attrib, const AjPStr value)
21352 {
21353     ajint iattr = -1;
21354     ajint idef  = -1;
21355 
21356     AcdPAttr attr   = acdType[thys->Type].Attr;
21357     AjPStr *attrstr = thys->AttrStr;
21358     AcdPAcd aqual;
21359 
21360     acdLog("acdSet attr '%S' val '%S' type '%S'\n",
21361 	   thys->Name, *attrib, value);
21362 
21363     /* recursion with associated qualifiers */
21364     aqual = NULL;
21365     if(thys->AssocQuals)
21366 	aqual = acdFindAssoc(thys, *attrib, NULL);
21367 
21368     iattr = acdFindAttr(attr, *attrib);
21369 
21370     if(thys->DefStr)	       /* try again with default attributes */
21371 	idef = acdFindAttr(acdAttrDef, *attrib);
21372 
21373     if(iattr >= 0 && idef >= 0)		/* should never happen */
21374 	acdErrorAcd(thys, "Duplicate type and default attribute '%S'",
21375 		    *attrib);
21376 
21377     if(aqual)
21378     {
21379 	if(iattr >= 0)
21380 	    acdErrorAcd(thys,		/* no known case */
21381 			"'%S' matches attribute '%s' and "
21382 			"associated qualifier '%S'",
21383 			*attrib, attr[iattr].Name, aqual->Name);
21384 	if(idef >= 0)
21385 	    acdErrorAcd(thys,		/* no known case */
21386 			"'%S' matches default attribute '%s' and "
21387 			"associated qualifier '%S'",
21388 			*attrib, acdAttrDef[idef].Name, aqual->Name);
21389     }
21390 
21391     if(iattr >= 0)
21392     {
21393 	ajStrAssignC(attrib, attr[iattr].Name);
21394         if(attr[iattr].Multiple)
21395         {
21396             if(ajStrGetLen(attrstr[iattr]))
21397                 ajStrAppendK(&attrstr[iattr], '|');
21398             ajStrAppendS(&attrstr[iattr], value);
21399         }
21400         else
21401         {
21402             if(acdDoValid && ajStrGetLen(attrstr[iattr]))
21403                 acdWarn("duplicate attribute '%S'", *attrib);
21404             ajStrAssignS(&attrstr[iattr], value);
21405         }
21406 
21407 	return ajTrue;
21408     }
21409 
21410     if(idef >= 0)
21411     {
21412 	ajStrAssignC(attrib, acdAttrDef[idef].Name);
21413         if(acdAttrDef[idef].Multiple)
21414         {
21415             if(ajStrGetLen(thys->DefStr[idef]))
21416                 ajStrAppendK(&thys->DefStr[idef], '|');
21417             ajStrAppendS(&thys->DefStr[idef], value);
21418         }
21419 
21420         else
21421         {
21422             if(acdDoValid && ajStrGetLen(thys->DefStr[idef]))
21423                 acdWarn("duplicate attribute '%S'", *attrib);
21424             ajStrAssignS(&thys->DefStr[idef], value);
21425         }
21426 
21427 	return ajTrue;
21428     }
21429 
21430     if(aqual)
21431 	return acdDef(aqual, value);
21432 
21433     /* test: wrongattr.acd */
21434     acdErrorAcd(thys, "Attribute '%S' unknown\n", *attrib );
21435 
21436     return ajFalse;
21437 }
21438 
21439 
21440 
21441 
21442 /* @funcstatic acdSetKey ******************************************************
21443 **
21444 ** Sets an attribute for an ACD key item.
21445 **
21446 ** All attributes, of whatever type, are treated as strings at this stage.
21447 **
21448 ** @param [r] thys [const AcdPAcd] ACD item.
21449 ** @param [u] attrib [AjPStr*] Attribute name, converted to full name
21450 ** @param [r] value [const AjPStr] Attribute value
21451 ** @return [AjBool] ajTrue if attribute is valid.
21452 ** @cre Aborts if attribute is not found.
21453 **
21454 ** @release 1.0.0
21455 ** @@
21456 ******************************************************************************/
21457 
acdSetKey(const AcdPAcd thys,AjPStr * attrib,const AjPStr value)21458 static AjBool acdSetKey(const AcdPAcd thys, AjPStr* attrib, const AjPStr value)
21459 {
21460     ajint iattr = -1;
21461 
21462     AcdPAttr attr = acdKeywords[thys->Type].Attr;
21463     AjPStr* attrstr = thys->AttrStr;
21464     AcdPAcd aqual;
21465 
21466     /* recursion with associated qualifiers - e.g.for application */
21467     aqual = NULL;
21468 
21469     if(thys->AssocQuals)
21470 	aqual = acdFindAssoc(thys, *attrib, NULL);
21471 
21472     iattr = acdFindAttr(attr, *attrib);
21473 
21474     if(aqual)
21475 	if(iattr >= 0)
21476 	    acdErrorAcd(thys,		/* no known case */
21477 			"'%S' matches attribute '%s' and qualifier '%S'",
21478 			*attrib, attr[iattr].Name, aqual->Name);
21479 
21480     if(iattr >= 0)
21481     {
21482 	ajStrAssignC(attrib, attr[iattr].Name);
21483         if(attr[iattr].Multiple)
21484         {
21485             if(ajStrGetLen(attrstr[iattr]))
21486                 ajStrAppendK(&attrstr[iattr], '|');
21487             ajStrAppendS(&attrstr[iattr], value);
21488         }
21489         else
21490         {
21491             if(acdDoValid && ajStrGetLen(attrstr[iattr]))
21492                 acdWarn("duplicate attribute '%S'", *attrib);
21493             ajStrAssignS(&attrstr[iattr], value);
21494         }
21495 
21496 	return ajTrue;
21497     }
21498 
21499     if(aqual)
21500 	return acdDef(aqual, value);
21501 
21502     /* test: wrongattr.acd */
21503     acdErrorAcd(thys, "Attribute '%S' unknown\n", *attrib );
21504 
21505     return ajFalse;
21506 }
21507 
21508 
21509 
21510 
21511 /* @funcstatic acdDef *********************************************************
21512 **
21513 ** Sets the default value for an ACD item, and flags in thys as Defined.
21514 **
21515 ** @param [u] thys [AcdPAcd] ACD item
21516 ** @param [r] value [const AjPStr] Default value
21517 ** @return [AjBool] ajTrue always.
21518 ** @see acdSetDef
21519 **
21520 ** @release 1.0.0
21521 ** @@
21522 ******************************************************************************/
21523 
acdDef(AcdPAcd thys,const AjPStr value)21524 static AjBool acdDef(AcdPAcd thys, const AjPStr value)
21525 {
21526     AjPStr* attrstr = thys->DefStr;
21527 
21528     acdLog("acdDef %S '%S' %x\n", thys->Name, value, attrstr);
21529 
21530     acdSetDef(thys, value);
21531     thys->Defined = ajTrue;
21532 
21533     return ajTrue;
21534 }
21535 
21536 
21537 
21538 
21539 /* @funcstatic acdSetDef ******************************************************
21540 **
21541 ** Sets the default value for an ACD item.
21542 **
21543 ** @param [u] thys [AcdPAcd] ACD item
21544 ** @param [r] value [const AjPStr] Default value
21545 ** @return [AjBool] ajTrue always.
21546 **
21547 ** @release 1.0.0
21548 ** @@
21549 ******************************************************************************/
21550 
acdSetDef(AcdPAcd thys,const AjPStr value)21551 static AjBool acdSetDef(AcdPAcd thys, const AjPStr value)
21552 {
21553     AjPStr* attrstr = thys->DefStr;
21554 
21555     acdLog("acdSetDef %S '%S' %x\n", thys->Name, value, attrstr);
21556 
21557     if(!thys->DefStr)
21558 	return ajFalse;
21559 
21560     ajStrAssignS(&attrstr[DEF_DEFAULT], value);
21561 
21562     return ajTrue;
21563 }
21564 
21565 
21566 
21567 
21568 /* @funcstatic acdSetDefC *****************************************************
21569 **
21570 ** Sets the default value for an ACD item.
21571 **
21572 ** @param [u] thys [AcdPAcd] ACD item
21573 ** @param [r] value [const char *] Default value
21574 ** @return [AjBool] ajTrue always.
21575 **
21576 ** @release 1.0.0
21577 ** @@
21578 ******************************************************************************/
21579 
acdSetDefC(AcdPAcd thys,const char * value)21580 static AjBool acdSetDefC(AcdPAcd thys, const char* value)
21581 {
21582     AjPStr *attrstr = thys->DefStr;
21583 
21584     acdLog("acdSetDefC %S '%s' %x\n", thys->Name, value, attrstr);
21585 
21586     if(!thys->DefStr)
21587 	return ajFalse;
21588 
21589     ajStrAssignC(&attrstr[DEF_DEFAULT], value);
21590 
21591     return ajTrue;
21592 }
21593 
21594 
21595 
21596 
21597 /* @funcstatic acdSetQualDefBool **********************************************
21598 **
21599 ** Sets the default value for an ACD item or one of its associated qualifiers
21600 **
21601 ** @param [u] thys [AcdPAcd] ACD item
21602 ** @param [r] name [const char *] Qualifier name
21603 ** @param [r] value [AjBool] Default value
21604 ** @return [AjBool] ajTrue always.
21605 **
21606 ** @release 1.0.0
21607 ** @@
21608 ******************************************************************************/
21609 
acdSetQualDefBool(AcdPAcd thys,const char * name,AjBool value)21610 static AjBool acdSetQualDefBool(AcdPAcd thys,
21611 				const char* name, AjBool value)
21612 {
21613     AjPStr *attrstr;
21614     AjPStr qname = NULL;
21615     AcdPAcd acd;
21616 
21617     ajStrAssignC(&qname, name);
21618     acd = acdFindQualAssoc(thys, qname, NULL, NULL, 0);
21619     ajStrDel(&qname);
21620 
21621     if(!acd)
21622 	return ajFalse;
21623 
21624     attrstr = acd->DefStr;
21625 
21626     acdLog("acdSetQualDefBool %S [%d] '%s' %B\n",
21627 	   thys->Name, thys->PNum, name, value);
21628 
21629     if(!thys->DefStr)
21630 	return ajFalse;
21631 
21632     ajFmtPrintS(&attrstr[DEF_DEFAULT], "%b", value);
21633 
21634     return ajTrue;
21635 }
21636 
21637 
21638 
21639 
21640 /* @funcstatic acdSetQualDefInt ***********************************************
21641 **
21642 ** Sets the default value for an ACD item or one of its associated qualifiers
21643 **
21644 ** @param [u] thys [AcdPAcd] ACD item
21645 ** @param [r] name [const char *] Qualifier name
21646 ** @param [r] value [ajint] Default value
21647 ** @return [AjBool] ajTrue always.
21648 **
21649 ** @release 1.0.0
21650 ** @@
21651 ******************************************************************************/
21652 
acdSetQualDefInt(AcdPAcd thys,const char * name,ajint value)21653 static AjBool acdSetQualDefInt(AcdPAcd thys, const char* name,
21654 			       ajint value)
21655 {
21656     AjPStr *attrstr;
21657     AjPStr qname = NULL;
21658     AcdPAcd acd;
21659 
21660     ajStrAssignC(&qname, name);
21661     acd = acdFindQualAssoc(thys, qname, NULL, NULL, 0);
21662 
21663     if(!acd)
21664 	return ajFalse;
21665 
21666     attrstr = acd->DefStr;
21667 
21668     acdLog("acdSetQualDefInt %S [%d] '%s' %S [%d] %d\n",
21669 	   thys->Name, thys->PNum, name, acd->Name, acd->PNum, value);
21670 
21671     if(!thys->DefStr)
21672 	return ajFalse;
21673 
21674     ajFmtPrintS(&attrstr[DEF_DEFAULT], "%d", value);
21675 
21676     ajStrDel(&qname);
21677 
21678     return ajTrue;
21679 }
21680 
21681 
21682 
21683 
21684 /* @funcstatic acdSetVarDef ***************************************************
21685 **
21686 ** Sets the default value for a variable ACD item.
21687 **
21688 ** @param [u] thys [AcdPAcd] ACD item
21689 ** @param [r] value [const AjPStr] Default value
21690 ** @return [AjBool] ajTrue always.
21691 **
21692 ** @release 1.0.0
21693 ** @@
21694 **
21695 ** Note: we have to set the ValStr directly as variables have no defstr.
21696 ** Variable references are resolved later by acdSetVar
21697 ******************************************************************************/
21698 
acdSetVarDef(AcdPAcd thys,const AjPStr value)21699 static AjBool acdSetVarDef(AcdPAcd thys, const AjPStr value)
21700 {
21701     acdLog("acdSetVarDef %S '%S' %x\n", thys->Name, value, thys->ValStr);
21702 
21703     ajStrAssignS(&thys->ValStr, value);
21704 
21705     return ajTrue;
21706 }
21707 
21708 
21709 
21710 
21711 /* @funcstatic acdFindAttr ****************************************************
21712 **
21713 ** Locates an attribute by name in an attribute list.
21714 **
21715 ** @param [r] attr [const AcdPAttr] Attribute list
21716 ** @param [r] attrib [const AjPStr] Attribute name to be found
21717 ** @return [ajint] offset in "attr" if found
21718 ** @error -1 if not found.
21719 **
21720 ** @release 1.0.0
21721 ** @@
21722 ******************************************************************************/
21723 
acdFindAttr(const AcdPAttr attr,const AjPStr attrib)21724 static ajint acdFindAttr(const AcdPAttr attr, const AjPStr attrib)
21725 {
21726     static ajint i;
21727     static ajint j;
21728     ajint ifound = 0;
21729 
21730     AjPStr ambigList = NULL;
21731 
21732     ambigList = ajStrNew();
21733 
21734     for(i=0; attr[i].Name; i++)
21735     {
21736 	if(ajStrMatchC(attrib, attr[i].Name))
21737 	{
21738 	    ajStrDel(&ambigList);
21739 	    return i;
21740 	}
21741 
21742 	if(ajCharPrefixS(attr[i].Name, attrib))
21743 	{
21744 	    ifound++;
21745 	    j = i;
21746 	    acdAmbigAppC(&ambigList, attr[i].Name);
21747 	}
21748     }
21749 
21750     if(ifound == 1)
21751     {
21752 	if (acdDoValid)
21753 	    acdWarn("Abbreviated attribute '%S' (%S)", attrib, ambigList);
21754 	ajStrDel(&ambigList);
21755 	return j;
21756     }
21757 
21758     if(ifound > 1)
21759     {
21760 	ajWarn("Ambiguous attribute %S (%S)", attrib, ambigList);
21761     }
21762 
21763     ajStrDel(&ambigList);
21764 
21765     return -1;
21766 }
21767 
21768 
21769 
21770 
21771 /* @funcstatic acdFindAttrC ***************************************************
21772 **
21773 ** Locates an attribute by name in an attribute list.
21774 **
21775 ** @param [r] attr [const AcdPAttr] Attribute list
21776 ** @param [r] attrib [const char*] Attribute name to be found
21777 ** @return [ajint] offset in "attr" if found
21778 ** @error -1 if not found.
21779 **
21780 ** @release 1.0.0
21781 ** @@
21782 ******************************************************************************/
21783 
acdFindAttrC(const AcdPAttr attr,const char * attrib)21784 static ajint acdFindAttrC(const AcdPAttr attr, const char* attrib)
21785 {
21786     static ajint i;
21787     static ajint j;
21788     ajint k;
21789     ajint ifound = 0;
21790     AjPStr ambigList = NULL;
21791 
21792     k = strlen(attrib);
21793 
21794     ambigList = ajStrNew();
21795 
21796     for(i=0; attr[i].Name; i++)
21797 	if(!strncmp(attr[i].Name, attrib, k))
21798 	{
21799 	    if(!strcmp(attr[i].Name, attrib))
21800 	    {
21801 		ajStrDel(&ambigList);
21802 		return i;
21803 	    }
21804 
21805 	    ifound++;
21806 	    j = i;
21807 	    acdAmbigAppC(&ambigList, attr[i].Name);
21808 	}
21809 
21810     if(ifound == 1)
21811     {
21812 	if (acdDoValid)
21813 	    acdWarn("Abbreviated attribute '%s', %S", attrib, ambigList);
21814 	ajStrDel(&ambigList);
21815 
21816 	return j;
21817     }
21818 
21819     if(ifound > 1)
21820     {
21821 	ajWarn("ambiguous attribute %s (%S)", attrib, ambigList);
21822     }
21823 
21824     ajStrDel(&ambigList);
21825 
21826     return -1;
21827 }
21828 
21829 
21830 
21831 
21832 /* @funcstatic acdProcess *****************************************************
21833 **
21834 ** Steps through all the ACD items, filling in missing information.
21835 ** Parameters are defined in the default attributes. The parameter
21836 ** number is generated here in the order they are found.
21837 **
21838 ** Associated qualifiers (if any) also get a copy of the parameter number.
21839 **
21840 ** @return [void]
21841 **
21842 ** @release 1.0.0
21843 ** @@
21844 ******************************************************************************/
21845 
acdProcess(void)21846 static void acdProcess(void)
21847 {
21848     AcdPAcd pa;
21849     AcdPAcd qa = NULL;
21850 
21851     AjPStr reqstr = NULL;
21852     AjPStr yesstr = NULL;
21853     AjBool isreq;
21854     AjBool isparam;
21855 
21856     if(!reqstr)
21857     {
21858 	ajStrAssignC(&reqstr, "standard");
21859 	ajStrAssignC(&yesstr, "Y");
21860     }
21861 
21862     for(acdProcCurr=acdList; acdProcCurr; acdProcCurr=acdProcCurr->Next)
21863     {
21864 	pa = acdProcCurr;
21865 
21866 	if(pa->DefStr)
21867 	    ajStrAssignS(&pa->OrigStr, pa->DefStr[DEF_DEFAULT]);
21868 
21869 	acdLog("acdProcess '%S' defstr '%x' test parameter\n",
21870 	       pa->Name, pa->DefStr);
21871 
21872 	if(!pa->Assoc && pa->DefStr && acdAttrToBoolTest(pa, "parameter",
21873                                                          ajFalse, &isparam))
21874 	{
21875 	    if(isparam)
21876 	    {
21877 		acdNParam++;
21878 		pa->PNum = acdNParam;
21879 		pa->Level = ACD_PARAM;
21880 		acdLog("acdProcess '%S' required\n", pa->Name);
21881 
21882 		/* no unresolvable variables */
21883 		if(!(acdVarTest(acdAttrValue(pa, "standard"))))
21884 		    if(!(acdAttrToBool(pa, "standard", ajFalse, &isreq)))
21885 		    {
21886 			acdSet(pa, &reqstr, yesstr);
21887 		    }
21888 
21889 		qa = pa->AssocQuals;
21890 		if(qa)
21891 		    while(qa->Assoc)
21892 		    {
21893 			qa->PNum = acdNParam;
21894 			qa = qa->Next;
21895 		    }
21896 	    }
21897 	}
21898     }
21899 
21900     ajStrDel(&reqstr);
21901     ajStrDel(&yesstr);
21902 
21903     return;
21904 }
21905 
21906 
21907 
21908 
21909 /* @funcstatic acdSetAll ******************************************************
21910 **
21911 ** Steps through all the ACD items, calling the acdSet... function
21912 ** for each in turn to prompt the user for any missing values and
21913 ** to check that all is OK.
21914 **
21915 ** @return [void]
21916 **
21917 ** @release 1.0.0
21918 ** @@
21919 ******************************************************************************/
21920 
acdSetAll(void)21921 static void acdSetAll(void)
21922 {
21923     AcdPAcd pa;
21924 
21925     AjBool isstd;
21926     AjBool isadd;
21927 
21928     const char* stdstring = "std";
21929     const char* addstring = "opt";
21930     const char* advstring = "   ";
21931     const char* nostring  = "   ";
21932     const char* level = NULL;
21933     ajint iendsec = 0;
21934 
21935     if (acdDoTrace)
21936     {
21937 	iendsec = acdFindKeyC("endsection");
21938 	ajUserDumpC("Trace:");
21939 	ajUserDumpC("Trace: Line Std        ACD_Type  Name and 'value'");
21940 	ajUserDumpC("Trace: ---- --- ---------------  ----------------");
21941     }
21942 
21943     for(acdSetCurr=acdList; acdSetCurr; acdSetCurr = acdSetCurr->Next)
21944     {
21945 	pa = acdSetCurr;
21946 
21947 	if(!pa->Assoc)
21948 	    acdMasterQual = pa;
21949 
21950 	if(!acdIsStype(pa))
21951 	{
21952 	    if (acdIsQtype(pa))
21953 		(*acdType[pa->Type].TypeSet)(pa);
21954 	    else
21955 		(*acdKeywords[pa->Type].KeySet)(pa);
21956 	}
21957 
21958 	if (acdDoTrace)
21959 	{
21960 	    if(acdIsQtype(pa))
21961 	    {
21962 		acdAttrToBool(pa, "standard", ajFalse, &isstd);
21963 		acdAttrToBool(pa, "parameter", isstd, &isstd);
21964 		acdAttrToBool(pa, "additional", ajFalse, &isadd);
21965 		if (isstd)
21966 		    level = stdstring;
21967 		else if (isadd)
21968 		    level = addstring;
21969 		else
21970 		    level = advstring;
21971 
21972 		if (pa->Assoc)
21973 		    continue;
21974 		else
21975 		    ajUser("Trace: %4d %s %15s: %15S '%S'",
21976 			   pa->LineNum, level, acdType[pa->Type].Name,
21977 			   pa->Name, pa->ValStr);
21978 	    }
21979 	    else if(acdIsStype(pa))
21980 	    {
21981 		ajUser("Trace: %4d %s %15s: %15S",
21982 		       pa->LineNum, level, acdKeywords[pa->Type].Name,
21983 		       pa->Name);
21984 		if (pa->Type == iendsec)
21985 		    ajUserDumpC("Trace:");
21986 	    }
21987 	    else
21988 	    {
21989 		ajUser("Trace: %4d %s %15s: %15S '%S'",
21990 		       pa->LineNum, nostring, acdKeywords[pa->Type].Name,
21991 		       pa->Name, pa->ValStr);
21992 	    }
21993 	}
21994     }
21995 
21996     return;
21997 }
21998 
21999 
22000 
22001 
22002 /* @funcstatic acdQualToBool **************************************************
22003 **
22004 ** Converts an associated qualifier value into a boolean.
22005 ** Any variable references are resolved at this stage.
22006 **
22007 ** @param [r] thys [const AcdPAcd] ACD item of master parameter or qualifier.
22008 ** @param [r] qual [const char*] Qualifier name
22009 ** @param [r] defval [AjBool] default value
22010 ** @param [w] result [AjBool*] Resulting value.
22011 ** @param [w] valstr [AjPStr*] Resulting value as a string
22012 ** @return [AjBool] ajTrue on success
22013 **
22014 ** @release 1.0.0
22015 ** @@
22016 ******************************************************************************/
22017 
acdQualToBool(const AcdPAcd thys,const char * qual,AjBool defval,AjBool * result,AjPStr * valstr)22018 static AjBool acdQualToBool(const AcdPAcd thys, const char *qual,
22019 			    AjBool defval, AjBool *result, AjPStr* valstr)
22020 {
22021     AjBool ret;
22022 
22023     ret = acdGetValueAssoc(thys, qual, valstr);
22024     acdLog("acdQualToBool item: %S qual: %s defval: %B str: '%S', ret: %B\n",
22025 	   thys->Name, qual, defval, *valstr, ret);
22026     if(ret)
22027     {
22028 	acdVarResolve(valstr);
22029 	acdLog("resolved to: '%S'\n", *valstr);
22030 
22031 	if(ajStrGetLen(*valstr))
22032 	{
22033 	    if(!ajStrToBool(*valstr, result))
22034 	    {
22035 		acdErrorAcd(thys,
22036 			    "Bad associated qualifier "
22037 			    "boolean value -%s = %S\n",
22038 			    thys->Name , qual, *valstr) ;
22039 	    }
22040 
22041 	    return ajTrue;
22042 	}
22043     }
22044 
22045     *result = defval;
22046     ajFmtPrintS(valstr, "%b", defval);
22047 
22048     return ajFalse;
22049 }
22050 
22051 
22052 
22053 
22054 /* @funcstatic acdQualToFloat *************************************************
22055 **
22056 ** Converts an associated qualifier value into a floating point number.
22057 ** Any variable references are resolved at this stage.
22058 **
22059 ** @param [r] thys [const AcdPAcd] ACD item of master parameter or qualifier.
22060 ** @param [r] qual [const char*] Qualifier name
22061 ** @param [r] defval [float] default value
22062 ** @param [r] precision [ajint] floating point precision
22063 ** @param [w] result [float*] Resulting value.
22064 ** @param [w] valstr [AjPStr*] Resulting value as a string
22065 ** @return [AjBool] ajTrue on success
22066 **
22067 ** @release 1.0.0
22068 ** @@
22069 ******************************************************************************/
22070 
acdQualToFloat(const AcdPAcd thys,const char * qual,float defval,ajint precision,float * result,AjPStr * valstr)22071 static AjBool acdQualToFloat(const AcdPAcd thys, const char *qual,
22072 			     float defval, ajint precision,
22073 			     float *result, AjPStr* valstr)
22074 {
22075     AjBool ret;
22076 
22077     ret = acdGetValueAssoc(thys, qual, valstr);
22078     acdLog("acdQualToFloat item: %S qual: %s defval: %.3f "
22079 	   "str: '%S' ret: %B\n",
22080 	   thys->Name, qual, defval, *valstr, ret);
22081 
22082     if(ret)
22083     {
22084 	acdVarResolve(valstr);
22085 	acdLog("resolved to: '%S'\n", *valstr);
22086 
22087 
22088 	if(ajStrGetLen(*valstr))
22089 	{
22090 	    if(!ajStrToFloat(*valstr, result))
22091 	    {
22092 		acdErrorAcd(thys,
22093 			    "%S: Bad associated qualifier "
22094 			    "float value -%s = %S\n",
22095 			    qual, *valstr) ;
22096 	    }
22097 	    return ajTrue;
22098 	}
22099     }
22100 
22101     *result = defval;
22102     ajStrFromFloat(valstr, defval, precision);
22103 
22104     return ajFalse;
22105 }
22106 
22107 
22108 
22109 
22110 /* @funcstatic acdQualToInt ***************************************************
22111 **
22112 ** Converts an associated qualifier value into an integer.
22113 ** Any variable references are resolved at this stage.
22114 **
22115 ** @param [r] thys [const AcdPAcd] ACD item of master parameter or qualifier.
22116 ** @param [r] qual [const char*] Qualifier name
22117 ** @param [r] defval [ajint] default value
22118 ** @param [w] result [ajint*] Resulting value.
22119 ** @param [w] valstr [AjPStr*] Qualifier value as a string
22120 ** @return [AjBool] ajTrue on success
22121 **
22122 ** @release 1.0.0
22123 ** @@
22124 ******************************************************************************/
22125 
acdQualToInt(const AcdPAcd thys,const char * qual,ajint defval,ajint * result,AjPStr * valstr)22126 static AjBool acdQualToInt(const AcdPAcd thys, const char *qual,
22127 			   ajint defval, ajint *result, AjPStr* valstr)
22128 {
22129     AjBool ret;
22130 
22131     ret = acdGetValueAssoc(thys, qual, valstr);
22132     acdLog("acdQualToInt item: %S qual: %s defval: %d str: '%S' ret: %B\n",
22133 	   thys->Name, qual, defval, *valstr, ret);
22134 
22135     if(ret)
22136     {
22137 	acdVarResolve(valstr);
22138 	acdLog("resolved to: '%S'\n", *valstr);
22139 
22140 	if(ajStrGetLen(*valstr))
22141 	{
22142 	    if(ajStrMatchC(*valstr, "default"))
22143 		ajStrAssignC(valstr, "0");
22144 
22145 	    if(!ajStrToInt(*valstr, result))
22146 		acdErrorAcd(thys,
22147 			    "%S: Bad associated qualifier "
22148 			    "integer value -%s = %S\n",
22149 			    qual, *valstr);
22150 
22151 	    return ajTrue;
22152 	}
22153     }
22154 
22155     *result = defval;
22156     ajStrFromInt(valstr, defval);
22157 
22158     return ajFalse;
22159 }
22160 
22161 
22162 
22163 
22164 /* @funcstatic acdQualToLong **************************************************
22165 **
22166 ** Converts an associated qualifier value into a long integer.
22167 ** Any variable references are resolved at this stage.
22168 **
22169 ** @param [r] thys [const AcdPAcd] ACD item of master parameter or qualifier.
22170 ** @param [r] qual [const char*] Qualifier name
22171 ** @param [r] defval [ajlong] default value
22172 ** @param [w] result [ajlong*] Resulting value.
22173 ** @param [w] valstr [AjPStr*] Qualifier value as a string
22174 ** @return [AjBool] ajTrue on success
22175 **
22176 ** @release 1.0.0
22177 ** @@
22178 ******************************************************************************/
22179 
acdQualToLong(const AcdPAcd thys,const char * qual,ajlong defval,ajlong * result,AjPStr * valstr)22180 static AjBool acdQualToLong(const AcdPAcd thys, const char *qual,
22181                             ajlong defval, ajlong *result, AjPStr* valstr)
22182 {
22183     AjBool ret;
22184 
22185     ret = acdGetValueAssoc(thys, qual, valstr);
22186     acdLog("acdQualToLong item: %S qual: %s defval: %Ld str: '%S' ret: %B\n",
22187 	   thys->Name, qual, defval, *valstr, ret);
22188 
22189     if(ret)
22190     {
22191 	acdVarResolve(valstr);
22192 	acdLog("resolved to: '%S'\n", *valstr);
22193 
22194 	if(ajStrGetLen(*valstr))
22195 	{
22196 	    if(ajStrMatchC(*valstr, "default"))
22197 		ajStrAssignC(valstr, "0");
22198 
22199 	    if(!ajStrToLong(*valstr, result))
22200 		acdErrorAcd(thys,
22201 			    "%S: Bad associated qualifier "
22202 			    "long integer value -%s = %S\n",
22203 			    qual, *valstr);
22204 
22205 	    return ajTrue;
22206 	}
22207     }
22208 
22209     *result = defval;
22210     ajStrFromLong(valstr, defval);
22211 
22212     return ajFalse;
22213 }
22214 
22215 
22216 
22217 
22218 /* @funcstatic acdQualToSeqbegin **********************************************
22219 **
22220 ** Converts an associated qualifier value into an integer, or the
22221 ** string "start".
22222 **
22223 ** Any variable references are resolved at this stage.
22224 **
22225 ** @param [r] thys [const AcdPAcd] ACD item of master parameter or qualifier.
22226 ** @param [r] qual [const char*] Qualifier name
22227 ** @param [r] defval [ajint] default value
22228 ** @param [w] result [ajint*] Resulting value.
22229 ** @param [w] valstr [AjPStr*] Qualifier value as a string
22230 ** @return [AjBool] ajTrue on success
22231 **
22232 ** @release 1.0.0
22233 ** @@
22234 ******************************************************************************/
22235 
acdQualToSeqbegin(const AcdPAcd thys,const char * qual,ajint defval,ajint * result,AjPStr * valstr)22236 static AjBool acdQualToSeqbegin(const AcdPAcd thys, const char *qual,
22237 				ajint defval, ajint *result, AjPStr* valstr)
22238 {
22239     AjBool ret;
22240 
22241     ret = acdGetValueAssoc(thys, qual, valstr);
22242     acdLog("acdQualToSeqpos item: %S qual: %s defval: %d str: '%S' ret: %B\n",
22243 	   thys->Name, qual, defval, *valstr, ret);
22244 
22245     if(ret)
22246     {
22247 	acdVarResolve(valstr);
22248 	acdLog("resolved to: '%S'\n", *valstr);
22249 
22250 	if(ajStrGetLen(*valstr))
22251 	{
22252 	    if(!ajStrMatchCaseC(*valstr, "default"))
22253 		if(!ajStrToInt(*valstr, result))
22254 		{
22255 		    acdErrorAcd(thys,
22256 				"Bad associated qualifier "
22257 				"integer value -%s = %S\n",
22258 				qual, *valstr);
22259 		}
22260 
22261 	    acdLog("return value %B '%S'\n", ajTrue, *valstr);
22262 	    return ajTrue;
22263 	}
22264     }
22265 
22266     *result = defval;
22267 
22268     if(!defval)
22269 	ajStrAssignC(valstr, "start");
22270     else
22271 	ajStrFromInt(valstr, defval);
22272 
22273 
22274     acdLog("return default %B '%S'\n", ajFalse, *valstr);
22275 
22276     return ajFalse;
22277 }
22278 
22279 
22280 
22281 
22282 /* @funcstatic acdQualToSeqend ************************************************
22283 **
22284 ** Converts an associated qualifier value into an integer, or the
22285 ** string "end".
22286 **
22287 ** Any variable references are resolved at this stage.
22288 **
22289 ** @param [r] thys [const AcdPAcd] ACD item of master parameter or qualifier.
22290 ** @param [r] qual [const char*] Qualifier name
22291 ** @param [r] defval [ajint] default value
22292 ** @param [w] result [ajint*] Resulting value.
22293 ** @param [w] valstr [AjPStr*] Qualifier value as a string
22294 ** @return [AjBool] ajTrue on success
22295 **
22296 ** @release 1.0.0
22297 ** @@
22298 ******************************************************************************/
22299 
acdQualToSeqend(const AcdPAcd thys,const char * qual,ajint defval,ajint * result,AjPStr * valstr)22300 static AjBool acdQualToSeqend(const AcdPAcd thys, const char *qual,
22301 			      ajint defval, ajint *result, AjPStr* valstr)
22302 {
22303     AjBool ret;
22304 
22305     ret = acdGetValueAssoc(thys, qual, valstr);
22306     acdLog("acdQualToSeqpos item: %S qual: %s defval: %d str: '%S' ret: %B\n",
22307 	   thys->Name, qual, defval, *valstr, ret);
22308 
22309     if(ret)
22310     {
22311 	acdVarResolve(valstr);
22312 	acdLog("resolved to: '%S'\n", *valstr);
22313 
22314 	if(ajStrGetLen(*valstr))
22315 	{
22316 	    if(!ajStrMatchCaseC(*valstr, "default"))
22317 		if(!ajStrToInt(*valstr, result))
22318 		{
22319 		    acdErrorAcd(thys,
22320 				"Bad associated qualifier "
22321 				"integer value -%s = %S\n",
22322 				qual, *valstr);
22323 		}
22324 
22325 	    acdLog("return value %B '%S'\n", ajTrue, *valstr);
22326 	    return ajTrue;
22327 	}
22328     }
22329 
22330     *result = defval;
22331 
22332     if(!defval)
22333 	ajStrAssignC(valstr, "end");
22334     else
22335 	ajStrFromInt(valstr, defval);
22336 
22337     acdLog("return default %B '%S'\n", ajFalse, *valstr);
22338 
22339     return ajFalse;
22340 }
22341 
22342 
22343 
22344 
22345 /* @funcstatic acdAttrToBoolTest **********************************************
22346 **
22347 ** Resolves and tests an attribute string. If it has a boolean value, returns
22348 ** true and sets the value. Otherwise returns false and the default value.
22349 **
22350 ** Has to take care to test for variables, as their values are not yet
22351 ** set when this is called.
22352 **
22353 ** @param [r] thys [const AcdPAcd] ACD item
22354 ** @param [r] attr [const char*] Attribute name
22355 ** @param [r] defval [AjBool] Default value
22356 ** @param [w] result [AjBool*] Resulting value.
22357 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22358 **         default value was used.
22359 **
22360 ** @release 2.7.0
22361 ** @@
22362 ******************************************************************************/
22363 
acdAttrToBoolTest(const AcdPAcd thys,const char * attr,AjBool defval,AjBool * result)22364 static AjBool acdAttrToBoolTest(const AcdPAcd thys,
22365 				const char *attr, AjBool defval,
22366 				AjBool *result)
22367 {
22368     if(acdVarTest(acdAttrValue(thys, attr))) /* test calcparam.acd */
22369 	acdErrorAcd(thys,
22370 		    "'%s' attribute cannot use a variable. "
22371 		    "It is used to define "
22372 		    "the command line before values have been set",
22373 		    attr);
22374 
22375     return acdAttrToBool(thys, attr, defval, result);
22376 }
22377 
22378 
22379 
22380 
22381 /* @funcstatic acdAttrToBool **************************************************
22382 **
22383 ** Resolves and tests an attribute string. If it has a boolean value, returns
22384 ** true and sets the value. Otherwise returns false and the default value.
22385 **
22386 ** @param [r] thys [const AcdPAcd] ACD item
22387 ** @param [r] attr [const char*] Attribute name
22388 ** @param [r] defval [AjBool] Default value
22389 ** @param [w] result [AjBool*] Resulting value.
22390 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22391 **         default value was used.
22392 **
22393 ** @release 1.0.0
22394 ** @@
22395 ******************************************************************************/
22396 
acdAttrToBool(const AcdPAcd thys,const char * attr,AjBool defval,AjBool * result)22397 static AjBool acdAttrToBool(const AcdPAcd thys,
22398 			    const char *attr, AjBool defval, AjBool *result)
22399 {
22400     ajint i;
22401 
22402     acdAttrResolve(thys, attr, &acdAttrValTmp);
22403 
22404     if(ajStrGetLen(acdAttrValTmp))
22405     {
22406 	if(ajStrToBool(acdAttrValTmp, result))
22407 	{
22408 	    ajStrDelStatic(&acdAttrValTmp);
22409 
22410 	    return ajTrue;
22411 	}
22412 
22413 	if(ajStrToInt(acdAttrValTmp, &i))
22414 	{
22415 	    if(i)
22416                 *result = ajTrue;
22417 	    else
22418                 *result = ajFalse;
22419 
22420 	    ajStrDelStatic(&acdAttrValTmp);
22421 
22422 	    return ajTrue;
22423 	}
22424 	else
22425 	{
22426 	    acdErrorAcd(thys, "%S: Bad attribute boolean value %s = %S\n",
22427 			thys->Name, attr, acdAttrValTmp);
22428 	}
22429     }
22430 
22431     *result = defval;
22432     ajStrDelStatic(&acdAttrValTmp);
22433 
22434     return ajFalse;
22435 }
22436 
22437 
22438 
22439 
22440 /* @funcstatic acdAttrToDouble ************************************************
22441 **
22442 ** Resolves and tests an attribute string. If it has a float value, returns
22443 ** true and sets the value. Otherwise returns false and the default value.
22444 **
22445 ** @param [r] thys [const AcdPAcd] ACD item
22446 ** @param [r] attr [const char*] Attribute name
22447 ** @param [r] defval [double] Default value
22448 ** @param [w] result [double*] Resulting value.
22449 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22450 **         default value was used.
22451 **
22452 ** @release 6.1.0
22453 ** @@
22454 ******************************************************************************/
22455 
acdAttrToDouble(const AcdPAcd thys,const char * attr,double defval,double * result)22456 static AjBool acdAttrToDouble(const AcdPAcd thys,
22457                               const char *attr, double defval, double *result)
22458 {
22459     acdAttrResolve(thys, attr, &acdAttrValTmp);
22460 
22461     if(ajStrGetLen(acdAttrValTmp))
22462     {
22463 	if(ajStrToDouble(acdAttrValTmp, result))
22464 	{
22465 	    ajStrDelStatic(&acdAttrValTmp);
22466 
22467 	    return ajTrue;
22468 	}
22469 	else
22470 	{
22471 	    acdErrorAcd(thys,
22472 			"Bad attribute double value %s = %S\n",
22473 			attr, acdAttrValTmp);
22474 	}
22475     }
22476 
22477     *result = defval;
22478     ajStrDelStatic(&acdAttrValTmp);
22479 
22480     return ajFalse;
22481 }
22482 
22483 
22484 
22485 
22486 /* @funcstatic acdAttrToFloat *************************************************
22487 **
22488 ** Resolves and tests an attribute string. If it has a float value, returns
22489 ** true and sets the value. Otherwise returns false and the default value.
22490 **
22491 ** @param [r] thys [const AcdPAcd] ACD item
22492 ** @param [r] attr [const char*] Attribute name
22493 ** @param [r] defval [float] Default value
22494 ** @param [w] result [float*] Resulting value.
22495 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22496 **         default value was used.
22497 **
22498 ** @release 1.0.0
22499 ** @@
22500 ******************************************************************************/
22501 
acdAttrToFloat(const AcdPAcd thys,const char * attr,float defval,float * result)22502 static AjBool acdAttrToFloat(const AcdPAcd thys,
22503 			     const char *attr, float defval, float *result)
22504 {
22505     acdAttrResolve(thys, attr, &acdAttrValTmp);
22506 
22507     if(ajStrGetLen(acdAttrValTmp))
22508     {
22509 	if(ajStrToFloat(acdAttrValTmp, result))
22510 	{
22511 	    ajStrDelStatic(&acdAttrValTmp);
22512 
22513 	    return ajTrue;
22514 	}
22515 	else
22516 	{
22517 	    acdErrorAcd(thys,
22518 			"Bad attribute float value %s = %S\n",
22519 			attr, acdAttrValTmp);
22520 	}
22521     }
22522 
22523     *result = defval;
22524     ajStrDelStatic(&acdAttrValTmp);
22525 
22526     return ajFalse;
22527 }
22528 
22529 
22530 
22531 
22532 /* @funcstatic acdAttrToInt ***************************************************
22533 **
22534 ** Resolves and tests an attribute string. If it has an integer value, returns
22535 ** true and sets the value. Otherwise returns false and the default value.
22536 **
22537 ** @param [r] thys [const AcdPAcd] ACD item
22538 ** @param [r] attr [const char*] Attribute name
22539 ** @param [r] defval [ajint] Default value
22540 ** @param [w] result [ajint*] Resulting value.
22541 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22542 **         default value was used.
22543 **
22544 ** @release 1.0.0
22545 ** @@
22546 ******************************************************************************/
22547 
acdAttrToInt(const AcdPAcd thys,const char * attr,ajint defval,ajint * result)22548 static AjBool acdAttrToInt(const AcdPAcd thys,
22549 			   const char *attr, ajint defval, ajint *result)
22550 {
22551     acdAttrResolve(thys, attr, &acdAttrValTmp);
22552 
22553     if(ajStrGetLen(acdAttrValTmp))
22554     {
22555 	if(ajStrToInt(acdAttrValTmp, result))
22556 	{
22557 	    ajStrDelStatic(&acdAttrValTmp);
22558 
22559 	    return ajTrue;
22560 	}
22561 	else
22562 	    acdErrorAcd(thys, "Bad attribute integer value %s = %S\n",
22563 			attr, acdAttrValTmp);
22564     }
22565 
22566     *result = defval;
22567     ajStrDelStatic(&acdAttrValTmp);
22568 
22569     return ajFalse;
22570 }
22571 
22572 
22573 
22574 
22575 /* @funcstatic acdAttrToLong **************************************************
22576 **
22577 ** Resolves and tests an attribute string. If it has an integer value, returns
22578 ** true and sets the value. Otherwise returns false and the default value.
22579 **
22580 ** @param [r] thys [const AcdPAcd] ACD item
22581 ** @param [r] attr [const char*] Attribute name
22582 ** @param [r] defval [ajlong] Default value
22583 ** @param [w] result [ajlong*] Resulting value.
22584 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22585 **         default value was used.
22586 **
22587 ** @release 6.1.0
22588 ** @@
22589 ******************************************************************************/
22590 
acdAttrToLong(const AcdPAcd thys,const char * attr,ajlong defval,ajlong * result)22591 static AjBool acdAttrToLong(const AcdPAcd thys,
22592                             const char *attr, ajlong defval, ajlong *result)
22593 {
22594     acdAttrResolve(thys, attr, &acdAttrValTmp);
22595 
22596     if(ajStrGetLen(acdAttrValTmp))
22597     {
22598 	if(ajStrToLong(acdAttrValTmp, result))
22599 	{
22600 	    ajStrDelStatic(&acdAttrValTmp);
22601 
22602 	    return ajTrue;
22603 	}
22604 	else
22605 	    acdErrorAcd(thys, "Bad attribute long integer value %s = %S\n",
22606 			attr, acdAttrValTmp);
22607     }
22608 
22609     *result = defval;
22610     ajStrDelStatic(&acdAttrValTmp);
22611 
22612     return ajFalse;
22613 }
22614 
22615 
22616 
22617 
22618 /* @funcstatic acdAttrToStr ***************************************************
22619 **
22620 ** Resolves an attribute to a string with translation of variable name(s).
22621 **
22622 ** @param [r] thys [const AcdPAcd] ACD item
22623 ** @param [r] attr [const char*] Attribute name
22624 ** @param [r] defval [const char*] Default value
22625 ** @param [w] result [AjPStr*] Resulting value.
22626 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22627 **         default value was used.
22628 **
22629 ** @release 1.0.0
22630 ** @@
22631 ******************************************************************************/
22632 
acdAttrToStr(const AcdPAcd thys,const char * attr,const char * defval,AjPStr * result)22633 static AjBool acdAttrToStr(const AcdPAcd thys,
22634 			   const char *attr, const char* defval,
22635 			   AjPStr *result)
22636 {
22637     if(acdAttrResolve(thys, attr, result))
22638 	return ajTrue;
22639 
22640     ajStrAssignC(result, defval);
22641 
22642     return ajFalse;
22643 }
22644 
22645 
22646 
22647 
22648 /* @funcstatic acdAttrToChar **************************************************
22649 **
22650 ** Resolves an attribute to a character with translation of variable name(s).
22651 **
22652 ** @param [r] thys [const AcdPAcd] ACD item
22653 ** @param [r] attr [const char*] Attribute name
22654 ** @param [r] defval [char] Default value
22655 ** @param [w] result [char*] Resulting value.
22656 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22657 **         default value was used.
22658 **
22659 ** @release 2.8.0
22660 ** @@
22661 ******************************************************************************/
22662 
acdAttrToChar(const AcdPAcd thys,const char * attr,char defval,char * result)22663 static AjBool acdAttrToChar(const AcdPAcd thys,
22664 			    const char *attr, char defval,
22665 			    char* result)
22666 {
22667     static AjPStr str = NULL;
22668 
22669     acdAttrResolve(thys, attr, &str);
22670 
22671     if(ajStrGetLen(str))
22672     {
22673 	*result = ajStrGetCharFirst(str);
22674 
22675 	return ajTrue;
22676     }
22677 
22678     *result = defval;
22679 
22680     return ajFalse;
22681 }
22682 
22683 
22684 
22685 
22686 /* @funcstatic acdAttrToUint **************************************************
22687 **
22688 ** Resolves and tests an attribute string. If it has an integer value, returns
22689 ** true and sets the value. Otherwise returns false and the default value.
22690 **
22691 ** @param [r] thys [const AcdPAcd] ACD item
22692 ** @param [r] attr [const char*] Attribute name
22693 ** @param [r] defval [ajuint] Default value
22694 ** @param [w] result [ajuint*] Resulting value.
22695 ** @return [AjBool] ajTrue if a value was defined, ajFalse if the
22696 **         default value was used.
22697 **
22698 ** @release 4.1.0
22699 ** @@
22700 ******************************************************************************/
22701 
acdAttrToUint(const AcdPAcd thys,const char * attr,ajuint defval,ajuint * result)22702 static AjBool acdAttrToUint(const AcdPAcd thys,
22703 			   const char *attr, ajuint defval, ajuint *result)
22704 {
22705     acdAttrResolve(thys, attr, &acdAttrValTmp);
22706 
22707     if(ajStrGetLen(acdAttrValTmp))
22708     {
22709 	if(ajStrToUint(acdAttrValTmp, result))
22710 	{
22711 	    ajStrDelStatic(&acdAttrValTmp);
22712 
22713 	    return ajTrue;
22714 	}
22715 	else
22716 	    acdErrorAcd(thys, "Bad attribute unsigned integer value %s = %S\n",
22717 			attr, acdAttrValTmp);
22718     }
22719 
22720     *result = defval;
22721     ajStrDelStatic(&acdAttrValTmp);
22722 
22723     return ajFalse;
22724 }
22725 
22726 
22727 
22728 
22729 /* @funcstatic acdAttrResolve *************************************************
22730 **
22731 ** Resolves an attribute to a string with translation of variable name(s).
22732 **
22733 ** @param [r] thys [const AcdPAcd] ACD item
22734 ** @param [r] attr [const char*] Attribute name
22735 ** @param [w] result [AjPStr*] Resulting value.
22736 ** @return [AjBool] ajTrue if a value was defined,
22737 **                  ajFalse if an empty string is returned.
22738 **
22739 ** @release 1.0.0
22740 ** @@
22741 ******************************************************************************/
22742 
acdAttrResolve(const AcdPAcd thys,const char * attr,AjPStr * result)22743 static AjBool acdAttrResolve(const AcdPAcd thys, const char *attr,
22744 			     AjPStr *result)
22745 {
22746     ajStrAssignS(result, acdAttrValue(thys, attr));
22747     acdVarResolve(result);
22748 
22749     if(ajStrGetLen(*result))
22750 	return ajTrue;
22751 
22752     return ajFalse;
22753 }
22754 
22755 
22756 
22757 
22758 /* @funcstatic acdVarTest *****************************************************
22759 **
22760 ** tests for any variable (but not function) references in a string.
22761 **
22762 ** Used to check whether variables might be used before we have set
22763 ** their values..
22764 **
22765 ** @param [r] var [const AjPStr] String value
22766 ** @return [AjBool] ajTrue if a variable was found
22767 **
22768 ** @release 2.7.0
22769 ** @@
22770 ******************************************************************************/
22771 
acdVarTest(const AjPStr var)22772 static AjBool acdVarTest(const AjPStr var)
22773 {
22774     if(!acdRegVarInit)
22775         acdRegVarDefine();
22776 
22777     if(ajRegExec(acdRegVarname, var))
22778 	return ajTrue;
22779 
22780     return ajFalse;
22781 }
22782 
22783 
22784 
22785 
22786 /* @funcstatic acdVarTestValid ************************************************
22787 **
22788 ** Tests for any variable (but not function) references in a string.
22789 **
22790 ** Used by acdvalid to check for dependencies that are too complex
22791 **
22792 ** @param [r] var [const AjPStr] String value
22793 ** @param [w] toggle [AjBool*] ajTrue if the value is a simple true or false
22794 **                             test of a toggle variable
22795 ** @return [AjBool] ajTrue if a variable was found
22796 **
22797 ** @release 2.8.0
22798 ** @@
22799 ******************************************************************************/
22800 
acdVarTestValid(const AjPStr var,AjBool * toggle)22801 static AjBool acdVarTestValid(const AjPStr var, AjBool* toggle)
22802 {
22803     AjPStr varref = NULL;
22804     AjPStr varname = NULL;
22805     AcdPAcd acd = NULL;
22806 
22807 
22808     if(!acdRegVarInit)
22809         acdRegVarDefine();
22810 
22811     *toggle = ajFalse;
22812 
22813     if(!ajRegExec(acdRegVarname, var))
22814 	return ajFalse;
22815 
22816     /*
22817      ** A variable - is it a simple (toggle) dependency?
22818      ** Toggles can be $(varname) or \@($(varname)) or \@(!$(varname))
22819      ** Also allowed is automatic variable acdprotein
22820      */
22821 
22822     acdLog("acdVarTestValid variable '%S'\n", var);
22823     if(ajRegExec(acdRegToggle, var))
22824     {
22825 	ajRegSubI(acdRegToggle, 2, &varref); /* returns $(varname) */
22826 	if(acdVarSimple(varref, &varname))
22827 	{
22828 	    acd = acdFindAcd(varname, varname);
22829 	    if (acd)
22830 	    {
22831 		acdLog("acdVarTestValid varname %S acd %S type %s\n",
22832 		       varname, acd->Name, acdType[acd->Type].Name);
22833 		if(!strcmp(acdType[acd->Type].Name, "toggle"))
22834 		    *toggle = ajTrue;
22835 		if(ajStrMatchCaseC(varname, "acdprotein"))
22836 		    *toggle = ajTrue;
22837 	    }
22838 	    else
22839 		acdLog("acdVarTestValid varname %S not found\n",
22840 		       varname);
22841 	}
22842 
22843 	acdLog("varname '%S' toggle %B\n", varname, *toggle);
22844 	ajStrDel(&varref);
22845 	ajStrDel(&varname);
22846     }
22847 
22848     return ajTrue;
22849 }
22850 
22851 
22852 
22853 
22854 /* @funcstatic acdVarSimple ***************************************************
22855 **
22856 ** Tests a variable reference is non recursive
22857 **
22858 ** @param [r] var [const AjPStr] String value to be tested
22859 ** @param [w] varname [AjPStr*] Variable name if found, else unchanged
22860 ** @return [AjBool] ajTrue if no further variable or function is found
22861 **
22862 ** @release 2.8.0
22863 ** @@
22864 ******************************************************************************/
22865 
acdVarSimple(const AjPStr var,AjPStr * varname)22866 static AjBool acdVarSimple(const AjPStr var, AjPStr* varname)
22867 {
22868     AjPStr attrname = NULL;
22869     AjPStr result   = NULL;
22870     AjPStr token    = NULL;
22871     AjPStr newvar    = NULL;
22872     AjPStr restvar   = NULL;
22873     AjBool ret = ajTrue;
22874 
22875     if(!acdRegVarInit)
22876         acdRegVarDefine();
22877 
22878     if(ajRegExec(acdRegVarname, var))
22879     {
22880 	ajRegSubI(acdRegVarname, 2, &token);	/* variable name */
22881 	acdVarSplit(token, varname, &attrname);
22882 
22883 	if(!ajStrGetLen(attrname))
22884 	    ajStrAssignC(&attrname, "default");
22885 
22886 	if(!acdGetAttr(&result, *varname, attrname))
22887 	{
22888 	    acdLog("acdVarSimple failed to resolve '%S.%S\n",
22889 		   *varname, attrname);
22890 	    ajStrAssignClear(&result);
22891 	}
22892 
22893 	ajRegSubI(acdRegVarname, 1, &newvar);
22894 	ajStrAppendS(&newvar, result);
22895 
22896 	if(ajRegPost(acdRegVarname, &restvar)) /* any more? */
22897 	    ajStrAppendS(&newvar, restvar);
22898 
22899 	acdLog("acdVarSimple name %S resolved to '%S'\n", *varname, newvar);
22900 
22901 	if(ajRegExec(acdRegVarname, newvar))
22902 	    ret = ajFalse;
22903 
22904 	else if(ajRegExec(acdRegFunction, newvar))
22905 	    ret = ajFalse;
22906     }
22907 
22908     /* else no variable reference at found */
22909 
22910     ajStrDel(&token);
22911     ajStrDel(&attrname);
22912     ajStrDel(&result);
22913     ajStrDel(&newvar);
22914     ajStrDel(&restvar);
22915 
22916     return ret;
22917 }
22918 
22919 
22920 
22921 
22922 /* @funcstatic acdVarSimpleResolve ********************************************
22923 **
22924 ** Tests a variable reference is a simple copy and resolves
22925 **
22926 ** @param [r] var [const AjPStr] String value to be tested
22927 ** @param [w] newvar [AjPStr*] Substituted value if found, else unchanged
22928 ** @return [AjBool] ajTrue if no further variable or function is found
22929 **
22930 ** @release 2.8.0
22931 ** @@
22932 ******************************************************************************/
22933 
acdVarSimpleResolve(const AjPStr var,AjPStr * newvar)22934 static AjBool acdVarSimpleResolve(const AjPStr var, AjPStr* newvar)
22935 {
22936     AjPStr attrname = NULL;
22937     AjPStr result   = NULL;
22938     AjPStr token    = NULL;
22939     AjPStr varname  = NULL;
22940     AjPStr restvar   = NULL;
22941     AjBool ret = ajTrue;
22942     AjPStr tmpvar = NULL;
22943 
22944     if(!acdRegVarInit)
22945         acdRegVarDefine();
22946 
22947     if(ajRegExec(acdRegVarname, var))
22948     {
22949         tmpvar = ajStrNewS(*newvar);
22950 
22951 	ajRegSubI(acdRegVarname, 2, &token);	/* variable name */
22952 	acdVarSplit(token, &varname, &attrname);
22953 
22954 	if(!ajStrGetLen(attrname))
22955 	    ajStrAssignC(&attrname, "default");
22956 
22957 	if(!acdGetAttr(&result, varname, attrname))
22958 	{
22959 	    acdLog("acdVarSimpleResolve failed to resolve '%S.%S\n",
22960 		   varname, attrname);
22961             if(ajStrMatchC(attrname, "begin"))
22962                 ajStrAssignC(&result, "0");
22963             else if(ajStrMatchC(attrname, "end"))
22964                 ajStrAssignC(&result, "0");
22965             else
22966                 ajStrAssignClear(&result);
22967 	}
22968 
22969 	ajRegSubI(acdRegVarname, 1, newvar);
22970 	ajStrAppendS(newvar, result);
22971 
22972 	if(ajRegPost(acdRegVarname, &restvar)) /* any more? */
22973 	    ajStrAppendS(newvar, restvar);
22974 
22975 	acdLog("acdVarSimpleResolve name %S resolved to '%S'\n",
22976                varname, *newvar);
22977 
22978 	if(ajRegExec(acdRegVarname, *newvar))
22979 	    ret = ajFalse;
22980 
22981 	else if(ajRegExec(acdRegFunction, *newvar))
22982 	    ret = ajFalse;
22983 
22984         if(!ret)
22985             ajStrAssignS(newvar, tmpvar);
22986 
22987         ajStrDel(&tmpvar);
22988     }
22989 
22990     /* else no variable reference at found */
22991 
22992     ajStrDel(&token);
22993     ajStrDel(&attrname);
22994     ajStrDel(&result);
22995     ajStrDel(&varname);
22996     ajStrDel(&restvar);
22997 
22998     return ret;
22999 }
23000 
23001 
23002 
23003 
23004 /* @funcstatic acdVarResolve **************************************************
23005 **
23006 ** Resolves any variable or function references in a string.
23007 **
23008 ** First resolves variables in the form $(name) or $(name.attribute).
23009 ** This cunningly resolves internal () pairs.
23010 **
23011 ** Then looks for function references and resolves them.
23012 **
23013 ** @param [w] var [AjPStr*] String value
23014 ** @return [AjBool] Always ajTrue so far
23015 **
23016 ** @release 1.0.0
23017 ** @@
23018 ******************************************************************************/
23019 
acdVarResolve(AjPStr * var)23020 static AjBool acdVarResolve(AjPStr* var)
23021 {
23022     AjPStr varname  = NULL;
23023     AjPStr attrname = NULL;
23024     AjPStr result   = NULL;
23025     AjPStr token    = NULL;
23026     AjPStr newvar    = NULL;
23027     AjPStr restvar   = NULL;
23028     AjPStr savein    = NULL;
23029 
23030     ajint ivar = 0;
23031     ajint ifun = 0;
23032 
23033     if(!acdRegResolveVar)
23034 	acdRegResolveVar = ajRegCompC("^(.*)\\$\\(([a-zA-Z0-9_.]+)\\)");
23035 
23036     if(!acdRegResolveFun)
23037 	acdRegResolveFun = ajRegCompC("^(.*)\\@\\(([^()]+)\\)");
23038 
23039     /* resolve variable references first to resolve internal parentheses */
23040     if(!var)
23041     {
23042 	ajStrAssignClear(var);
23043 	return ajTrue;
23044     }
23045 
23046     if(!ajStrGetLen(*var))
23047 	return ajTrue;
23048 
23049     ajStrAssignS(&savein, *var);
23050     acdLog("acdVarResolve '%S'\n", savein);
23051 
23052     while(ajRegExec(acdRegResolveVar, *var))
23053     {
23054 	ivar++;
23055 	ajRegSubI(acdRegResolveVar, 2, &token);	/* variable name */
23056 	acdVarSplit(token, &varname, &attrname);
23057 
23058 	if(!acdGetAttr(&result, varname, attrname))
23059 	    ajStrAssignClear(&result);
23060 
23061 	ajRegSubI(acdRegResolveVar, 1, &newvar);
23062 	ajStrAppendS(&newvar, result);
23063 
23064 	if(ajRegPost(acdRegResolveVar, &restvar)) /* any more? */
23065 	    ajStrAppendS(&newvar, restvar);
23066 
23067 	ajStrAssignS(var, newvar);
23068 	acdLog("... name %S resolved to '%S'\n", varname, newvar);
23069     }
23070 
23071     /* now resolve any function */
23072 
23073     while(ajRegExec(acdRegResolveFun, *var))
23074     {
23075 	ifun++;
23076 	ajRegSubI(acdRegResolveFun, 2, &token);	/* function statement */
23077 	acdFunResolve(&result, token);
23078 	ajRegSubI(acdRegResolveFun, 1, &newvar);
23079 	ajStrAppendS(&newvar, result);
23080 
23081 	if(ajRegPost(acdRegResolveFun, &restvar)) /* any more? */
23082 	    ajStrAppendS(&newvar, restvar);
23083 
23084 	ajStrAssignS(var, newvar);
23085 	acdLog("... function %S resolved to '%S'\n", token, newvar);
23086     }
23087 
23088     if(ivar > 1)
23089 	acdLog("Recursive variables in '%S'\n", savein);
23090 
23091     if(ifun > 1)
23092 	acdLog("Recursive expressions in '%S'\n", savein);
23093 
23094     if(acdDoTrace)
23095     {
23096 	if(ifun || ivar)
23097 	    ajUser("Trace:                           resolved '%S' => '%S'",
23098 		   savein, *var);
23099     }
23100     ajStrDel(&savein);
23101     ajStrDel(&result);
23102     ajStrDel(&varname);
23103     ajStrDel(&newvar);
23104     ajStrDel(&restvar);
23105     ajStrDel(&token);
23106     ajStrDel(&attrname);
23107 
23108     return ajTrue;
23109 }
23110 
23111 
23112 
23113 
23114 /* @funcstatic acdHelpVarResolve **********************************************
23115 **
23116 ** Resolves any variable or function references in a string if clearly
23117 ** defined, otherwise returns ajFalse and sets the string to "". For
23118 ** use with strings that cannot be resolved in help processing
23119 ** because of functions, variable dependencies etc.
23120 **
23121 ** @param [w] str [AjPStr*] String value
23122 ** @param [r] var [const AjPStr] Source string value
23123 ** @return [AjBool] ajTrue if it could be resolved cleanly
23124 **
23125 ** @release 1.0.0
23126 ** @@
23127 ******************************************************************************/
23128 
acdHelpVarResolve(AjPStr * str,const AjPStr var)23129 static AjBool acdHelpVarResolve(AjPStr* str, const AjPStr var)
23130 {
23131     if(!acdRegVarInit)
23132         acdRegVarDefine();
23133 
23134     if(!var)
23135     {
23136 	ajStrAssignClear(str);
23137 
23138 	return ajTrue;
23139     }
23140 
23141     /* reject variable references first to resolve internal parentheses */
23142     if(ajRegExec(acdRegVarname, var))
23143     {
23144         ajStrAssignClear(str);
23145 
23146         return ajFalse;
23147     }
23148 
23149     /* reject any function */
23150     if(ajRegExec(acdRegFunction, var))
23151     {
23152 	ajStrAssignClear(str);
23153 
23154 	return ajFalse;
23155     }
23156 
23157     ajStrAssignS(str, var);
23158 
23159     return ajTrue;
23160 }
23161 
23162 
23163 
23164 
23165 /* @funcstatic acdFunResolve **************************************************
23166 **
23167 ** Resolves a function reference.
23168 **
23169 ** Has a list of all accepted function syntax.
23170 **
23171 ** @param [w] result [AjPStr*] Result returned
23172 ** @param [r] str [const AjPStr] Function statement input
23173 ** @return [AjBool] Always ajTrue so far
23174 **
23175 ** @release 1.0.0
23176 ** @@
23177 ******************************************************************************/
23178 
acdFunResolve(AjPStr * result,const AjPStr str)23179 static AjBool acdFunResolve(AjPStr* result, const AjPStr str)
23180 {
23181     ajint i;
23182 
23183     acdLog("acdFunResolve '%S'\n", str);
23184 
23185     for(i = 0; explist[i].Name; i++)
23186     {
23187 	/* Calling funclist acdexplist() */
23188 
23189 	if((*explist[i].Func)(result, str))
23190 	{
23191 	    acdLog("resolved '%S' using '%s'\n", str, explist[i].Name);
23192 	    acdLog("  result '%S'\n", *result);
23193 	    return ajTrue;
23194 	}
23195     }
23196 
23197     ajWarn("ACD expression invalid @(%S)", str);
23198     acdLog("@(%S) *failed**\n", str);
23199 
23200     ajStrAssignS(result, str);
23201 
23202     return ajFalse;
23203 }
23204 
23205 
23206 
23207 
23208 /* @funcstatic acdExpPlus *****************************************************
23209 **
23210 ** Looks for and resolves an expression \@( num + num )
23211 **
23212 ** @param [w] result [AjPStr*] Expression result
23213 ** @param [r] str [const AjPStr] String with possible expression
23214 ** @return [AjBool] ajTrue if successfully resolved
23215 **
23216 ** @release 1.0.0
23217 ** @@
23218 ******************************************************************************/
23219 
acdExpPlus(AjPStr * result,const AjPStr str)23220 static AjBool acdExpPlus(AjPStr* result, const AjPStr str)
23221 {
23222     ajint ia, ib;
23223     double da, db;
23224 
23225     if(!acdRegExpPlusI)				/* ajint + ajint */
23226 	acdRegExpPlusI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[+][ \t]*"
23227 			  "([0-9+-]+)[ \t]*$");
23228 
23229     if(ajRegExec(acdRegExpPlusI, str))
23230     {
23231 	acdLog("acdRegExpPlusI matched  '%S'\n", str);
23232 	ajRegSubI(acdRegExpPlusI, 1, &acdTmpStr);
23233 	ajStrToInt(acdTmpStr, &ia);
23234 	ajRegSubI(acdRegExpPlusI, 2, &acdTmpStr);
23235 	ajStrToInt(acdTmpStr, &ib);
23236 	ajFmtPrintS(result, "%d", ia+ib);
23237 	acdLog("ia: %d + ib: %d = '%S'\n", ia, ib, *result);
23238 
23239 	return ajTrue;
23240     }
23241 
23242     if(!acdRegExpPlusD)				/* float + float */
23243 	acdRegExpPlusD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[+][ \t]*"
23244 			  "([0-9.+-]+)[ \t]*$");
23245 
23246     if(ajRegExec(acdRegExpPlusD, str))
23247     {
23248 	acdLog("dexp matched  '%S'\n", str);
23249 	ajRegSubI(acdRegExpPlusD, 1, &acdTmpStr);
23250 	ajStrToDouble(acdTmpStr, &da);
23251 	ajRegSubI(acdRegExpPlusD, 2, &acdTmpStr);
23252 	ajStrToDouble(acdTmpStr, &db);
23253 	ajFmtPrintS(result, "%f", da+db);
23254 	acdLog("da: %f + db: %f = '%S'\n", da, db, *result);
23255 
23256 	return ajTrue;
23257     }
23258 
23259     return ajFalse;
23260 }
23261 
23262 
23263 
23264 
23265 /* @funcstatic acdExpMinus ****************************************************
23266 **
23267 ** Looks for and resolves an expression \@( num - num )
23268 **
23269 ** @param [w] result [AjPStr*] Expression result
23270 ** @param [r] str [const AjPStr] String with possible expression
23271 ** @return [AjBool] ajTrue if successfully resolved
23272 **
23273 ** @release 1.0.0
23274 ** @@
23275 ******************************************************************************/
23276 
acdExpMinus(AjPStr * result,const AjPStr str)23277 static AjBool acdExpMinus(AjPStr* result, const AjPStr str)
23278 {
23279     ajint ia, ib;
23280     double da, db;
23281 
23282     if(!acdRegExpMinusI)				/* ajint + ajint */
23283 	acdRegExpMinusI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[-][ \t]*"
23284 			  "([0-9+-]+)[ \t]*$");
23285 
23286     if(ajRegExec(acdRegExpMinusI, str))
23287     {
23288 	acdLog("acdRegExpMinusI matched  '%S'\n", str);
23289 	ajRegSubI(acdRegExpMinusI, 1, &acdTmpStr);
23290 	ajStrToInt(acdTmpStr, &ia);
23291 	ajRegSubI(acdRegExpMinusI, 2, &acdTmpStr);
23292 	ajStrToInt(acdTmpStr, &ib);
23293 	ajFmtPrintS(result, "%d", ia-ib);
23294 	acdLog("ia: %d - ib: %d = '%S'\n", ia, ib, *result);
23295 
23296 	return ajTrue;
23297     }
23298 
23299     if(!acdRegExpMinusD)				/* float + float */
23300 	acdRegExpMinusD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[-][ \t]*"
23301 			  "([0-9.+-]+)[ \t]*$");
23302 
23303     if(ajRegExec(acdRegExpMinusD, str))
23304     {
23305 	acdLog("acdRegExpMinusD matched  '%S'\n", str);
23306 	ajRegSubI(acdRegExpMinusD, 1, &acdTmpStr);
23307 	ajStrToDouble(acdTmpStr, &da);
23308 	ajRegSubI(acdRegExpMinusD, 2, &acdTmpStr);
23309 	ajStrToDouble(acdTmpStr, &db);
23310 	ajFmtPrintS(result, "%f", da-db);
23311 	acdLog("da: %f - db: %f = '%S'\n", da, db, *result);
23312 
23313 	return ajTrue;
23314     }
23315 
23316     return ajFalse;
23317 }
23318 
23319 
23320 
23321 
23322 /* @funcstatic acdExpStar *****************************************************
23323 **
23324 ** Looks for and resolves an expression \@( num * num )
23325 **
23326 ** @param [w] result [AjPStr*] Expression result
23327 ** @param [r] str [const AjPStr] String with possible expression
23328 ** @return [AjBool] ajTrue if successfully resolved
23329 **
23330 ** @release 1.0.0
23331 ** @@
23332 ******************************************************************************/
23333 
acdExpStar(AjPStr * result,const AjPStr str)23334 static AjBool acdExpStar(AjPStr* result, const AjPStr str)
23335 {
23336     ajint ia, ib;
23337     double da, db;
23338 
23339     if(!acdRegExpStarI)				/* ajint + ajint */
23340 	acdRegExpStarI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[*][ \t]*"
23341 			  "([0-9+-]+)[ \t]*$");
23342 
23343     if(ajRegExec(acdRegExpStarI, str))
23344     {
23345 	acdLog("acdRegExpStarI matched  '%S'\n", str);
23346 	ajRegSubI(acdRegExpStarI, 1, &acdTmpStr);
23347 	ajStrToInt(acdTmpStr, &ia);
23348 	ajRegSubI(acdRegExpStarI, 2, &acdTmpStr);
23349 	ajStrToInt(acdTmpStr, &ib);
23350 	ajFmtPrintS(result, "%d", ia*ib);
23351 	acdLog("ia: %d * ib: %d = '%S'\n", ia, ib, *result);
23352 
23353 	return ajTrue;
23354     }
23355 
23356     if(!acdRegExpStarD)				/* float + float */
23357 	acdRegExpStarD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[*][ \t]*"
23358 			  "([0-9.+-]+)[ \t]*$");
23359 
23360     if(ajRegExec(acdRegExpStarD, str))
23361     {
23362 	acdLog("acdRegExpStarD matched  '%S'\n", str);
23363 	ajRegSubI(acdRegExpStarD, 1, &acdTmpStr);
23364 	ajStrToDouble(acdTmpStr, &da);
23365 	ajRegSubI(acdRegExpStarD, 2, &acdTmpStr);
23366 	ajStrToDouble(acdTmpStr, &db);
23367 	ajFmtPrintS(result, "%f", da*db);
23368 	acdLog("da: %f * db: %f = '%S'\n", da, db, *result);
23369 
23370 	return ajTrue;
23371     }
23372 
23373     return ajFalse;
23374 }
23375 
23376 
23377 
23378 
23379 /* @funcstatic acdExpDiv ******************************************************
23380 **
23381 ** Looks for and resolves an expression \@( num / num )
23382 **
23383 ** @param [w] result [AjPStr*] Expression result
23384 ** @param [r] str [const AjPStr] String with possible expression
23385 ** @return [AjBool] ajTrue if successfully resolved
23386 **
23387 ** @release 1.0.0
23388 ** @@
23389 ******************************************************************************/
23390 
acdExpDiv(AjPStr * result,const AjPStr str)23391 static AjBool acdExpDiv(AjPStr* result, const AjPStr str)
23392 {
23393     ajint ia;
23394     ajint ib;
23395     double da;
23396     double db;
23397 
23398     if(!acdRegExpDivI)				/* ajint + ajint */
23399 	acdRegExpDivI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[/][ \t]*"
23400 			  "([0-9+-]+)[ \t]*$");
23401 
23402     if(ajRegExec(acdRegExpDivI, str))
23403     {
23404 	acdLog("acdRegExpDivI matched  '%S'\n", str);
23405 	ajRegSubI(acdRegExpDivI, 1, &acdTmpStr);
23406 	ajStrToInt(acdTmpStr, &ia);
23407 	ajRegSubI(acdRegExpDivI, 2, &acdTmpStr);
23408 	ajStrToInt(acdTmpStr, &ib);
23409 	ajFmtPrintS(result, "%d", ia/ib);
23410 	acdLog("ia: %d / ib: %d = '%S'\n", ia, ib, *result);
23411 
23412 	return ajTrue;
23413     }
23414 
23415     if(!acdRegExpDivD)				/* float + float */
23416 	acdRegExpDivD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[/][ \t]*"
23417 			  "([0-9.+-]+)[ \t]*$");
23418 
23419     if(ajRegExec(acdRegExpDivD, str))
23420     {
23421 	acdLog("acdRegExpDivD matched  '%S'\n", str);
23422 	ajRegSubI(acdRegExpDivD, 1, &acdTmpStr);
23423 	ajStrToDouble(acdTmpStr, &da);
23424 	ajRegSubI(acdRegExpDivD, 2, &acdTmpStr);
23425 	ajStrToDouble(acdTmpStr, &db);
23426 	ajFmtPrintS(result, "%f", da/db);
23427 	acdLog("da: %f / db: %f = '%S'\n", da, db, *result);
23428 
23429 	return ajTrue;
23430     }
23431 
23432     return ajFalse;
23433 }
23434 
23435 
23436 
23437 
23438 /* @funcstatic acdExpNot ******************************************************
23439 **
23440 ** Looks for and resolves an expression \@(! bool ) or \@(NOT bool)
23441 ** or \@(not bool). An invalid bool value is treated as false,
23442 ** so it will return a true value.
23443 **
23444 ** @param [w] result [AjPStr*] Expression result
23445 ** @param [r] str [const AjPStr] String with possible expression
23446 ** @return [AjBool] ajTrue if successfully resolved
23447 **
23448 ** @release 1.0.0
23449 ** @@
23450 ******************************************************************************/
23451 
acdExpNot(AjPStr * result,const AjPStr str)23452 static AjBool acdExpNot(AjPStr* result, const AjPStr str)
23453 {
23454     AjBool ba;
23455 
23456     if(!acdRegExpNot)				/* ajint + ajint */
23457 	acdRegExpNot = ajRegCompC("^[ \t]*(!|[Nn][Oo][Tt])"
23458 			  "[ \t]*([A-Za-z0-9]+)[ \t]*$");
23459 
23460     if(ajRegExec(acdRegExpNot, str))
23461     {
23462 	acdLog("nexp matched  '%S'\n", str);
23463 	ajRegSubI(acdRegExpNot, 2, &acdTmpStr);
23464 
23465 	if(!ajStrToBool(acdTmpStr, &ba))
23466 	{
23467 	    acdLog("invalid bool value '%S' in acdExpNot\n", acdTmpStr);
23468 	    ba = ajFalse;
23469 	}
23470 
23471 	if(ba)
23472 	    ajFmtPrintS(result, "%b", ajFalse);
23473 	else
23474 	    ajFmtPrintS(result, "%b", ajTrue);
23475 
23476 	acdLog("ta: ! '%S' = '%S'\n", acdTmpStr, *result);
23477 
23478 	return ajTrue;
23479     }
23480 
23481     return ajFalse;
23482 }
23483 
23484 
23485 
23486 
23487 /* @funcstatic acdExpEqual ****************************************************
23488 **
23489 ** Looks for and resolves an expression \@( num == num )
23490 **
23491 ** @param [w] result [AjPStr*] Expression result
23492 ** @param [r] str [const AjPStr] String with possible expression
23493 ** @return [AjBool] ajTrue if successfully resolved
23494 **
23495 ** @release 1.0.0
23496 ** @@
23497 ******************************************************************************/
23498 
acdExpEqual(AjPStr * result,const AjPStr str)23499 static AjBool acdExpEqual(AjPStr* result, const AjPStr str)
23500 {
23501     ajint ia;
23502     ajint ib;
23503     double da;
23504     double db;
23505 
23506     if(!acdRegExpEqualI)				/* ajint + ajint */
23507 	acdRegExpEqualI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[=][=][ \t]*"
23508 			  "([0-9+-]+)[ \t]*$");
23509 
23510     if(ajRegExec(acdRegExpEqualI, str))
23511     {
23512 	acdLog("acdRegExpEqualI matched  '%S'\n", str);
23513 	ajRegSubI(acdRegExpEqualI, 1, &acdTmpStr);
23514 	ajStrToInt(acdTmpStr, &ia);
23515 	ajRegSubI(acdRegExpEqualI, 2, &acdTmpStr);
23516 	ajStrToInt(acdTmpStr, &ib);
23517 
23518 	if(ia == ib)
23519 	    ajFmtPrintS(result, "%b", ajTrue);
23520 	else
23521 	    ajFmtPrintS(result, "%b", ajFalse);
23522 
23523 	acdLog("ia: %d == ib: %d = '%S'\n", ia, ib, *result);
23524 
23525 	return ajTrue;
23526     }
23527 
23528     if(!acdRegExpEqualD)				/* float == float */
23529 	acdRegExpEqualD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[=][=][ \t]*"
23530 			  "([0-9.+-]+)[ \t]*$");
23531 
23532     if(ajRegExec(acdRegExpEqualD, str))
23533     {
23534 	acdLog("acdRegExpEqualD matched  '%S'\n", str);
23535 	ajRegSubI(acdRegExpEqualD, 1, &acdTmpStr);
23536 	ajStrToDouble(acdTmpStr, &da);
23537 	ajRegSubI(acdRegExpEqualD, 2, &acdTmpStr);
23538 	ajStrToDouble(acdTmpStr, &db);
23539 
23540 	if(da == db)
23541 	    ajFmtPrintS(result, "%b", ajTrue);
23542 	else
23543 	    ajFmtPrintS(result, "%b", ajFalse);
23544 
23545 	acdLog("da: %f == db: %f = '%S'\n", da, db, *result);
23546 
23547 	return ajTrue;
23548     }
23549 
23550     if(!acdRegExpEqualT)				/* string == string */
23551 	acdRegExpEqualT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[=][=][ \t]*"
23552 			  "([^ \t{}]+)[ \t]*$"); /* for {} see acdExpOneof */
23553 
23554     if(ajRegExec(acdRegExpEqualT, str))
23555     {
23556 	acdLog("acdRegExpEqualT matched  '%S'\n", str);
23557 	ajRegSubI(acdRegExpEqualT, 1, &acdTmpStr);
23558 	ajRegSubI(acdRegExpEqualT, 2, &acdTmpStr2);
23559 
23560 	if(ajStrMatchCaseS(acdTmpStr, acdTmpStr2))
23561 	    ajFmtPrintS(result, "%b", ajTrue);
23562 	else
23563 	    ajFmtPrintS(result, "%b", ajFalse);
23564 
23565 	acdLog("ta: '%S' == tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2,
23566 	       *result);
23567 
23568 	return ajTrue;
23569     }
23570 
23571     return ajFalse;
23572 }
23573 
23574 
23575 
23576 
23577 /* @funcstatic acdExpNotEqual *************************************************
23578 **
23579 ** Looks for and resolves an expression \@( num != num )
23580 **
23581 ** @param [w] result [AjPStr*] Expression result
23582 ** @param [r] str [const AjPStr] String with possible expression
23583 ** @return [AjBool] ajTrue if successfully resolved
23584 **
23585 ** @release 1.0.0
23586 ** @@
23587 ******************************************************************************/
23588 
acdExpNotEqual(AjPStr * result,const AjPStr str)23589 static AjBool acdExpNotEqual(AjPStr* result, const AjPStr str)
23590 {
23591     ajint ia;
23592     ajint ib;
23593     double da;
23594     double db;
23595 
23596     if(!acdRegExpNeI)				/* int != int */
23597 	acdRegExpNeI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[!][=][ \t]*"
23598 			  "([0-9+-]+)[ \t]*$");
23599 
23600     if(ajRegExec(acdRegExpNeI, str))
23601     {
23602 	acdLog("acdRegExpNeI matched  '%S'\n", str);
23603 	ajRegSubI(acdRegExpNeI, 1, &acdTmpStr);
23604 	ajStrToInt(acdTmpStr, &ia);
23605 	ajRegSubI(acdRegExpNeI, 2, &acdTmpStr);
23606 	ajStrToInt(acdTmpStr, &ib);
23607 
23608 	if(ia != ib)
23609 	    ajFmtPrintS(result, "%b", ajTrue);
23610 	else
23611 	    ajFmtPrintS(result, "%b", ajFalse);
23612 
23613 	acdLog("ia: %d != ib: %d = '%S'\n", ia, ib, *result);
23614 
23615 	return ajTrue;
23616     }
23617 
23618     if(!acdRegExpNeD)				/* float != float */
23619 	acdRegExpNeD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[!][=][ \t]*"
23620 			  "([0-9.+-]+)[ \t]*$");
23621 
23622     if(ajRegExec(acdRegExpNeD, str))
23623     {
23624 	acdLog("acdRegExpNeD matched  '%S'\n", str);
23625 	ajRegSubI(acdRegExpNeD, 1, &acdTmpStr);
23626 	ajStrToDouble(acdTmpStr, &da);
23627 	ajRegSubI(acdRegExpNeD, 2, &acdTmpStr);
23628 	ajStrToDouble(acdTmpStr, &db);
23629 
23630 	if(da != db)
23631 	    ajFmtPrintS(result, "%b", ajTrue);
23632 	else
23633 	    ajFmtPrintS(result, "%b", ajFalse);
23634 
23635 	acdLog("da: %f != db: %f = '%S'\n", da, db, *result);
23636 
23637 	return ajTrue;
23638     }
23639 
23640     if(!acdRegExpNeT)				/* string != string*/
23641 	acdRegExpNeT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[!][=][ \t]*"
23642 			  "([^ \t{}]+)[ \t]*$"); /* for {} see acdExpOneof */
23643 
23644     if(ajRegExec(acdRegExpNeT, str))
23645     {
23646 	acdLog("acdRegExpNeT matched  '%S'\n", str);
23647 	ajRegSubI(acdRegExpNeT, 1, &acdTmpStr);
23648 	ajRegSubI(acdRegExpNeT, 2, &acdTmpStr2);
23649 
23650 	if(!ajStrMatchCaseS(acdTmpStr, acdTmpStr2))
23651 	    ajFmtPrintS(result, "%b", ajTrue);
23652 	else
23653 	    ajFmtPrintS(result, "%b", ajFalse);
23654 
23655 	acdLog("ta: '%S' != tb: '%S' = '%S'\n",
23656 	       acdTmpStr, acdTmpStr2, *result);
23657 
23658 	return ajTrue;
23659     }
23660 
23661     return ajFalse;
23662 }
23663 
23664 
23665 
23666 
23667 /* @funcstatic acdExpGreater **************************************************
23668 **
23669 ** Looks for and resolves an expression \@( num > num )
23670 **
23671 ** @param [w] result [AjPStr*] Expression result
23672 ** @param [r] str [const AjPStr] String with possible expression
23673 ** @return [AjBool] ajTrue if successfully resolved
23674 **
23675 ** @release 1.0.0
23676 ** @@
23677 ******************************************************************************/
23678 
acdExpGreater(AjPStr * result,const AjPStr str)23679 static AjBool acdExpGreater(AjPStr* result, const AjPStr str)
23680 {
23681     ajint ia;
23682     ajint ib;
23683     double da;
23684     double  db;
23685 
23686     if(!acdRegExpGtI)				/* ajint + ajint */
23687 	acdRegExpGtI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[>][ \t]*"
23688 			  "([0-9+-]+)[ \t]*$");
23689 
23690     if(ajRegExec(acdRegExpGtI, str))
23691     {
23692 	acdLog("acdRegExpGtI matched  '%S'\n", str);
23693 	ajRegSubI(acdRegExpGtI, 1, &acdTmpStr);
23694 	ajStrToInt(acdTmpStr, &ia);
23695 	ajRegSubI(acdRegExpGtI, 2, &acdTmpStr);
23696 	ajStrToInt(acdTmpStr, &ib);
23697 
23698 	if(ia > ib)
23699 	    ajFmtPrintS(result, "%b", ajTrue);
23700 	else
23701 	    ajFmtPrintS(result, "%b", ajFalse);
23702 
23703 	acdLog("ia: %d > ib: %d = '%S'\n", ia, ib, *result);
23704 
23705 	return ajTrue;
23706     }
23707 
23708     if(!acdRegExpGtD)				/* float + float */
23709 	acdRegExpGtD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[>][ \t]*"
23710 			  "([0-9.+-]+)[ \t]*$");
23711 
23712     if(ajRegExec(acdRegExpGtD, str))
23713     {
23714 	acdLog("acdRegExpGtD matched  '%S'\n", str);
23715 	ajRegSubI(acdRegExpGtD, 1, &acdTmpStr);
23716 	ajStrToDouble(acdTmpStr, &da);
23717 	ajRegSubI(acdRegExpGtD, 2, &acdTmpStr);
23718 	ajStrToDouble(acdTmpStr, &db);
23719 
23720 	if(da > db)
23721 	    ajFmtPrintS(result, "%b", ajTrue);
23722 	else
23723 	    ajFmtPrintS(result, "%b", ajFalse);
23724 
23725 	acdLog("da: %f > db: %f = '%S'\n", da, db, *result);
23726 
23727 	return ajTrue;
23728     }
23729 
23730     if(!acdRegExpGtT)				/* float + float */
23731 	acdRegExpGtT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[>][ \t]*"
23732 			  "([^ \t]+)[ \t]*$");
23733 
23734     if(ajRegExec(acdRegExpGtT, str))
23735     {
23736 	acdLog("acdRegExpGtT matched  '%S'\n", str);
23737 	ajRegSubI(acdRegExpGtT, 1, &acdTmpStr);
23738 	ajRegSubI(acdRegExpGtT, 2, &acdTmpStr2);
23739 
23740 	if(0 > ajStrCmpCaseS(acdTmpStr2, acdTmpStr))
23741 	    ajFmtPrintS(result, "%b", ajTrue);
23742 	else
23743 	    ajFmtPrintS(result, "%b", ajFalse);
23744 
23745 	acdLog("ta: '%S' > tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2,
23746 	       *result);
23747 
23748 	return ajTrue;
23749     }
23750 
23751     return ajFalse;
23752 }
23753 
23754 
23755 
23756 
23757 /* @funcstatic acdExpLesser ***************************************************
23758 **
23759 ** Looks for and resolves an expression \@( num < num )
23760 **
23761 ** @param [w] result [AjPStr*] Expression result
23762 ** @param [r] str [const AjPStr] String with possible expression
23763 ** @return [AjBool] ajTrue if successfully resolved
23764 **
23765 ** @release 1.0.0
23766 ** @@
23767 ******************************************************************************/
23768 
acdExpLesser(AjPStr * result,const AjPStr str)23769 static AjBool acdExpLesser(AjPStr* result, const AjPStr str)
23770 {
23771     ajint ia;
23772     ajint ib;
23773     double da;
23774     double db;
23775 
23776     if(!acdRegExpLtI)				/* ajint + ajint */
23777 	acdRegExpLtI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[<][ \t]*"
23778 			  "([0-9+-]+)[ \t]*$");
23779 
23780     if(ajRegExec(acdRegExpLtI, str))
23781     {
23782 	acdLog("acdRegExpLtI matched  '%S'\n", str);
23783 	ajRegSubI(acdRegExpLtI, 1, &acdTmpStr);
23784 	ajStrToInt(acdTmpStr, &ia);
23785 	ajRegSubI(acdRegExpLtI, 2, &acdTmpStr);
23786 	ajStrToInt(acdTmpStr, &ib);
23787 
23788 	if(ia < ib)
23789 	    ajFmtPrintS(result, "%b", ajTrue);
23790 	else
23791 	    ajFmtPrintS(result, "%b", ajFalse);
23792 
23793 	acdLog("ia: %d < ib: %d = '%S'\n", ia, ib, *result);
23794 
23795 	return ajTrue;
23796     }
23797 
23798     if(!acdRegExpLtD)				/* float + float */
23799 	acdRegExpLtD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[<][ \t]*"
23800 			  "([0-9.+-]+)[ \t]*$");
23801 
23802     if(ajRegExec(acdRegExpLtD, str))
23803     {
23804 	acdLog("acdRegExpLtD matched  '%S'\n", str);
23805 	ajRegSubI(acdRegExpLtD, 1, &acdTmpStr);
23806 	ajStrToDouble(acdTmpStr, &da);
23807 	ajRegSubI(acdRegExpLtD, 2, &acdTmpStr);
23808 	ajStrToDouble(acdTmpStr, &db);
23809 
23810 	if(da < db)
23811 	    ajFmtPrintS(result, "%b", ajTrue);
23812 	else
23813 	    ajFmtPrintS(result, "%b", ajFalse);
23814 
23815 	acdLog("da: %f < db: %f = '%S'\n", da, db, *result);
23816 
23817 	return ajTrue;
23818     }
23819 
23820     if(!acdRegExpLtT)				/* float + float */
23821 	acdRegExpLtT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[<][ \t]*"
23822 			  "([^ \t]+)[ \t]*$");
23823 
23824     if(ajRegExec(acdRegExpLtT, str))
23825     {
23826 	acdLog("acdRegExpLtT matched  '%S'\n", str);
23827 	ajRegSubI(acdRegExpLtT, 1, &acdTmpStr);
23828 	ajRegSubI(acdRegExpLtT, 2, &acdTmpStr2);
23829 
23830 	if(0 < ajStrCmpCaseS(acdTmpStr2, acdTmpStr))
23831 	    ajFmtPrintS(result, "%b", ajTrue);
23832 	else
23833 	    ajFmtPrintS(result, "%b", ajFalse);
23834 
23835 	acdLog("ta: '%S' < tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2,
23836 	       *result);
23837 
23838 	return ajTrue;
23839     }
23840 
23841     return ajFalse;
23842 }
23843 
23844 
23845 
23846 
23847 /* @funcstatic acdExpOr *******************************************************
23848 **
23849 ** Looks for and resolves an expression \@( num | num )
23850 **
23851 ** @param [w] result [AjPStr*] Expression result
23852 ** @param [r] str [const AjPStr] String with possible expression
23853 ** @return [AjBool] ajTrue if successfully resolved
23854 **
23855 ** @release 1.0.0
23856 ** @@
23857 ******************************************************************************/
23858 
acdExpOr(AjPStr * result,const AjPStr str)23859 static AjBool acdExpOr(AjPStr* result, const AjPStr str)
23860 {
23861     ajint ia;
23862     ajint ib;
23863     double da;
23864     double db;
23865     AjBool ba;
23866     AjBool bb;
23867 
23868     if(!acdRegExpOrI)				/* ajint + ajint */
23869 	acdRegExpOrI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[|][ \t]*"
23870 			  "([0-9+-]+)[ \t]*$");
23871 
23872     if(ajRegExec(acdRegExpOrI, str))
23873     {
23874 	acdLog("acdRegExpOrI matched  '%S'\n", str);
23875 	ajRegSubI(acdRegExpOrI, 1, &acdTmpStr);
23876 	ajStrToInt(acdTmpStr, &ia);
23877 	ajRegSubI(acdRegExpOrI, 2, &acdTmpStr);
23878 	ajStrToInt(acdTmpStr, &ib);
23879 
23880 	if(ia || ib)
23881 	    ajFmtPrintS(result, "%b", ajTrue);
23882 	else
23883 	    ajFmtPrintS(result, "%b", ajFalse);
23884 
23885 	acdLog("ia: %d | ib: %d = '%S'\n", ia, ib, *result);
23886 
23887 	return ajTrue;
23888     }
23889 
23890     if(!acdRegExpOrD)				/* float + float */
23891 	acdRegExpOrD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[|][ \t]*"
23892 			  "([0-9.+-]+)[ \t]*$");
23893 
23894     if(ajRegExec(acdRegExpOrD, str))
23895     {
23896 	acdLog("acdRegExpOrD matched  '%S'\n", str);
23897 	ajRegSubI(acdRegExpOrD, 1, &acdTmpStr);
23898 	ajStrToDouble(acdTmpStr, &da);
23899 	ajRegSubI(acdRegExpOrD, 2, &acdTmpStr);
23900 	ajStrToDouble(acdTmpStr, &db);
23901 
23902 	if(da || db)
23903 	    ajFmtPrintS(result, "%b", ajTrue);
23904 	else
23905 	    ajFmtPrintS(result, "%b", ajFalse);
23906 
23907 	acdLog("da: %f | db: %f = '%S'\n", da, db, *result);
23908 
23909 	return ajTrue;
23910     }
23911 
23912     if(!acdRegExpOrT)				/* char + char */
23913 	acdRegExpOrT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[|][ \t]*"
23914 			  "([^ \t]+)[ \t]*$");
23915 
23916     if(ajRegExec(acdRegExpOrT, str))
23917     {
23918 	acdLog("acdRegExpOrT matched  '%S'\n", str);
23919 	ajRegSubI(acdRegExpOrT, 1, &acdTmpStr);
23920 	ajRegSubI(acdRegExpOrT, 2, &acdTmpStr2);
23921 	ajStrToBool(acdTmpStr2,&ba);
23922 	ajStrToBool(acdTmpStr, &bb);
23923 
23924 	if( ba || bb )
23925 	    ajFmtPrintS(result, "%b", ajTrue);
23926 	else
23927 	    ajFmtPrintS(result, "%b", ajFalse);
23928 
23929 	acdLog("ta: '%S' | tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2,
23930 	       *result);
23931 
23932 	return ajTrue;
23933     }
23934 
23935     return ajFalse;
23936 }
23937 
23938 
23939 
23940 
23941 /* @funcstatic acdExpAnd ******************************************************
23942 **
23943 ** Looks for and resolves an expression \@( num & num )
23944 **
23945 ** @param [w] result [AjPStr*] Expression result
23946 ** @param [r] str [const AjPStr] String with possible expression
23947 ** @return [AjBool] ajTrue if successfully resolved
23948 **
23949 ** @release 1.0.0
23950 ** @@
23951 ******************************************************************************/
23952 
acdExpAnd(AjPStr * result,const AjPStr str)23953 static AjBool acdExpAnd(AjPStr* result, const AjPStr str)
23954 {
23955     ajint ia;
23956     ajint ib;
23957     double da;
23958     double db;
23959     AjBool ba;
23960     AjBool bb;
23961 
23962     if(!acdRegExpAndI)				/* ajint + ajint */
23963 	acdRegExpAndI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[&][ \t]*"
23964 			  "([0-9+-]+)[ \t]*$");
23965 
23966     if(ajRegExec(acdRegExpAndI, str))
23967     {
23968 	acdLog("acdRegExpAndI matched  '%S'\n", str);
23969 	ajRegSubI(acdRegExpAndI, 1, &acdTmpStr);
23970 	ajStrToInt(acdTmpStr, &ia);
23971 	ajRegSubI(acdRegExpAndI, 2, &acdTmpStr);
23972 	ajStrToInt(acdTmpStr, &ib);
23973 
23974 	if(ia && ib)
23975 	    ajFmtPrintS(result, "%b", ajTrue);
23976 	else
23977 	    ajFmtPrintS(result, "%b", ajFalse);
23978 
23979 	acdLog("ia: %d & ib: %d = '%S'\n", ia, ib, *result);
23980 
23981 	return ajTrue;
23982     }
23983 
23984     if(!acdRegExpAndD)				/* float + float */
23985 	acdRegExpAndD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[&][ \t]*"
23986 			  "([0-9.+-]+)[ \t]*$");
23987     if(ajRegExec(acdRegExpAndD, str))
23988     {
23989 	acdLog("acdRegExpAndD matched  '%S'\n", str);
23990 	ajRegSubI(acdRegExpAndD, 1, &acdTmpStr);
23991 	ajStrToDouble(acdTmpStr, &da);
23992 	ajRegSubI(acdRegExpAndD, 2, &acdTmpStr);
23993 	ajStrToDouble(acdTmpStr, &db);
23994 
23995 	if(da && db)
23996 	    ajFmtPrintS(result, "%b", ajTrue);
23997 	else
23998 	    ajFmtPrintS(result, "%b", ajFalse);
23999 
24000 	acdLog("da: %f & db: %f = '%S'\n", da, db, *result);
24001 
24002 	return ajTrue;
24003     }
24004 
24005     if(!acdRegExpAndT)				/* char + char */
24006 	acdRegExpAndT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[&][ \t]*"
24007 			  "([^ \t]+)[ \t]*$");
24008 
24009     if(ajRegExec(acdRegExpAndT, str))
24010     {
24011 	acdLog("acdRegExpAndT matched  '%S'\n", str);
24012 	ajRegSubI(acdRegExpAndT, 1, &acdTmpStr);
24013 	ajRegSubI(acdRegExpAndT, 2, &acdTmpStr2);
24014 	ajStrToBool(acdTmpStr2,&ba);
24015 	ajStrToBool(acdTmpStr, &bb);
24016 
24017 	if( ba && bb )
24018 	    ajFmtPrintS(result, "%b", ajTrue);
24019 	else
24020 	    ajFmtPrintS(result, "%b", ajFalse);
24021 
24022 	acdLog("ta: '%S' & tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2,
24023 	       *result);
24024 
24025 	return ajTrue;
24026     }
24027 
24028     return ajFalse;
24029 }
24030 
24031 
24032 
24033 
24034 /* @funcstatic acdExpCond *****************************************************
24035 **
24036 ** Looks for and resolves an expression \@( bool ? trueval : falseval )
24037 **
24038 ** @param [w] result [AjPStr*] Expression result
24039 ** @param [r] str [const AjPStr] String with possible expression
24040 ** @return [AjBool] ajTrue if successfully resolved
24041 **
24042 ** @release 1.0.0
24043 ** @@
24044 ******************************************************************************/
24045 
acdExpCond(AjPStr * result,const AjPStr str)24046 static AjBool acdExpCond(AjPStr* result, const AjPStr str)
24047 {
24048     AjBool ba;
24049 
24050     if(!acdRegExpCond)			/* bool ? iftrue : iffalse */
24051 	acdRegExpCond = ajRegCompC("^[ \t]*([.A-Za-z0-9+-]*)[ \t]*[?]"
24052 				   "[ \t]*([^: \t]+)[ \t]*[:]"
24053 				   "[ \t]*([^: \t]+)[ \t]*$");
24054 
24055     if(ajRegExec(acdRegExpCond, str))
24056     {
24057 	ajRegSubI(acdRegExpCond, 1, &acdTmpStr);
24058 	ajStrToBool(acdTmpStr, &ba);
24059 
24060 	if(ba)
24061 	    ajRegSubI(acdRegExpCond, 2, result);
24062 	else
24063 	    ajRegSubI(acdRegExpCond, 3, result);
24064 
24065 	acdLog("ba: %B = '%S'\n", ba, *result);
24066 
24067 	return ajTrue;
24068     }
24069 
24070     return ajFalse;
24071 }
24072 
24073 
24074 
24075 
24076 /* @funcstatic acdExpOneof ****************************************************
24077 **
24078 ** Looks for and resolves an expression as a test for a list of values
24079 ** \@( var == { vala | valb | valc } )
24080 ** \@( var != { vala | valb | valc } )
24081 **
24082 ** @param [w] result [AjPStr*] Expression result
24083 ** @param [r] str [const AjPStr] String with possible expression
24084 ** @return [AjBool] ajTrue if successfully resolved
24085 **
24086 ** @release 2.9.0
24087 ** @@
24088 ******************************************************************************/
24089 
acdExpOneof(AjPStr * result,const AjPStr str)24090 static AjBool acdExpOneof(AjPStr* result, const AjPStr str)
24091 {
24092     AjBool todo;
24093 
24094     AjPStr testvar = NULL;
24095     AjPStr notvar = NULL;
24096     AjPStr restvar = NULL;
24097     AjPStr elsevar = NULL;
24098 
24099     if(!acdRegExpOneofCase)	 /* value = ( vala | valb | valc} ) */
24100 	acdRegExpOneofCase = ajRegCompC("^[ \t]*([A-Za-z0-9+-]+)[ \t]*"
24101 					"([!=])[=][ \t]*[{]");
24102     if(!acdRegExpOneofList)			/* case : value */
24103 	acdRegExpOneofList = ajRegCompC("^[ \t]*([^| \t]+)[ \t]*[|}]");
24104 
24105     if(ajRegExec(acdRegExpOneofCase, str))
24106     {
24107 	ajRegSubI(acdRegExpOneofCase, 1, &testvar);
24108 	ajRegSubI(acdRegExpOneofCase, 2, &notvar);	/* "!" or empty */
24109 
24110 	if(!ajRegPost(acdRegExpOneofCase, &restvar)) /* any more? */
24111 	{
24112 	    ajStrDel(&testvar);
24113 	    ajStrDel(&notvar);
24114 
24115 	    return ajFalse;
24116 	}
24117 
24118 	ajStrAssignClear(&elsevar);
24119 	todo = ajTrue;
24120 
24121 	while(todo && ajRegExec(acdRegExpOneofList, restvar))
24122 	{
24123 	    ajRegSubI(acdRegExpOneofList, 1, &acdTmpStr);
24124 
24125 	    if(ajStrMatchS(acdTmpStr, testvar)) /* match, but did we
24126 						     want to find it? */
24127 	    {
24128 		if (ajStrGetCharFirst(notvar) == '=')
24129 		    ajStrAssignC(result, "Y");
24130 		else
24131 		    ajStrAssignC(result, "N");
24132 		ajStrDel(&testvar);
24133 		ajStrDel(&notvar);
24134 		ajStrDel(&elsevar);
24135 		ajStrDel(&restvar);
24136 
24137 		return ajTrue;
24138 	    }
24139 
24140 	    todo = ajRegPost(acdRegExpOneofList, &restvar);
24141 	}
24142 	/* no match, but did we not
24143 	   want to find it? */
24144 	if (ajStrGetCharFirst(notvar) == '=')
24145 	    ajStrAssignC(result, "N");
24146 	else
24147 	    ajStrAssignC(result, "Y");
24148 
24149 	ajStrDel(&testvar);
24150 	ajStrDel(&notvar);
24151 	ajStrDel(&elsevar);
24152 	ajStrDel(&restvar);
24153 
24154 	return ajTrue;
24155     }
24156 
24157     ajStrDel(&testvar);
24158     ajStrDel(&notvar);
24159     ajStrDel(&elsevar);
24160     ajStrDel(&restvar);
24161 
24162     return ajFalse;
24163 }
24164 
24165 
24166 
24167 
24168 /* @funcstatic acdExpCase *****************************************************
24169 **
24170 ** Looks for and resolves an expression as a switch/case statement
24171 ** \@( var = casea : vala, caseb: valb else: val )
24172 **
24173 ** @param [w] result [AjPStr*] Expression result
24174 ** @param [r] str [const AjPStr] String with possible expression
24175 ** @return [AjBool] ajTrue if successfully resolved
24176 **
24177 ** @release 1.0.0
24178 ** @@
24179 ******************************************************************************/
24180 
acdExpCase(AjPStr * result,const AjPStr str)24181 static AjBool acdExpCase(AjPStr* result, const AjPStr str)
24182 {
24183     ajint ifound;
24184     AjBool todo;
24185 
24186     static AjPStr testvar = NULL;
24187     static AjPStr restvar = NULL;
24188     static AjPStr elsevar = NULL;
24189 
24190     if(!acdRegExpCaseCase)		    /* value = (case : value,  ...) */
24191 	acdRegExpCaseCase = ajRegCompC("^[ \t]*([A-Za-z0-9+-]+)[ \t]*[=]");
24192     if(!acdRegExpCaseList)			/* case : value */
24193 	acdRegExpCaseList = ajRegCompC("^[ \t]*([^: \t]+)[ \t]*[:]+"
24194 				       "[ \t]*([^: \t,]+)[ \t,]*");
24195 
24196     if(ajRegExec(acdRegExpCaseCase, str))
24197     {
24198 	ajRegSubI(acdRegExpCaseCase, 1, &testvar);
24199 
24200 	if(!ajRegPost(acdRegExpCaseCase, &restvar)) /* any more? */
24201 	{
24202 	    ajStrDel(&testvar);
24203 	    ajStrDel(&elsevar);
24204 	    ajStrDel(&restvar);
24205 
24206 	    return ajFalse;
24207 	}
24208 
24209 	ajStrAssignClear(&elsevar);
24210 	todo = ajTrue;
24211 	ifound = 0;
24212 
24213 	while(todo && ajRegExec(acdRegExpCaseList, restvar))
24214 	{
24215 	    ajRegSubI(acdRegExpCaseList, 1, &acdTmpStr);
24216 
24217 	    if(ajStrMatchC(acdTmpStr, "else")) /* default */
24218 		ajRegSubI(acdRegExpCaseList, 2, &elsevar);
24219 
24220 	    if(ajStrMatchS(acdTmpStr, testvar)) /* match, take the value */
24221 	    {
24222 		ajRegSubI(acdRegExpCaseList, 2, result);
24223 		acdLog("%S == %S : '%S'\n", testvar, acdTmpStr, *result);
24224 		ajStrDel(&testvar);
24225 		ajStrDel(&elsevar);
24226 		ajStrDel(&restvar);
24227 
24228 		return ajTrue;
24229 	    }
24230 
24231 	    if(ajStrPrefixS(testvar, acdTmpStr))
24232 	    {
24233 		ifound++;
24234 		ajRegSubI(acdRegExpCaseList, 2, result);
24235 	    }
24236 
24237 	    todo = ajRegPost(acdRegExpCaseList, &restvar);
24238 	}
24239 
24240 	if(ifound)		   /* let ambiguous matches through */
24241 	{
24242 	    if(ifound > 1)
24243 	    {
24244 		acdLog("@(=) ambiguous match, last match accepted %S\n",
24245 		       testvar);
24246 		acdLog("@(=) ambiguous match, last match accepted %S\n",
24247 		       testvar);
24248 	    }
24249 
24250 	    acdLog("%S ~= %S : '%S'\n", testvar, acdTmpStr, *result);
24251 
24252 	    if (acdDoValid)
24253 		acdWarn("Ambiguous case expression '%S' (%S)",
24254 			testvar, *result);
24255 	    ajStrDel(&testvar);
24256 	    ajStrDel(&elsevar);
24257 	    ajStrDel(&restvar);
24258 
24259 	    return ajTrue;
24260 	}
24261 
24262 	if(ifound == 0)
24263 	{
24264 	    ajStrAssignS(result, elsevar);
24265 	    acdLog("%S != else : '%S'\n", testvar, *result);
24266 	    ajStrDel(&testvar);
24267 	    ajStrDel(&elsevar);
24268 	    ajStrDel(&restvar);
24269 
24270 	    return ajTrue;
24271 	}
24272     }
24273 
24274     ajStrDel(&testvar);
24275     ajStrDel(&elsevar);
24276     ajStrDel(&restvar);
24277 
24278     return ajFalse;
24279 }
24280 
24281 
24282 
24283 
24284 /* @funcstatic acdExpFilename *************************************************
24285 **
24286 ** Looks for an expression \@(file: string) and returns a trimmed
24287 ** lower case file name prefix or suffix.
24288 **
24289 ** @param [w] result [AjPStr*] Expression result
24290 ** @param [r] str [const AjPStr] String with possible expression
24291 ** @return [AjBool] ajTrue if successfully resolved
24292 **
24293 ** @release 1.0.0
24294 ** @@
24295 ******************************************************************************/
24296 
acdExpFilename(AjPStr * result,const AjPStr str)24297 static AjBool acdExpFilename(AjPStr* result, const AjPStr str)
24298 {
24299     if(!acdRegExpFilename)				/* file: name */
24300 	acdRegExpFilename =
24301 	    ajRegCompC("^[ \t]*[Ff][Ii][Ll][Ee]:[ \t]*([^ \t]+)[ \t]*$");
24302 
24303     if(ajRegExec(acdRegExpFilename, str))
24304     {
24305 	acdLog("acdRegExpFilename matched  '%S'\n", str);
24306 	ajRegSubI(acdRegExpFilename, 1, &acdTmpStr);
24307 	ajStrAssignS(result, acdTmpStr);
24308 	ajFilenameTrimAll(result);
24309 	ajStrFmtLower(result);
24310 	acdLog("file: %S = '%S'\n", acdTmpStr, *result);
24311 
24312 	return ajTrue;
24313     }
24314 
24315     return ajFalse;
24316 }
24317 
24318 
24319 
24320 
24321 /* @funcstatic acdExpExists ***************************************************
24322 **
24323 ** Looks for an expression \@(is string) and returns ajTrue
24324 ** if there is a value, and ajFalse if there is none
24325 **
24326 ** @param [w] result [AjPStr*] Expression result
24327 ** @param [r] str [const AjPStr] String with possible expression
24328 ** @return [AjBool] ajTrue if successfully resolved
24329 **
24330 ** @release 1.0.0
24331 ** @@
24332 ******************************************************************************/
24333 
acdExpExists(AjPStr * result,const AjPStr str)24334 static AjBool acdExpExists(AjPStr* result, const AjPStr str)
24335 {
24336     AjBool test;
24337 
24338     if(!acdRegExpFileExists)				/* file: name */
24339 	acdRegExpFileExists =
24340 	    ajRegCompC("^[ \t]*[Ii][Ss]:[ \t]*([^ \t]*)[ \t]*$");
24341 
24342     if(ajRegExec(acdRegExpFileExists, str))
24343     {
24344 	acdLog("acdRegExpFileExists matched  '%S'\n", str);
24345 	ajRegSubI(acdRegExpFileExists, 1, &acdTmpStr);
24346 
24347 	if(ajStrGetLen(acdTmpStr))
24348 	    test = ajTrue;
24349 	else
24350 	    test = ajFalse;
24351 
24352 	ajFmtPrintS(result, "%b", test);
24353 	acdLog("test: '%S' = '%S'\n", acdTmpStr, *result);
24354 
24355 	return ajTrue;
24356     }
24357 
24358     return ajFalse;
24359 }
24360 
24361 
24362 
24363 
24364 /* @funcstatic acdExpValue ****************************************************
24365 **
24366 ** Looks for an expression \@(value string) and returns ajTrue
24367 ** if there is a value, and ajFalse if there is none
24368 **
24369 ** @param [w] result [AjPStr*] Expression result
24370 ** @param [r] str [const AjPStr] String with possible expression
24371 ** @return [AjBool] ajTrue if successfully resolved
24372 **
24373 ** @release 6.1.0
24374 ** @@
24375 ******************************************************************************/
24376 
acdExpValue(AjPStr * result,const AjPStr str)24377 static AjBool acdExpValue(AjPStr* result, const AjPStr str)
24378 {
24379     if(!acdRegExpValue)				/* file: name */
24380 	acdRegExpValue =
24381 	    ajRegCompC("^[ \t]*[Vv][Aa][Ll][Uu][Ee]:[ \t]*([^ \t]*)[ \t]*$");
24382 
24383     if(ajRegExec(acdRegExpValue, str))
24384     {
24385 	acdLog("acdRegExpValue matched  '%S'\n", str);
24386 	ajRegSubI(acdRegExpValue, 1, &acdTmpStr);
24387 
24388         if(!ajNamGetValueS(acdTmpStr, result))
24389             ajNamGetenvS(acdTmpStr, result);
24390 	acdLog("test: '%S' = '%S'\n", acdTmpStr, *result);
24391 
24392 	return ajTrue;
24393     }
24394 
24395     return ajFalse;
24396 }
24397 
24398 
24399 
24400 
24401 /* @funcstatic acdVarSplit ****************************************************
24402 **
24403 ** Splits a variable reference into name and attribute.
24404 ** Attribute is "default" if not specified
24405 **
24406 ** @param [r] var [const AjPStr] Variable reference
24407 ** @param [w] name [AjPStr*] Variable name
24408 ** @param [w] pattrname [AjPStr*] Attribute name, or "default" if not set.
24409 ** @return [AjBool] ajTrue if successfully split
24410 **
24411 ** @release 1.0.0
24412 ** @@
24413 ******************************************************************************/
24414 
acdVarSplit(const AjPStr var,AjPStr * name,AjPStr * pattrname)24415 static AjBool acdVarSplit(const AjPStr var, AjPStr* name, AjPStr* pattrname)
24416 {
24417     ajlong i;
24418 
24419     ajStrAssignS(name, var);
24420 
24421     i = ajStrFindC(*name, ".");		/* qualifier with value */
24422 
24423     if(i > 0)
24424     {
24425 	ajStrAssignS(pattrname, var);
24426 	ajStrKeepRange(name, 0, i-1); /* strip any value and keep testing */
24427 	ajStrCutStart(pattrname, (size_t) (i+1));
24428     }
24429     else
24430 	ajStrDelStatic(pattrname);
24431 
24432     return ajTrue;
24433 }
24434 
24435 
24436 
24437 
24438 /* @funcstatic acdAttrTest ****************************************************
24439 **
24440 ** Tests for the existence of a named attribute
24441 **
24442 ** @param [r] thys [const AcdPAcd] ACD item
24443 ** @param [r] attrib [const char*] Attribute name
24444 ** @return [AjBool] ajTrue if the named attribute exists
24445 **
24446 ** @release 2.7.0
24447 ** @@
24448 ******************************************************************************/
24449 
acdAttrTest(const AcdPAcd thys,const char * attrib)24450 static AjBool acdAttrTest(const AcdPAcd thys,const  char *attrib)
24451 {
24452     AcdPAttr attr;
24453     AcdPAttr defattr = acdAttrDef;
24454     ajint i;
24455 
24456     if(acdIsQtype(thys))
24457 	attr = acdType[thys->Type].Attr;
24458     else
24459 	attr = acdKeywords[thys->Type].Attr;
24460 
24461     i = acdFindAttrC(attr, attrib);
24462 
24463     if(i >= 0)
24464 	return ajTrue;
24465 
24466     if(thys->DefStr)
24467     {
24468 	i = acdFindAttrC(defattr, attrib);
24469 
24470 	if(i >= 0)
24471 	    return ajTrue;
24472     }
24473 
24474     return ajFalse;
24475 }
24476 
24477 
24478 
24479 
24480 /* @funcstatic acdAttrTestDefined *********************************************
24481 **
24482 ** Tests for the existence of a named attribute with a value
24483 **
24484 ** @param [r] thys [const AcdPAcd] ACD item
24485 ** @param [r] attrib [const char*] Attribute name
24486 ** @return [AjBool] ajTrue if the named attribute exists
24487 **
24488 ** @release 3.0.0
24489 ** @@
24490 ******************************************************************************/
24491 
acdAttrTestDefined(const AcdPAcd thys,const char * attrib)24492 static AjBool acdAttrTestDefined(const AcdPAcd thys,const  char *attrib)
24493 {
24494     AcdPAttr attr;
24495     AjPStr  *attrstr;
24496     AcdPAttr defattr = acdAttrDef;
24497     AjPStr  *defstr;
24498     ajint i;
24499 
24500     attrstr = thys->AttrStr;
24501     defstr = thys->DefStr;
24502 
24503 
24504     if(acdIsQtype(thys))
24505 	attr = acdType[thys->Type].Attr;
24506     else
24507 	attr = acdKeywords[thys->Type].Attr;
24508 
24509     i = acdFindAttrC(attr, attrib);
24510 
24511     if(i >= 0)
24512     {
24513 	if (ajStrGetLen(attrstr[i]))
24514 	    return ajTrue;
24515 	else
24516 	    return ajFalse;
24517     }
24518 
24519 
24520     if(thys->DefStr)
24521     {
24522 	i = acdFindAttrC(defattr, attrib);
24523 
24524 	if(i >= 0)
24525 	{
24526 	    if (ajStrGetLen(defstr[i]))
24527 		return ajTrue;
24528 	    else
24529 		return ajFalse;
24530 	}
24531     }
24532 
24533     return ajFalse;
24534 }
24535 
24536 
24537 
24538 
24539 /* @funcstatic acdAttrTestValue ***********************************************
24540 **
24541 ** Tests for the existence of a named attribute with a simple value
24542 **
24543 ** @param [r] thys [const AcdPAcd] ACD item
24544 ** @param [r] attrib [const char*] Attribute name
24545 ** @return [AjBool] ajTrue if the named attribute exists
24546 **
24547 ** @release 4.1.0
24548 ** @@
24549 ******************************************************************************/
24550 
acdAttrTestValue(const AcdPAcd thys,const char * attrib)24551 static AjBool acdAttrTestValue(const AcdPAcd thys,const  char *attrib)
24552 {
24553     AcdPAttr attr;
24554     AjPStr  *attrstr;
24555     AcdPAttr defattr = acdAttrDef;
24556     AjPStr  *defstr;
24557     ajint i;
24558 
24559     attrstr = thys->AttrStr;
24560     defstr = thys->DefStr;
24561 
24562 
24563     if(acdIsQtype(thys))
24564 	attr = acdType[thys->Type].Attr;
24565     else
24566 	attr = acdKeywords[thys->Type].Attr;
24567 
24568     i = acdFindAttrC(attr, attrib);
24569 
24570     if(i >= 0)
24571     {
24572 	if (ajStrGetLen(attrstr[i]) && ajStrFindAnyK(attrstr[i], '$') < 0)
24573 	    return ajTrue;
24574 	else
24575 	    return ajFalse;
24576     }
24577 
24578 
24579     if(thys->DefStr)
24580     {
24581 	i = acdFindAttrC(defattr, attrib);
24582 
24583 	if(i >= 0)
24584 	{
24585 	    if (ajStrGetLen(defstr[i]) && ajStrFindAnyK(defstr[i], '$') < 0)
24586 		return ajTrue;
24587 	    else
24588 		return ajFalse;
24589 	}
24590     }
24591 
24592     return ajFalse;
24593 }
24594 
24595 
24596 
24597 
24598 /* @funcstatic acdAttrValue ***************************************************
24599 **
24600 ** Returns the string value for a named attribute
24601 **
24602 ** @param [r] thys [const AcdPAcd] ACD item
24603 ** @param [r] attrib [const char*] Attribute name
24604 ** @return [const AjPStr] Attribute value.
24605 ** @cre Aborts if attribute is not found.
24606 **
24607 ** @release 1.0.0
24608 ** @@
24609 ******************************************************************************/
24610 
acdAttrValue(const AcdPAcd thys,const char * attrib)24611 static const AjPStr acdAttrValue(const AcdPAcd thys, const char *attrib)
24612 {
24613     AcdPAttr attr;
24614     AjPStr  *attrstr;
24615     AcdPAttr defattr;
24616     AjPStr  *defstr;
24617     ajint i;
24618 
24619     attrstr = thys->AttrStr;
24620     defattr = acdAttrDef;
24621     defstr = thys->DefStr;
24622 
24623 
24624     if(acdIsQtype(thys))
24625 	attr = acdType[thys->Type].Attr;
24626     else
24627 	attr = acdKeywords[thys->Type].Attr;
24628 
24629     i = acdFindAttrC(attr, attrib);
24630 
24631     if(i >= 0)
24632 	return attrstr[i];
24633 
24634     if(thys->DefStr)
24635     {
24636 	i = acdFindAttrC(defattr, attrib);
24637 
24638 	if(i >= 0)
24639 	    return defstr[i];
24640     }
24641 
24642     if(i < 0)
24643 	acdErrorAcd(thys, "Unknown attribute '%s'\n", attrib);
24644 
24645     return NULL;
24646 }
24647 
24648 
24649 
24650 
24651 /* @funcstatic acdAttrValueStr ************************************************
24652 **
24653 ** Returns the string value for a named attribute
24654 **
24655 ** @param [r] thys [const AcdPAcd] ACD item
24656 ** @param [r] attrib [const char*] Attribute name
24657 ** @param [r] def [const char*] Default value
24658 ** @param [w] str [AjPStr*] Attribute value
24659 ** @return [AjBool] ajTrue if success.
24660 ** @cre Aborts if attribute is not found.
24661 **
24662 ** @release 1.0.0
24663 ** @@
24664 ******************************************************************************/
24665 
acdAttrValueStr(const AcdPAcd thys,const char * attrib,const char * def,AjPStr * str)24666 static AjBool acdAttrValueStr(const AcdPAcd thys,
24667 			      const char *attrib, const char* def,
24668 			      AjPStr *str)
24669 {
24670     AcdPAttr attr;
24671     AjPStr  *attrstr;
24672     AcdPAttr defattr;
24673     AjPStr  *defstr;
24674     ajint i;
24675 
24676     attrstr = thys->AttrStr;
24677     defattr = acdAttrDef;
24678     defstr = thys->DefStr;
24679 
24680     if(acdIsQtype(thys))
24681 	attr = acdType[thys->Type].Attr;
24682     else
24683 	attr = acdKeywords[thys->Type].Attr;
24684 
24685     i = acdFindAttrC(attr, attrib);
24686 
24687     if(i >= 0)
24688     {
24689 	ajStrAssignS(str, attrstr[i]);
24690 	if(ajStrGetLen(*str))
24691 	    return ajTrue;
24692 	ajStrAssignC(str, def);
24693 	return ajFalse;
24694     }
24695 
24696     if(thys->DefStr)
24697     {
24698 	i = acdFindAttrC(defattr, attrib);
24699 
24700 	if(i >= 0)
24701 	{
24702 	    ajStrAssignS(str, defstr[i]);
24703 
24704 	    if(ajStrGetLen(*str))
24705 		return ajTrue;
24706 
24707 	    ajStrAssignC(str, def);
24708 
24709 	    return ajFalse;
24710 	}
24711     }
24712 
24713     if(i < 0)
24714 	acdErrorAcd(thys, "Unknown attribute %s\n", attrib);
24715 
24716     return ajFalse;
24717 }
24718 
24719 
24720 
24721 
24722 /* @section internals *********************************************************
24723 **
24724 ** Sets internal values
24725 **
24726 ** @fdata [none]
24727 **
24728 ** @nam3rule Set Set an internal value
24729 ** @nam4rule SetControl Set a control variable
24730 **
24731 ** @argrule SetControl optionName [const char*] Control variable name
24732 **
24733 ** @valrule * [AjBool]
24734 ** @fcategory misc
24735 **
24736 ******************************************************************************/
24737 
24738 
24739 
24740 
24741 /* @func ajAcdSetControl ******************************************************
24742 **
24743 ** Sets special qualifiers which were originally provided via the
24744 ** command line.
24745 **
24746 ** Sets special internal variables to reflect their presence.
24747 **
24748 ** Currently these are "acdhelp", "acdlog", "acdpretty", "acdtable",
24749 ** "acdtrace", "acdvalid", "acdverbose", "acdxsd" and "acdnocommandline"
24750 **
24751 ** @param [r] optionName [const char*] option name
24752 ** @return [AjBool] ajTrue if option was recognised
24753 **
24754 ** @release 2.7.0
24755 ** @@
24756 ******************************************************************************/
24757 
ajAcdSetControl(const char * optionName)24758 AjBool ajAcdSetControl(const char* optionName)
24759 {
24760     AcdPAcd vacd;
24761     AjPStr varname = NULL;
24762 
24763     if(!ajCharCmpCase(optionName, "acdhelp"))
24764     {
24765 	acdDoHelp = ajTrue;
24766 
24767 	return ajTrue;
24768     }
24769 
24770     if(!ajCharCmpCase(optionName, "acdlog"))
24771     {
24772 	acdDoLog = ajTrue;
24773 
24774 	return ajTrue;
24775     }
24776 
24777     if(!ajCharCmpCase(optionName, "acdnocommandline"))
24778     {
24779 	acdCommandLine = ajFalse;
24780 
24781 	return ajTrue;
24782     }
24783 
24784     if(!ajCharCmpCase(optionName, "acdpretty"))
24785     {
24786 	acdDoPretty = ajTrue;
24787 
24788 	return ajTrue;
24789     }
24790 
24791     if(!ajCharCmpCase(optionName, "acdtable"))
24792     {
24793 	acdDoTable = ajTrue;
24794 
24795 	return ajTrue;
24796     }
24797 
24798     if(!ajCharCmpCase(optionName, "acdtrace"))
24799     {
24800 	acdDoTrace = ajTrue;
24801 
24802 	return ajTrue;
24803     }
24804 
24805     if(!ajCharCmpCase(optionName, "acdvalid"))
24806     {
24807 	acdDoValid = ajTrue;
24808 
24809 	return ajTrue;
24810     }
24811 
24812     if(!ajCharCmpCase(optionName, "acdverbose"))
24813     {
24814 	acdVerbose = ajTrue;
24815 
24816 	return ajTrue;
24817     }
24818 
24819     if(!ajCharCmpCase(optionName, "acdgalaxy"))
24820     {
24821 	acdDoGalaxy = ajTrue;
24822 
24823 	return ajTrue;
24824     }
24825     if(!ajCharCmpCase(optionName, "acdgalaxynucleotide"))
24826     {
24827 	acdDoGalaxyNuc = ajTrue;
24828 
24829         ajStrAssignC(&varname, "acdprotein");
24830         ajStrAssignC(&acdVarAcdProtein, "N");
24831         vacd = acdNewVar(varname);
24832         acdSetVarDef(vacd, acdVarAcdProtein);
24833         ajStrDel(&varname);
24834 
24835 	return ajTrue;
24836     }
24837     if(!ajCharCmpCase(optionName, "acdgalaxyprotein"))
24838     {
24839 	acdDoGalaxyProt = ajTrue;
24840 
24841         ajStrAssignC(&varname, "acdprotein");
24842         ajStrAssignC(&acdVarAcdProtein, "Y");
24843         vacd = acdNewVar(varname);
24844         acdSetVarDef(vacd, acdVarAcdProtein);
24845         ajStrDel(&varname);
24846 
24847 	return ajTrue;
24848     }
24849     if(!ajCharCmpCase(optionName, "acdxsd"))
24850     {
24851 	acdDoXsd = ajTrue;
24852 
24853 	return ajTrue;
24854     }
24855 
24856     /* program source error */
24857     ajDie("Unknown ajAcdSetControl control option '%s'", optionName);
24858 
24859     return ajFalse;
24860 }
24861 
24862 
24863 
24864 
24865 /* @funcstatic acdArgsScan ****************************************************
24866 **
24867 ** Steps through the command line and checks for special qualifiers.
24868 ** Sets special internal variables to reflect their presence.
24869 **
24870 ** Currently these are "-debug", "-stdout", "-filter", "-options"
24871 ** "-help" and "-auto", plus the message controls
24872 ** "-warning", "-error", "-fatal", "-die"
24873 **
24874 ** @param [r] argc [ajint] Number of arguments
24875 ** @param [r] argv [char* const[]] Actual arguments as a text array.
24876 ** @return [void]
24877 **
24878 ** @release 1.0.0
24879 ** @@
24880 ******************************************************************************/
24881 
acdArgsScan(ajint argc,char * const argv[])24882 static void acdArgsScan(ajint argc, char * const argv[])
24883 {
24884     ajint i;
24885     char* cp;
24886 
24887     for(i=0; i < argc; i++)
24888     {
24889 	cp = argv[i];
24890 
24891 	if(*cp && strchr("-/", *cp))  /* first character vs. qualifier starts */
24892 	{
24893 	    cp++;
24894 
24895 	    if(*cp == '-')   /* allow --qualifier */
24896 		cp++;
24897 	}
24898 	else
24899 	    continue;
24900 
24901 	if(!*cp)
24902 	    continue;
24903 
24904 	if(!strcmp(cp, "debug"))
24905 	{
24906 	    acdDebug = ajTrue;
24907 	    acdDebugSet = ajTrue;
24908 	}
24909 
24910 	if(!strcmp(cp, "nodebug"))
24911 	{
24912 	    acdDebug = ajFalse;
24913 	    acdDebugSet = ajTrue;
24914 	}
24915 
24916 	if(!strcmp(cp, "stdout"))
24917 	    acdStdout = ajTrue;
24918 
24919 	if(!strcmp(cp, "filter"))
24920 	    acdFilter = ajTrue;
24921 
24922 	if(!strcmp(cp, "options"))
24923 	    acdOptions = ajTrue;
24924 
24925 	if(!strcmp(cp, "verbose"))
24926 	    acdVerbose = ajTrue;
24927 
24928 	if(!strcmp(cp, "version"))
24929 	    acdDoVersion = ajTrue;
24930 
24931 	if(!strcmp(cp, "help"))
24932 	    acdDoHelp = ajTrue;
24933 
24934 	if(!strcmp(cp, "auto"))
24935         {
24936             acdPromptTry = 1;
24937 	    acdAuto = ajTrue;
24938         }
24939 
24940 	if(!strcmp(cp, "warning"))
24941 	    AjErrorLevel.warning = ajTrue;
24942 
24943 	if(!strcmp(cp, "nowarning"))
24944 	    AjErrorLevel.warning = ajFalse;
24945 
24946 	if(!strcmp(cp, "error"))
24947 	    AjErrorLevel.error = ajTrue;
24948 
24949 	if(!strcmp(cp, "noerror"))
24950 	    AjErrorLevel.error = ajFalse;
24951 
24952 	if(!strcmp(cp, "-fatal"))
24953 	    AjErrorLevel.fatal = ajTrue;
24954 
24955 	if(!strcmp(cp, "nofatal"))
24956 	    AjErrorLevel.fatal = ajFalse;
24957 
24958 	if(!strcmp(cp, "die"))
24959 	    AjErrorLevel.die = ajTrue;
24960 
24961 	if(!strcmp(cp, "nodie"))
24962 	    AjErrorLevel.die = ajFalse;
24963 
24964 	if(!strcmp(cp, "help"))
24965 	    acdLog("acdArgsScan -help argv[%d]\n", i);
24966     }
24967 
24968     acdLog("acdArgsScan acdDebug %B acdDoHelp %B\n", acdDebug, acdDoHelp);
24969 
24970     return;
24971 }
24972 
24973 
24974 
24975 
24976 /* @funcstatic acdArgsParse ***************************************************
24977 **
24978 ** Steps through the command line and compares to the stored command structure.
24979 ** Capable of cunning tricks such as matching values to qualifiers if they fit,
24980 ** and otherwise treating them as parameters.
24981 **
24982 ** @param [r] argc [ajint] Number of arguments
24983 ** @param [r] argv [char* const[]] Actual arguments as a text array.
24984 ** @return [void]
24985 **
24986 ** @release 1.0.0
24987 ** @@
24988 ******************************************************************************/
24989 
acdArgsParse(ajint argc,char * const argv[])24990 static void acdArgsParse(ajint argc, char * const argv[])
24991 {
24992     ajint i;
24993     ajint j;
24994     ajint number;
24995 
24996     ajint iparam = 0;			/* expected next param */
24997     ajint jparam = 0;			/* param found */
24998     ajint itestparam = 0;
24999     ajint jtestparam = 0;
25000     AcdPAcd acd;
25001     AcdPAcd acd2;
25002 
25003     const char *cp;
25004     const char *cq;
25005 
25006     AjPStr qual  = NULL;
25007     AjPStr noqual = NULL;
25008     AjPStr value = NULL;
25009     AjPStr param = NULL;
25010     AjPStr token = NULL;
25011     AjPStr master = NULL;
25012     AjPStr argvalstr = NULL;
25013 
25014     acdLog("ArgsParse\n=========\n");
25015 
25016     acdLog("\n");
25017 
25018     acdMasterQual = NULL;
25019 /*    acdQualTestSkip = ajFalse; */
25020 
25021     i = 1;
25022 
25023     while(i < argc)
25024     {
25025 	acdLog("%s ", argv[i]);
25026 	i++;
25027     }
25028 
25029     acdLog("\n");
25030     acdLog("\n");
25031 
25032     i = 1;				/* skip the program name */
25033 
25034     while(i < argc)
25035     {
25036 	cp = argv[i];
25037 
25038 	if((i+1) < argc)
25039             cq = argv[i+1];
25040 	else
25041             cq = NULL;
25042 
25043 	if(acdArgSave)
25044 	    ajStrAppendK(&acdArgSave, '\n');
25045 
25046 	acdLog("\n");
25047 	acdLog("argv[%d] <%s>", i, cp);
25048 
25049 	if(cq)
25050 	    acdLog(" + argv[%d] <%s>", i+1, cq);
25051 
25052 	acdLog("\n");
25053 	jparam = 0;
25054 
25055 	if((j = acdIsQual(cp, cq, &jparam, &qual, &noqual,
25056 			  &value, &number, &master, &acd)))
25057 	{
25058 	    if(jparam)
25059 	    {
25060 		acdLog("Parameter (%d) ", jparam);
25061 		acdParamSet[jparam-1] = ajTrue;
25062 
25063 		if(iparam == (jparam-1))
25064 		{
25065 		    iparam = acdNextParam(iparam);
25066 		    acdLog("reset iparam = %d\n", iparam);
25067 		}
25068 		else
25069 		    acdLog("keep iparam = %d\n", iparam);
25070 	    }
25071 	    else
25072 		acdLog("Qualifier ");
25073 
25074 	    acdLog("-%S ", noqual);
25075 
25076 	    if(number)
25077 		acdLog("[%d] ", number);
25078 
25079 	    if(ajStrGetLen(value))
25080 		acdLog("= '%S'", value);
25081 
25082 	    acdLog("\n");
25083 
25084 	    /*
25085 	     ** acdFindQualDetail dies (Unknown qualifier) if acd is not set,
25086 	     ** so we are safe here
25087 	     */
25088 
25089 	    acdDef(acd, value);
25090 	    acdLog("set qualifier -%S[%d] (param %d) = %S\n",
25091 		   acd->Name, acd->PNum, jparam, value);
25092 
25093 	    /* loop over any associated qualifiers for the rest */
25094 	    acdLog("number: %d jparam: %d acd->PNum: %d acdNParam: %d\n",
25095 		   number, jparam, acd->PNum, acdNParam);
25096 
25097             if(!ajStrGetLen(master) && !number && !jparam && acd->PNum)
25098 	    {
25099 		for(itestparam = acd->PNum+1; itestparam <= acdNParam;
25100 		    itestparam++)
25101 		{
25102 		    acdLog("test [%d] '%S'\n", itestparam, qual);
25103 		    acd2 = acdFindQualDetail(qual, NULL, NULL,
25104 					    itestparam, &jtestparam);
25105 		    if(acd2)
25106 		    {
25107 			acdDef(acd2, value);
25108 			acdLog("set next qualifier -%S[%d] (param %d) = %S\n",
25109 			       acd2->Name, acd2->PNum, jparam, value);
25110 		    }
25111 		    else
25112 			acdLog("no -%S[%d]\n", qual, itestparam);
25113 		}
25114 	    }
25115 
25116 	    acd->UserDefined = ajTrue;
25117 	    ajStrAppendK(&acdArgSave, '-');
25118 	    ajStrAppendS(&acdArgSave, noqual);
25119 
25120 	    if(number)
25121 		ajFmtPrintAppS(&acdArgSave, "%d", number);
25122 	    else if(ajStrGetLen(master))
25123 		ajFmtPrintAppS(&acdArgSave, "_%S", master);
25124 
25125 	    if(j==2)
25126 	    {
25127 		i++;
25128 	    }
25129 
25130 	    ajStrAssignS(&argvalstr, value);
25131 
25132 	    if(!strcmp(acdType[acd->Type].Name, "boolean") ||
25133 	       !strcmp(acdType[acd->Type].Name, "toggle"))
25134 	    {
25135 		if(ajStrMatchS(qual, noqual)) /* -boolqual */
25136 		{
25137 		    if(ajStrMatchC(value, "Y"))
25138 			ajStrAssignClear(&argvalstr);
25139 		}
25140 		else if(ajStrMatchC(value, "N")) /* -noboolqual */
25141 			ajStrAssignClear(&argvalstr);
25142 
25143 		if(ajStrGetLen(argvalstr)) /* non-trivial boolean values */
25144 		{
25145 		    ajStrAppendK(&acdArgSave, ' ');
25146 		    ajStrAppendS(&acdArgSave, argvalstr);
25147 		}
25148 	    }
25149 	    else if(ajStrIsWord(value) &&
25150 		    (ajStrFindAnyC(value, "*?[]{}|!&^") < 0))
25151 	    {
25152 		ajStrAppendK(&acdArgSave, ' ');
25153 		ajStrAppendS(&acdArgSave, value);
25154 	    }
25155 	    else if(ajStrMatchS(qual, noqual)) /* not -nomissfile */
25156 	    {
25157 		ajStrAppendK(&acdArgSave, ' ');
25158 		ajStrAppendK(&acdArgSave, '\"');
25159 		ajStrAppendS(&acdArgSave, value);
25160 		ajStrAppendK(&acdArgSave, '\"');
25161 	    }
25162 	}
25163 	else		    /* not a qualifier - assume a parameter */
25164 	{
25165 	    iparam = acdNextParam(0);	/* first free parameter */
25166 	    acdIsParam(cp, &param, &iparam, &acd); /* die if too many */
25167 
25168 	    acd->UserDefined = ajTrue;
25169 	    ajStrAppendC(&acdArgSave, "[-");
25170 	    ajStrAppendS(&acdArgSave, acd->Name);
25171 	    ajStrAppendC(&acdArgSave, "] ");
25172 
25173 	    if(acdIsParamValue(param))
25174 	    {
25175 		acdLog("Parameter %d: %S = %S\n",
25176 		       iparam, acd->Name, param);
25177 		acdDef(acd, param);
25178 		acdParamSet[iparam-1] = ajTrue;
25179 		ajStrAssignC(&argvalstr, cp);
25180 
25181 		if(ajStrIsWord(argvalstr) &&
25182 		   (ajStrFindAnyC(argvalstr, "*?[]{}|!&^") < 0))
25183 		    ajStrAppendS(&acdArgSave, argvalstr);
25184 		else
25185 		{
25186 		    ajStrAppendK(&acdArgSave, '\"');
25187 		    ajStrAppendS(&acdArgSave, argvalstr);
25188 		    ajStrAppendK(&acdArgSave, '\"');
25189 		}
25190 	    }
25191 	    else		 /* missing value "" ignored */
25192 	    {
25193 		acdLog("Parameter %d: %S = '%S' ** missing value **\n",
25194 		       iparam, acd->Name, param);
25195 		ajStrAssignClear(&param);
25196 		acdDef(acd, param);
25197 		acdParamSet[iparam-1] = ajTrue;
25198 		ajStrAppendC(&acdArgSave, "\"\"");
25199 	    }
25200 	}
25201 
25202 	i++;
25203     }
25204 
25205     ajStrDel(&qual);
25206     ajStrDel(&noqual);
25207     ajStrDel(&value);
25208     ajStrDel(&param);
25209     ajStrDel(&token);
25210     ajStrDel(&argvalstr);
25211 
25212     return;
25213 }
25214 
25215 
25216 
25217 
25218 /* @funcstatic acdIsParamValue ************************************************
25219 **
25220 ** Tests whether a parameter value is 'missing', in which case
25221 ** it will be ignored for now.
25222 **
25223 ** @param [r] pval [const AjPStr] Parameter value
25224 **
25225 ** @return [AjBool] ajFalse for a missing value.
25226 **
25227 ** @release 1.0.0
25228 ** @@
25229 ******************************************************************************/
25230 
acdIsParamValue(const AjPStr pval)25231 static AjBool acdIsParamValue(const AjPStr pval)
25232 {
25233     if(!ajStrGetLen(pval))
25234 	return ajFalse;
25235 
25236     return ajTrue;
25237 }
25238 
25239 
25240 
25241 
25242 /* @funcstatic acdNextParam ***************************************************
25243 **
25244 ** Returns the next unknown parameter. Used for cases where parameters
25245 ** are specified by qualifier before their turn on the command line
25246 **
25247 ** @param [r] pnum [ajint] Current parameter number
25248 **
25249 ** @return [ajint] next undefined parameter
25250 **
25251 ** @release 1.0.0
25252 ** @@
25253 ******************************************************************************/
25254 
acdNextParam(ajint pnum)25255 static ajint acdNextParam(ajint pnum)
25256 {
25257     ajint i;
25258 
25259     if(pnum > acdNParam)
25260 	return pnum+1;                  /* all done */
25261 
25262     for(i=pnum;i<acdNParam;i++)
25263 	if(!acdParamSet[i])
25264 	    return i;	                /* next free parameter */
25265 
25266     return acdNParam+1;			/* all done */
25267 }
25268 
25269 
25270 
25271 
25272 /* @funcstatic acdIsParam *****************************************************
25273 **
25274 ** Tests an argument to see whether it could be a parameter.
25275 ** Qualifiers start with "-" or "/", or are built as qual=value where
25276 ** "qual" is a known qualifier.
25277 ** Parameters are any other text.
25278 **
25279 ** @param [r] arg [const char*] Argument
25280 ** @param [w] param [AjPStr*] Parameter text copied on success
25281 ** @param [w] iparam [ajint*] Parameter number incremented on success
25282 ** @param [w] acd [AcdPAcd*] ACD item for the current parameter
25283 ** @return [AjBool] ajTrue if "arg" could be a parameter
25284 **         ajFalse if it appears to be a qualifier (starts with "-" and
25285 **         ends with a name)
25286 **
25287 ** @release 1.0.0
25288 ** @@
25289 ******************************************************************************/
25290 
acdIsParam(const char * arg,AjPStr * param,ajint * iparam,AcdPAcd * acd)25291 static AjBool acdIsParam(const char* arg, AjPStr* param, ajint* iparam,
25292 			 AcdPAcd* acd)
25293 {
25294     const char *cp;
25295 
25296     cp = arg;
25297 
25298     acdLog("acdIsParam arg: '%s' param: '%S' iparam: %d\n",
25299 	   arg, *param, *iparam);
25300 
25301     if(*iparam >= acdNParam)		/* test acdc-toomanyparam */
25302     {
25303 	ajErr("Argument '%s' : Too many parameters %d/%d",
25304 	      arg, (*iparam), acdNParam);
25305 	ajExitBad();
25306     }
25307 
25308     (*iparam)++;
25309     *acd = acdFindParam(*iparam);
25310 
25311     if(!*cp)                                    /* missing value */
25312     {
25313 	ajStrAssignClear(param);		/* clear the parameter */
25314 
25315 	return ajTrue;
25316     }
25317 
25318     ajStrAssignC(param, arg);		/* copy the argument value */
25319     if(*acd)
25320     {
25321 	if((*acd)->AssocQuals)
25322 	{
25323 	    acdLog("acdMasterQual [param] set to -%S\n", (*acd)->Name);
25324 	    acdMasterQual = *acd;
25325 	}
25326 	else if(acdMasterQual)
25327 	{
25328 	    acdLog("acdMasterQual cleared, was -%S\n", acdMasterQual->Name);
25329 	    acdMasterQual = NULL;
25330 	}
25331 
25332 	return ajTrue;
25333     }
25334 
25335     return ajFalse;
25336 }
25337 
25338 
25339 
25340 
25341 /* @funcstatic acdIsQual ******************************************************
25342 **
25343 ** Tests an argument to see whether it is a qualifier
25344 ** Qualifiers start with "-".
25345 ** Qualifiers are assumed to take a value, which is either
25346 ** delimited by an "=" sign or is the next argument.
25347 ** Qualifiers can also have a numbered suffix if matching one of the parameters
25348 ** or a specific master qualifier as a suffix after an underscore.
25349 **
25350 ** @param [r] arg [const char*] Argument
25351 ** @param [r] arg2 [const char*] Next argument
25352 ** @param [w] iparam [ajint*] Parameter number
25353 ** @param [w] pqual [AjPStr*] Qualifier name copied on success
25354 ** @param [w] pnoqual [AjPStr*] Qualifier name with possible 'no' prefix
25355 ** @param [w] pvalue [AjPStr*] Qualifier value copied on success
25356 ** @param [w] number [ajint*] Qualifier number
25357 ** @param [w] pmaster [AjPStr*] Named master qualifier
25358 ** @param [w] acd [AcdPAcd*] Qualifier data
25359 ** @return [ajint] Number of arguments consumed
25360 **
25361 ** @release 1.0.0
25362 ** @@
25363 ******************************************************************************/
25364 
acdIsQual(const char * arg,const char * arg2,ajint * iparam,AjPStr * pqual,AjPStr * pnoqual,AjPStr * pvalue,ajint * number,AjPStr * pmaster,AcdPAcd * acd)25365 static ajint acdIsQual(const char* arg, const char* arg2,
25366 		       ajint *iparam, AjPStr *pqual, AjPStr *pnoqual,
25367 		       AjPStr *pvalue, ajint* number, AjPStr *pmaster,
25368 		       AcdPAcd* acd)
25369 {
25370     ajint ret=0;
25371     const char *cp;
25372     ajlong i;
25373     AjBool gotvalue  = ajFalse;
25374     AjBool ismissing = ajFalse;
25375     AjBool qstart    = ajFalse;
25376     AjBool nullok    = ajFalse;
25377     AjBool attrok    = ajFalse;
25378     AjPStr noqual  = NULL;
25379 
25380     acdLog("acdIsQual '%s' '%s'\n", arg, arg2);
25381     cp = arg;
25382     *number = 0;
25383     *acd = NULL;
25384 
25385     ajStrDel(pmaster);
25386 
25387     if(!strcmp(cp, "-"))	       /* stdin or stdout parameter */
25388 	return 0;
25389     if(!*cp)                           /* dummy parameter */
25390 	return 0;
25391 
25392     if(!strcmp(cp, "--"))	       /* special -- to turn off processing */
25393     {
25394 /*	acdQualTestSkip = ajTrue; */
25395 	return 0;
25396     }
25397 
25398     if(*cp && strchr("-/", *cp))   /* first character vs. qualifier starts */
25399     {
25400 	cp++;
25401 	qstart = ajTrue;
25402 
25403 	if(*cp == '-')   /* allow --qualifier */
25404 	{
25405 	    cp++;
25406 	}
25407     }
25408 
25409     ajStrAssignClear(pqual);
25410     ajStrAssignClear(pnoqual);
25411 
25412     if(!*cp)
25413 	return 0;
25414 
25415     /* qualifier: now play hunt the value */
25416 
25417     ret = 1;
25418     ajStrAssignC(pqual, cp);      /* qualifier with '-' or '/' removed */
25419 
25420     /*
25421      ** pqual could be
25422      ** qualname (unless boolean, look for next arg as the value)
25423      ** qualname=value (value as part of arg)
25424      ** noqualname (boolean negative, or nullok set to empty string
25425      */
25426 
25427     /*
25428      ** First check whether we have a value (set gotvalue) in the first arg
25429      */
25430 
25431     i = ajStrFindC(*pqual, "=");
25432 
25433     if(i >= 0)
25434     {
25435         if((i+1) == (ajint) ajStrGetLen(*pqual)) /* ended with '=' */
25436             ajStrAssignC(pvalue, "");
25437         else
25438             ajStrAssignSubS(pvalue, *pqual, (i+1), -1);
25439 
25440 	acdLog("qualifier value '%S' '%S' %d .. %d\n",
25441 	       *pvalue, *pqual, (i+1), -1);
25442 	ajStrKeepRange(pqual, 0, (i-1));
25443 	gotvalue = ajTrue;
25444     }
25445     else
25446     {
25447 	if(!qstart)	/* no start, no "=" assume it's a parameter */
25448 	    return 0;
25449 	if(!ajStrIsAlnum(*pqual))	/* funny characters, fail */
25450 	    return 0;
25451     }
25452 
25453     acdQualParse(pqual, &noqual, pmaster, number);
25454 
25455     if(ajStrGetLen(*pmaster)) /* specific master, turn off auto processing */
25456 	acdMasterQual = NULL; /* pmaster resets this in acdFindQualDetail  */
25457 
25458     if(acdMasterQual)	      /* we are still working with a master */
25459     {
25460 	acdLog("(a) master, try associated with acdFindQualAssoc\n");
25461 	*acd = acdFindQualAssoc(acdMasterQual, *pqual, noqual, *pmaster,
25462                                 *number);
25463 
25464 	if(!*acd)
25465 	{
25466 	    acdLog("acdMasterQual cleared, was -%S\n", acdMasterQual->Name);
25467 	    acdMasterQual = NULL;
25468 	}
25469 	else
25470 	{
25471 	    *number = acdMasterQual->PNum;
25472 	    acdLog("Qualifier -%S associated with -%S\n",
25473 		   *pqual, acdMasterQual->Name);
25474 	}
25475     }
25476 
25477     if(!acdMasterQual)
25478     {
25479 	acdLog("(b) no master, general test with acdFindQualDetail\n");
25480 	*acd = acdFindQualDetail(*pqual, noqual, *pmaster, *number, iparam);
25481     }
25482 
25483     if(!*acd)				/* test acdc-badqual */
25484 	ajDie("Unknown qualifier %s", arg);
25485 
25486     ajStrAssignS(pqual, (*acd)->Name);
25487     ajStrAssignS(pnoqual, (*acd)->Name);
25488 
25489     if((*acd)->AssocQuals)		/* this one is a new master */
25490     {
25491 	acdLog("acdMasterQual set to -%S\n", (*acd)->Name);
25492 	acdMasterQual = *acd;
25493     }
25494 
25495     if(gotvalue)
25496     {
25497 	/* test acdc-noprefixvalue */
25498 	if(ajStrPrefixS((*acd)->Name, noqual))
25499 	    ajDie("'no' prefix used with value for '%s'", arg);
25500     }
25501     else
25502     {
25503 	acdLog("testing for a value\n");
25504 
25505 	/*
25506 	 ** Bool qualifiers can have no value
25507 	 ** or can be followed by a valid Bool value
25508 	 */
25509 
25510 	if(ajStrPrefixS((*acd)->Name, noqual))
25511 	{			       /* we have a -noqual matched */
25512 	    acdLog("we matched with -no\n");
25513 	    ajStrAssignC(pnoqual, "no");
25514 	    ajStrAppendS(pnoqual, (*acd)->Name);
25515 
25516 	    if(!strcmp(acdType[acdListCurr->Type].Name, "boolean") ||
25517 	       !strcmp(acdType[acdListCurr->Type].Name, "toggle"))
25518 	    {
25519 		acdLog("-no%S=N boolean or toggle accepted\n", noqual);
25520 		gotvalue = ajTrue;
25521 		ret = 1;
25522 		ajStrAssignC(pvalue, "N");
25523 		ajStrDel(&noqual);
25524 
25525 		return ret;
25526 	    }
25527 
25528 	    if(acdAttrTest(*acd, "nullok"))
25529 	    {
25530 		if(acdAttrTestValue(*acd, "nullok"))
25531 		    attrok = acdAttrToBool(*acd, /* -no for null value */
25532 					   "nullok", ajFalse, &nullok);
25533 		else			/* assume it can be true */
25534 		{
25535 		    attrok = ajTrue;
25536 		    nullok = ajTrue;
25537 		}
25538 		acdLog("check for nullok, found:%B value:%B\n",
25539 		       attrok, nullok);
25540 	    }
25541 	    else
25542 		nullok = ajFalse;
25543 
25544 	    if(nullok)
25545 	    {
25546 		acdLog("-no%S='' nullOK accepted\n", noqual);
25547 		gotvalue = ajTrue;
25548 		ret = 1;
25549                 (*acd)->UserSetNull = ajTrue;
25550 		ajStrAssignClear(pvalue);
25551 		ajStrDel(&noqual);
25552 
25553 		return ret;
25554 	    }
25555 	    else	 /* test acdc-noprefixbad acdc-noprefixbad2 */
25556 		ajDie("'no' prefix invalid for '%s'", arg);
25557 	}
25558 
25559 	/*
25560 	 ** just the qualifier name with no value
25561 	 */
25562 
25563 	if(!strcmp(acdType[acdListCurr->Type].Name, "boolean") ||
25564 	   !strcmp(acdType[acdListCurr->Type].Name, "toggle"))
25565 	{
25566 	    if(acdValIsBool(arg2))	/* bool value, accept */
25567 	    {
25568 		acdLog("acdValIsBool -%s '%s'\n", arg, arg2);
25569 		gotvalue = ajTrue;
25570 		ret = 2;
25571 		ajStrAssignC(pvalue, arg2);
25572 	    }
25573 	    else			/* we must mean true */
25574 		ajStrAssignC(pvalue, "Y");
25575 	}
25576 	else
25577 	{
25578 	    if(!arg2)			/* no value - can be missing? */
25579 	    {
25580 		ajStrToBool((*acd)->DefStr[DEF_MISSING], &ismissing);
25581 
25582 		if(!ismissing)		/* test acdc-novalue */
25583 		    ajDie("Value required for '%s'", arg);
25584 	    }
25585 	    /* test for known qualifiers */
25586 	    else
25587 	    {
25588 		if(*arg2 == '-')
25589 		{
25590 		    if(!acdTestQualC(arg2)) /* not known qualifier */
25591 			/* must be value */
25592 			gotvalue = ajTrue;
25593 		    else
25594 		    {
25595 			ajStrToBool((*acd)->DefStr[DEF_MISSING],
25596 				    &ismissing);
25597 			if(!ismissing)	/* test acdc-novalue2 */
25598 			    ajDie("Value required for '%s' before '%s'",
25599 				  arg, arg2);
25600 		    }
25601 		}
25602 		else
25603 		    gotvalue = ajTrue;
25604 	    }
25605 	    if(gotvalue)
25606 	    {
25607 		ret = 2;
25608 		ajStrAssignC(pvalue, arg2);
25609 	    }
25610 	    else
25611 		ajStrAssignClear(pvalue);
25612 	}
25613     }
25614 
25615     ajStrDel(&noqual);
25616 
25617     return ret;
25618 }
25619 
25620 
25621 
25622 
25623 /* @funcstatic acdValIsBool ***************************************************
25624 **
25625 ** Tests whether a value on the command line is a valid Boolean value
25626 **
25627 ** @param [r] arg [const char*] COmmand live argument value
25628 ** @return [AjBool] ajTrue if the value is boolean,
25629 **                  but not whether it is true or false.
25630 **
25631 ** @release 2.0.0
25632 ******************************************************************************/
25633 
acdValIsBool(const char * arg)25634 static AjBool acdValIsBool(const char* arg)
25635 {
25636     if(!arg)
25637 	return ajFalse;
25638 
25639     switch(*arg)
25640     {
25641         case 'n':
25642         case 'N':
25643             if(!arg[1])
25644                 return ajTrue;
25645             return ajCharMatchCaseC(arg, "no");
25646 
25647         case 'y':
25648         case 'Y':
25649             if(!arg[1])
25650                 return ajTrue;
25651             return ajCharMatchCaseC(arg, "yes");
25652 
25653 
25654         case 't':
25655         case 'T':
25656             if(!arg[1])
25657                 return ajTrue;
25658 
25659             return ajCharMatchCaseC(arg, "true");
25660 
25661 
25662         case 'f':
25663         case 'F':
25664             if(!arg[1])
25665                 return ajTrue;
25666 
25667             return ajCharMatchCaseC(arg, "false");
25668 
25669 
25670         case '0':
25671             if(!arg[1])
25672                 return ajTrue;
25673 
25674             return ajCharMatchCaseC(arg, "0");
25675 
25676 
25677         case '1':
25678             if(!arg[1])
25679                 return ajTrue;
25680 
25681             return ajCharMatchCaseC(arg, "1");
25682 
25683 
25684         default:
25685             break;
25686     }
25687 
25688     return ajFalse;
25689 }
25690 
25691 
25692 
25693 
25694 /* @funcstatic acdFindItem ****************************************************
25695 **
25696 ** Returns the ACD definition for a named item and
25697 ** (optionally) a given qualifier number. If the qualifier number
25698 ** is given, it is checked. If not, the first hit is used.
25699 **
25700 ** Section and Endsection do not count
25701 **
25702 ** @param [r] item [const AjPStr] Item name
25703 ** @param [r] number [ajint] Item number (zero if a general item)
25704 ** @return [AcdPAcd] ACD item required
25705 **
25706 ** @release 1.0.0
25707 ** @@
25708 ******************************************************************************/
25709 
acdFindItem(const AjPStr item,ajint number)25710 static AcdPAcd acdFindItem(const AjPStr item, ajint number)
25711 {
25712     AcdPAcd ret  = NULL;
25713     AcdPAcd pa;
25714     AjBool found = ajFalse;
25715     ajint ifound = 0;
25716     AjPStr ambigList = NULL;
25717 
25718     ambigList = ajStrNew();
25719 
25720     for(pa=acdList; pa; pa=pa->Next)
25721     {
25722 	if(acdIsStype(pa))
25723 	    continue;
25724 
25725 	found = ajFalse;
25726 	if(ajStrPrefixS(pa->Name, item))
25727 	    if(!number || number == pa->PNum)
25728 		found = ajTrue;
25729 
25730 	if(found)
25731 	{
25732 	    if(ajStrMatchS(pa->Name, item))
25733 	    {
25734 		ajStrDel(&ambigList);
25735 		return pa;
25736 	    }
25737 
25738 	    ifound++;
25739 	    ret = pa;
25740 	    acdAmbigApp(&ambigList, pa->Name);
25741 	}
25742     }
25743 
25744     if(ifound == 1)
25745     {
25746 	if (acdDoValid)
25747 	    acdWarn("Abbreviated item '%S' (%S)", item, ambigList);
25748 	ajStrDel(&ambigList);
25749 	return ret;
25750     }
25751 
25752     if(ifound > 1)
25753     {
25754 	ajWarn("ambiguous item %S (%S)", item, ambigList);
25755     }
25756 
25757     ajStrDel(&ambigList);
25758 
25759     return NULL;
25760 }
25761 
25762 
25763 
25764 
25765 /* @funcstatic acdFindQual ****************************************************
25766 **
25767 ** Finds a qualifier by name, and returns the full name
25768 **
25769 ** @param [u] pqual [AjPStr*] Qualifier name
25770 ** @return [AcdPAcd] ACD item for qualifier
25771 **
25772 ** @release 1.0.0
25773 ** @@
25774 ******************************************************************************/
25775 
acdFindQual(AjPStr * pqual)25776 static AcdPAcd acdFindQual(AjPStr *pqual)
25777 {
25778     AcdPAcd ret    = NULL;
25779     AcdPAcd pa;
25780     ajint ifound = 0;
25781     AjBool found = ajFalse;
25782 
25783     if(!ajStrGetLen(*pqual)) return NULL;
25784 
25785     for(pa=acdList; pa; pa=pa->Next)
25786     {
25787 	found = ajFalse;
25788 
25789 	if(acdIsStype(pa))
25790 	    continue;
25791 
25792 	found = ajFalse;
25793 
25794 	if(pa->Level == ACD_QUAL || pa->Level == ACD_PARAM)
25795 	{
25796 	    if(ajStrPrefixS(pa->Name, *pqual))
25797 		found = ajTrue;
25798 
25799 	    if(found)
25800 	    {
25801 		if(ajStrMatchS(pa->Name, *pqual))
25802 		    return pa;
25803 
25804 		ifound++;
25805 		ret = pa;
25806 	    }
25807 	}
25808     }
25809 
25810     if(ifound == 1)
25811     {
25812 	ajStrAssignS(pqual, ret->Name);
25813 
25814 	return ret;
25815     }
25816 
25817     return NULL;
25818 }
25819 
25820 
25821 
25822 
25823 /* @funcstatic acdFindQualDetail **********************************************
25824 **
25825 ** Returns the parameter definition for a named qualifier and
25826 ** (optionally) a given qualifier number. If the qualifier number
25827 ** is given, it is checked. If not, the current parameter number is checked.
25828 ** General qualifiers have no specified number and can match at any time.
25829 **
25830 ** @param [r] qual [const AjPStr] Qualifier name
25831 ** @param [r] noqual [const AjPStr] Alternative qualifier name
25832 **        (qual with "no" prefix removed, or empty, or NULL)
25833 ** @param [rN] master [const AjPStr] Master qualifier name
25834 ** @param [r] PNum [ajint] Qualifier number (zero if a general qualifier)
25835 ** @param [u] iparam [ajint*]  Current parameter number
25836 ** @return [AcdPAcd] ACD item for qualifier
25837 **
25838 ** @release 4.0.0
25839 ** @@
25840 ******************************************************************************/
25841 
acdFindQualDetail(const AjPStr qual,const AjPStr noqual,const AjPStr master,ajint PNum,ajint * iparam)25842 static AcdPAcd acdFindQualDetail(const AjPStr qual, const AjPStr noqual,
25843 				 const AjPStr master,
25844 				 ajint PNum, ajint *iparam)
25845 {
25846     /* test for match of parameter number and type */
25847 
25848     /* PNum : number encoded in qualifier name ==> forced match */
25849     /* iparam : current parameter number ==> possible match */
25850     /* when both are zero, could be a generic match, like "-begin" for
25851        all sequences. Just return the first and let caller find the rest */
25852 
25853     AcdPAcd ret    = NULL;
25854     AcdPAcd pa;
25855     AjBool found   = ajFalse;
25856     AjBool isparam = ajFalse;
25857     ajint ifound   = 0;
25858     AjPStr ambigList = NULL;
25859 
25860     if(ajStrGetLen(master))
25861     {
25862         acdLog("acdFindQualDetail ... call acdFindQualMaster\n",
25863 	   qual, noqual, PNum, *iparam);
25864 
25865 	*iparam = 0;
25866 	return acdFindQualMaster(qual, noqual, master, PNum);
25867     }
25868 
25869     ambigList = ajStrNew();
25870 
25871     acdLog("acdFindQualDetail '%S' (%S) PNum: %d iparam: %d\n",
25872 	   qual, noqual, PNum, *iparam);
25873 
25874     for(pa=acdList; pa; pa=pa->Next)
25875     {
25876 	if(acdIsStype(pa))
25877 	    continue;
25878 
25879 	found = ajFalse;
25880 	if(pa->Level == ACD_QUAL)
25881 	{
25882 	    if(ajStrPrefixS(pa->Name, qual) ||
25883 	       ajStrPrefixS(pa->Name, noqual))
25884 	    {
25885 		acdLog("..matched qualifier '%S' [%d]\n", pa->Name, pa->PNum);
25886 		if(PNum)	      /* -begin2 forces match to #2 */
25887 		{
25888 		    if(PNum == pa->PNum)
25889 		    {
25890 			acdLog("..matched PNum '%S' [%d]\n",
25891 			       pa->Name, pa->PNum);
25892 			found = ajTrue;
25893 		    }
25894 		}
25895 		else if(pa->PNum) /* defined for parameter pa->PNum */
25896 		{
25897 		    acdLog("..hit PNum '%S' [%d] (ambigList '%S')\n",
25898 			   pa->Name, pa->PNum, ambigList);
25899 		    if(!ifound  || !ajStrMatchS(pa->Name, ambigList))
25900 			found = ajTrue;
25901 		}
25902 		else			/* general match */
25903 		    found = ajTrue;
25904 
25905 		if(found)
25906 		{
25907 		    if(ajStrMatchS(pa->Name, qual) ||
25908 		       ajStrMatchS(pa->Name, noqual))
25909 		    {
25910 			acdListCurr = pa;
25911 			ajStrDel(&ambigList);
25912 			return pa;
25913 		    }
25914 
25915 		    acdAmbigApp(&ambigList, pa->Name);
25916 		    ifound++;
25917 		    ret = pa;
25918 		    acdLog("..prefix only '%S', ifound %d\n",
25919 			   pa->Name, ifound);
25920 		}
25921 	    }
25922 	}
25923 	else if(pa->Level == ACD_PARAM)
25924 	{
25925 	    if(ajStrPrefixS(pa->Name, qual) ||
25926 	       ajStrPrefixS(pa->Name, noqual))
25927 	    {
25928 		acdLog("..matched param '%S' [%d]\n", pa->Name, pa->PNum);
25929 		if(ajStrMatchS(pa->Name, qual) ||
25930 		   ajStrMatchS(pa->Name, noqual))
25931 		{
25932 		    acdListCurr = pa;
25933 		    *iparam = pa->PNum;
25934 		    ajStrDel(&ambigList);
25935 		    return pa;
25936 		}
25937 
25938 		acdAmbigApp(&ambigList, pa->Name);
25939 		ifound++;
25940 		isparam = ajTrue;
25941 		ret = pa;
25942 		acdLog("..prefix only '%S', ifound %d\n", pa->Name, ifound);
25943 	    }
25944 	}
25945     }
25946 
25947     if(ifound == 1)
25948     {
25949 	acdListCurr = ret;
25950 
25951 	if(isparam)
25952 	    *iparam = ret->PNum;
25953 
25954 	if (acdDoValid)
25955 	    acdWarn("Abbreviated qualifier '%S' (%S)", qual, ambigList);
25956 
25957 	ajStrDel(&ambigList);
25958 	return ret;
25959     }
25960 
25961     if(ifound > 1)
25962     {
25963 	ajWarn("ambiguous qualifier '%S' (%S)", qual, ambigList);
25964     }
25965 
25966     ajStrDel(&ambigList);
25967 
25968     return NULL;
25969 }
25970 
25971 
25972 
25973 
25974 /* @funcstatic acdFindQualMaster **********************************************
25975 **
25976 ** Returns the parameter definition for a named qualifier and
25977 ** (optionally) a given qualifier number. If the qualifier number
25978 ** is given, it is checked. If not, the current parameter number is checked.
25979 ** General qualifiers have no specified number and can match at any time.
25980 **
25981 ** @param [r] qual [const AjPStr] Qualifier name
25982 ** @param [r] noqual [const AjPStr] Alternative qualifier name
25983 **        (qual with "no" prefix removed, or empty, or NULL)
25984 ** @param [rN] master [const AjPStr] Master qualifier name
25985 ** @param [r] PNum [ajint] Qualifier number (zero if a general qualifier)
25986 ** @return [AcdPAcd] ACD item for qualifier
25987 **
25988 ** @release 1.0.0
25989 ** @@
25990 ******************************************************************************/
25991 
acdFindQualMaster(const AjPStr qual,const AjPStr noqual,const AjPStr master,ajint PNum)25992 static AcdPAcd acdFindQualMaster(const AjPStr qual, const AjPStr noqual,
25993 				 const AjPStr master,
25994 				 ajint PNum)
25995 {
25996     /* test for match of parameter number and type */
25997 
25998     /*
25999      ** PNum : number encoded in qualifier name ==> forced match
26000      ** iparam : current parameter number ==> possible match
26001      ** when both are zero, could be a generic match, like "-begin" for
26002      ** all sequences. Just return the first and let caller find the rest
26003      */
26004 
26005     AcdPAcd ret  = NULL;
26006     AcdPAcd pa;
26007     AjBool found = ajFalse;
26008     ajint ifound  =0;
26009     AjPStr ambigList = NULL;
26010 
26011     ambigList = ajStrNew();
26012 
26013     acdLog("acdFindQualMaster '%S_%S' (%S) PNum: %d\n",
26014 	   qual, master, noqual, PNum);
26015 
26016     for(pa=acdList; pa; pa=pa->Next)
26017     {
26018 	if(acdIsStype(pa))
26019 	    continue;
26020 
26021 	found = ajFalse;
26022 
26023 	if(pa->Level == ACD_QUAL)
26024 	{
26025 	    if(ajStrPrefixS(pa->Name, master))
26026 	    {
26027 		acdLog("..matched qualifier '%S' [%d]\n", pa->Name, pa->PNum);
26028 		if(PNum)	      /* -begin2 forces match to #2 */
26029 		{
26030 		    if(PNum == pa->PNum)
26031 		    {
26032 			acdLog("..matched PNum '%S' [%d]\n",
26033 			       pa->Name, pa->PNum);
26034 			found = ajTrue;
26035 		    }
26036 		}
26037 		else if(pa->PNum) /* defined for parameter pa->PNum */
26038 		{
26039 		    acdLog("..hit PNum '%S' [%d] (ambigList '%S')\n",
26040 			   pa->Name, pa->PNum, ambigList);
26041 		    if(!ifound  || !ajStrMatchS(pa->Name, ambigList))
26042 			found = ajTrue;
26043 		}
26044 		else			/* general match */
26045 		    found = ajTrue;
26046 
26047 		if(found)
26048 		{
26049 		    if(ajStrMatchS(pa->Name, master))
26050 		    {
26051 			ret = pa;
26052 			ifound = 1;
26053 			break;
26054 		    }
26055 		    acdAmbigApp(&ambigList, pa->Name);
26056 		    ifound++;
26057 		    ret = pa;
26058 		    acdLog("..prefix only, ifound %d\n", ifound);
26059 		}
26060 	    }
26061 	}
26062 	else if(pa->Level == ACD_PARAM)
26063 	{
26064 	    if(ajStrPrefixS(pa->Name, master))
26065 	    {
26066 		acdLog("..matched param '%S' [%d]\n", pa->Name, pa->PNum);
26067 
26068 		if(ajStrMatchS(pa->Name, master))
26069 		{
26070 		    ret = pa;
26071 		    ifound = 1;
26072 		    break;
26073 		}
26074 		acdAmbigApp(&ambigList, pa->Name);
26075 		ifound++;
26076 		ret = pa;
26077 		acdLog("..prefix only, ifound %d\n", ifound);
26078 	    }
26079 	}
26080     }
26081 
26082     if(ifound > 1)
26083     {
26084 	acdLog("..ambiguous master qualifier for %S_%S (%S)",
26085 	       qual, master, ambigList);
26086 	ajWarn("Ambiguous master qualifier '%S' in %S_%S (%S)",
26087 	       master, qual, master, ambigList);
26088 	ajStrDel(&ambigList);
26089 
26090 	return NULL;
26091     }
26092 
26093     if(!ifound)
26094     {
26095 	acdLog("..master qualifier for %S_%S not found\n", qual, master);
26096 	ajStrDel(&ambigList);
26097 	return NULL;
26098     }
26099 
26100     acdLog("..master qualifier found '%S' %d\n", ret->Name, ret->PNum);
26101 
26102     ifound = 0;
26103 
26104     for(pa=ret->AssocQuals; pa && pa->Assoc; pa=pa->Next)
26105     {
26106 	found = ajFalse;
26107 	if(ajStrPrefixS(pa->Name, qual) ||
26108 	   ajStrPrefixS(pa->Name, noqual))
26109 	{
26110 	    acdLog("..matched qualifier '%S' [%d]\n", pa->Name, pa->PNum);
26111 	    if(PNum)		      /* -begin2 forces match to #2 */
26112 	    {
26113 		if(PNum == pa->PNum)
26114 		{
26115 		    acdLog("..matched PNum '%S' [%d]\n",
26116 			   pa->Name, pa->PNum);
26117 		    found = ajTrue;
26118 		}
26119 	    }
26120 	    else if(pa->PNum)	  /* defined for parameter pa->PNum */
26121 	    {
26122 		acdLog("..hit PNum '%S' [%d] (ambigList '%S')\n",
26123 		       pa->Name, pa->PNum, ambigList);
26124 		if(!ifound  || !ajStrMatchS(pa->Name, ambigList))
26125 		{
26126 		    found = ajTrue;
26127 		}
26128 	    }
26129 	    else			/* general match */
26130 		found = ajTrue;
26131 
26132 	    if(found)
26133 	    {
26134 		if(ajStrMatchS(pa->Name, qual) ||
26135 		   ajStrMatchS(pa->Name, noqual))
26136 		{
26137 		    acdListCurr = pa;
26138 		    ajStrDel(&ambigList);
26139 		    return pa;
26140 		}
26141 
26142 		acdAmbigApp(&ambigList, pa->Name);
26143 		ifound++;
26144 		ret = pa;
26145 		acdLog("..prefix only, ifound %d\n", ifound);
26146 	    }
26147 	}
26148     }
26149 
26150     if(ifound == 1)
26151     {
26152 	acdListCurr = ret;
26153 	if (acdDoValid)
26154 	    acdWarn("Abbreviated associated qualifier '%S_%S' (%S)",
26155 		    qual, master, ambigList);
26156 	ajStrDel(&ambigList);
26157 	return ret;
26158     }
26159 
26160     if(ifound > 1)
26161     {
26162 	acdLog("..ambiguous associated qualifier %S_%S (%S)",
26163 	       qual, master, ambigList);
26164 	ajWarn("ambiguous associated qualifier %S_%S (%S)",
26165 	       qual, master, ambigList);
26166     }
26167 
26168     ajStrDel(&ambigList);
26169 
26170     acdLog("..associated qualifier %S_%S not found", qual, master);
26171 
26172     return NULL;
26173 }
26174 
26175 
26176 
26177 
26178 /* @funcstatic acdFindQualAssoc ***********************************************
26179 **
26180 ** Returns the definition for a named associated qualifier.
26181 ** If the qualifier number
26182 ** is given, it is checked. If not, the current parameter number is checked.
26183 ** General qualifiers have no specified number and can match at any time.
26184 **
26185 ** @param [r] thys [const AcdPAcd] Master ACD item
26186 ** @param [r] qual [const AjPStr] Qualifier name
26187 ** @param [r] noqual [const AjPStr] Alternative qualifier name
26188 **        (qual with "no" prefix removed, or empty, or NULL)
26189 ** @param [rN] master [const AjPStr] Master qualifier name
26190 ** @param [r] PNum [ajint] Qualifier number (zero if a general qualifier)
26191 ** @return [AcdPAcd] ACD item for associated qualifier
26192 ** @error NULL returned if not found.
26193 **
26194 ** @release 1.0.0
26195 ** @@
26196 ******************************************************************************/
26197 
acdFindQualAssoc(const AcdPAcd thys,const AjPStr qual,const AjPStr noqual,const AjPStr master,ajint PNum)26198 static AcdPAcd acdFindQualAssoc(const AcdPAcd thys,
26199 				const AjPStr qual, const AjPStr noqual,
26200 				const AjPStr master,
26201 				ajint PNum)
26202 {
26203     /* test for match of parameter number and type */
26204 
26205     /*
26206      **  PNum : number encoded in qualifier name ==> forced match
26207      ** iparam : current parameter number ==> possible match
26208      ** when both are zero, could be a generic match, like "-sbegin" for
26209      ** all sequences. Just return the first and let caller find the rest
26210      */
26211 
26212     AcdPAcd pa   = thys->AssocQuals;
26213     ajint ifound = 0;
26214     AcdPAcd ret  = NULL;
26215     AjPStr ambigList = NULL;
26216     ajint iparam;
26217 
26218     /* acdLog("acdFindQualAssoc '%S' pnum: %d\n", qual, pnum); */
26219 
26220     if(PNum  && (pa->PNum != PNum)) /* must be for same number (if any) */
26221 	return NULL;
26222 
26223     ambigList = ajStrNew();
26224 
26225     for(; pa && pa->Assoc; pa=pa->Next)
26226     {
26227 	if(ajStrPrefixS(pa->Name, qual) ||
26228 	   ajStrPrefixS(pa->Name, noqual))
26229 	{
26230 	    if(ajStrMatchS(pa->Name, qual) ||
26231 	       ajStrMatchS(pa->Name, noqual))
26232 	    {
26233 		/* acdLog("   *matched* '%S'\n", pa->Name); */
26234 		acdListCurr = pa;
26235 		ajStrDel(&ambigList);
26236 		return acdListCurr;
26237 	    }
26238 
26239 	    ifound++;
26240 	    ret = pa;
26241 	    acdAmbigApp(&ambigList, pa->Name);
26242 	}
26243     }
26244 
26245     /* acdLog("   ifound: %d\n", ifound); */
26246 
26247     if(ifound == 1)
26248     {
26249 	acdListCurr = ret;
26250 
26251         pa = acdFindQualDetail(qual,noqual,master,PNum, &iparam);
26252 
26253         if(pa == ret)
26254         {
26255             if (acdDoValid)
26256                 acdWarn("Abbreviated associated qualifier '%S' (%S)",
26257                         qual, ambigList);
26258 
26259             ajStrDel(&ambigList);
26260 
26261             return acdListCurr;
26262         }
26263     }
26264 
26265     if(ifound > 1)
26266 	ajWarn("ambiguous qualifier %S (%S)", qual, ambigList);
26267 
26268     ajStrDel(&ambigList);
26269 
26270     return NULL;
26271 }
26272 
26273 
26274 
26275 
26276 /* @funcstatic acdFindParam ***************************************************
26277 **
26278 ** Returns the paremeter definition for a given parameter number
26279 **
26280 ** @param [r] PNum [ajint] Parameter number
26281 ** @return [AcdPAcd] ACD item for parameter number PNum
26282 ** @error NULL if not found
26283 **
26284 ** @release 1.0.0
26285 ** @@
26286 ******************************************************************************/
26287 
acdFindParam(ajint PNum)26288 static AcdPAcd acdFindParam(ajint PNum)
26289 {
26290     /* test for match of parameter number and type */
26291 
26292     AcdPAcd pa;
26293 
26294     for(pa=acdList; pa; pa=pa->Next)
26295     {
26296 	if(acdIsStype(pa))
26297             continue;
26298 
26299 	if((pa->Level == ACD_PARAM) && (pa->PNum == PNum))
26300 	{
26301 	    acdListCurr = pa;
26302 	    return pa;
26303 	}
26304     }
26305 
26306     return NULL;
26307 }
26308 
26309 
26310 
26311 
26312 /* @funcstatic acdGetAttr *****************************************************
26313 **
26314 ** Pick up a defined attribute for variable handling.
26315 ** The ACD item must be defined (already processed).
26316 ** Attributes include any specially calculated by the acdSet function
26317 ** for that type.
26318 **
26319 ** @param [u] presult [AjPStr*] Resulting attribute value
26320 ** @param [r] name [const AjPStr] ACD item name
26321 ** @param [r] attrib [const AjPStr] attribute name
26322 ** @return [AjBool] ajTrue on success
26323 **
26324 ** @release 1.0.0
26325 ** @@
26326 ******************************************************************************/
26327 
acdGetAttr(AjPStr * presult,const AjPStr name,const AjPStr attrib)26328 static AjBool acdGetAttr(AjPStr* presult,
26329 			 const AjPStr name, const AjPStr attrib)
26330 {
26331     const char *cp;
26332     const char *cq;
26333     ajint ilen;
26334     ajint number = 0;
26335 
26336     AjPStr tempstr=NULL;
26337 
26338     AcdPAcd pa    = NULL;
26339     AcdPAttr attr = NULL;
26340     ajint i;
26341 
26342     acdLog("acdGetAttr name '%S' attrib '%S'\n", name, attrib);
26343     ajStrDelStatic(presult);
26344 
26345     ajStrAssignS(&tempstr, name);
26346     ajStrFmtLower(&tempstr);
26347     cp = ajStrGetPtr(tempstr);
26348     cq = &cp[ajStrGetLen(tempstr)];
26349 
26350     if(isdigit((ajint)*--cq))
26351     {
26352 	while(isdigit((ajint)*--cq));
26353 	++cq;
26354 
26355 	number = (ajint) strtol(cq, NULL, 0);
26356 	ilen = cq - cp - 1;
26357 	ajStrKeepRange(&tempstr, 0, ilen);
26358     }
26359 
26360     pa = acdFindItem(tempstr, number);
26361 
26362     if(!pa)				/* test ambigvar.acd */
26363 	acdError("Failed to resolve variable '%S'\n", name);
26364 
26365     ajStrDel(&tempstr);
26366 
26367     if(!pa->ValStr)
26368     {
26369 	if (!acdDoValid && !acdDoGalaxy)
26370 	{
26371 	    if(!acdDoHelp)			/* test undefvar.acd */
26372 		acdError("Variable '%S' not yet defined\n", name);
26373 
26374             acdAttrValueStr(pa, "default", "...", presult);
26375 
26376 	    return ajTrue;
26377 	}
26378     }
26379 
26380     if(!ajStrGetLen(attrib))		/* just use valstr */
26381     {
26382 	if (!acdDoValid && !acdDoGalaxy)
26383 	{
26384 	    ajStrAssignS(presult, pa->ValStr);
26385 	    acdLog("no attribute name, use valstr for %S '%S'\n",
26386 		   pa->Name, *presult);
26387 	    pa->Used |= USED_ACD;
26388 
26389 	    return ajTrue;
26390 	}
26391     }
26392 
26393     if(pa->DefStr)
26394     {
26395 	attr = acdAttrDef;
26396 	i = acdFindAttr(attr, attrib);
26397 
26398 	if(i >= 0)
26399 	{
26400 	    ajStrAssignS(presult, pa->DefStr[i]);
26401 	    acdLog("default attribute %S found for %S '%S'\n",
26402 		   attrib, pa->Name, *presult);
26403 
26404 	    return ajTrue;
26405 	}
26406     }
26407 
26408     if(pa->NAttr)
26409     {
26410 	attr = acdType[pa->Type].Attr;
26411 	i = acdFindAttr(attr, attrib);
26412 
26413 	if(i >= 0)
26414 	{
26415 	    ajStrAssignS(presult, pa->AttrStr[i]);
26416 	    acdLog("type attribute %S found for %S '%S'\n",
26417 		   attrib, pa->Name, *presult);
26418 
26419 	    return ajTrue;
26420 	}
26421     }
26422 
26423     if(pa->SAttr)
26424     {
26425 	acdLog("++calc++ Testing SAttr %d\n", pa->SAttr);
26426 	attr = pa->SetAttr;
26427 
26428 	for(i=0; i < pa->SAttr; i++)
26429 	    acdLog("calcattr[%d] '%s'\n",
26430 		   i, attr[i].Name);
26431 	i = acdFindAttr(attr, attrib);
26432 
26433 	if(i >= 0)
26434 	{
26435 	    ajStrAssignS(presult, pa->SetStr[i]);
26436 	    acdLog("calculated attribute %S found for %S '%S'\n",
26437 		   attrib, pa->Name, *presult);
26438 
26439 	    return ajTrue;
26440 	}
26441     }
26442 
26443     if(ajStrMatchCaseC(attrib, "isdefined"))
26444     {
26445 	acdLog("++isdefined++ Testing\n");
26446 
26447 	if (ajStrGetLen(pa->ValStr))
26448 	{
26449 	    ajStrAssignC(presult, "Y");
26450 	}
26451 	else
26452 	{
26453 	    ajStrAssignC(presult, "N");
26454 	}
26455 	acdLog("isdefined attribute found for %S '%S'\n",
26456 	       pa->Name, *presult);
26457 
26458 	return ajTrue;
26459     }
26460 
26461     acdLog("*attribute %S not found for %S*\n", attrib, pa->Name);
26462 
26463     return ajFalse;
26464 }
26465 
26466 
26467 
26468 
26469 /* @funcstatic acdQualParse ***************************************************
26470 **
26471 ** Converts a qualifier name to lower case and looks for a
26472 ** master qualifier name and a trailing number.
26473 **
26474 ** @param [w] pqual [AjPStr*] Qualifier name set to lower case
26475 **        with number suffix removed
26476 ** @param [w] pnoqual [AjPStr*] Qualifier name as pqual, with "no" prefix
26477 **        removed, or empty string id pqual doesn't start with "no"
26478 ** @param [w] pqmaster [AjPStr*] Master name for associated qualifier
26479 ** @param [w] number [ajint*] Qualifier number suffix if any
26480 ** @return [void]
26481 **
26482 ** @release 1.0.0
26483 ** @@
26484 ******************************************************************************/
26485 
acdQualParse(AjPStr * pqual,AjPStr * pnoqual,AjPStr * pqmaster,ajint * number)26486 static void acdQualParse(AjPStr* pqual, AjPStr* pnoqual, AjPStr* pqmaster,
26487 			 ajint* number)
26488 {
26489     if(!acdRegQualParse)
26490 	acdRegQualParse = ajRegCompC("^([a-z]+)(_([a-z]+))?([0-9]+)?$");
26491 
26492     ajStrFmtLower(pqual);
26493     ajStrAssignS(&acdQualNameTmp, *pqual);
26494 
26495     if(!ajRegExec(acdRegQualParse, acdQualNameTmp))
26496     {
26497 	ajStrAssignClear(pqual);
26498 	ajStrAssignClear(pnoqual);
26499 	ajStrAssignClear(pqmaster);
26500 	*number = 0;
26501 
26502 	return;
26503     }
26504     ajRegSubI(acdRegQualParse, 1, pqual);
26505     ajRegSubI(acdRegQualParse, 3, pqmaster);
26506     ajRegSubI(acdRegQualParse, 4, &acdQualNumTmp);
26507 
26508     if(ajStrPrefixC(*pqual, "no"))
26509 	ajStrAssignSubS(pnoqual, *pqual, 2, -1);
26510     else
26511 	ajStrAssignClear(pnoqual);
26512 
26513     *number = 0;
26514 
26515     if(ajStrGetLen(acdQualNumTmp))
26516 	ajStrToInt(acdQualNumTmp, number);
26517 
26518     if(ajStrGetLen(*pqmaster))
26519 	acdFindQual(pqmaster);
26520 
26521     return;
26522 }
26523 
26524 
26525 
26526 
26527 /* @funcstatic acdTokenToLowerS ***********************************************
26528 **
26529 ** Converts a token name to lower case and looks for a trailing number.
26530 **
26531 ** @param [u] ptoken [AjPStr*] Qualifier name set to lower case
26532 **        with number suffix removed
26533 ** @param [w] number [ajint*] Qualifier number suffix if any.
26534 ** @return [void]
26535 **
26536 ** @release 4.0.0
26537 ** @@
26538 ******************************************************************************/
26539 
acdTokenToLowerS(AjPStr * ptoken,ajint * number)26540 static void acdTokenToLowerS(AjPStr *ptoken, ajint* number)
26541 {
26542     const char *cp;
26543     const char *cq;
26544     ajint ilen;
26545 
26546     ajStrFmtLower(ptoken);
26547     cp = ajStrGetPtr(*ptoken);
26548     cq = cp+ajStrGetLen(*ptoken);
26549 
26550     if(!isdigit((ajint)*--cq))
26551     {
26552         *number = 0;
26553 
26554         return;
26555     }
26556 
26557     while(isdigit((ajint)*--cq))
26558 	;
26559 
26560     ++cq;
26561 
26562     *number = (ajint) strtol(cq, NULL, 0);
26563     ilen = cq - cp;
26564     ajStrCutEnd(ptoken, ajStrGetLen(*ptoken) - ilen);
26565 
26566     return;
26567 }
26568 
26569 
26570 
26571 
26572 /* @funcstatic acdIsRequired **************************************************
26573 **
26574 ** Returns true if an ACD item is required but not yet defined.
26575 ** Required means the standard attribute is set (which it is by
26576 ** default for a parameter),
26577 ** or the additional flag is set and -options was specified.
26578 **
26579 ** @param [r] thys [const AcdPAcd] ACD item
26580 ** @return [AjBool] ajTrue if "thys" is required but no value set yet.
26581 **
26582 ** @release 1.0.0
26583 ** @@
26584 ******************************************************************************/
26585 
acdIsRequired(const AcdPAcd thys)26586 static AjBool acdIsRequired(const AcdPAcd thys)
26587 {
26588     AjPStr *def     = thys->DefStr;
26589     AjBool required = ajFalse;
26590 
26591     if (thys->DefStr)
26592 	acdLog("acdIsRequired '%S' Defined %B DefStr '%x' std '%S' "
26593                "add '%S' def '%S'\n",
26594 	       thys->Name,
26595 	       thys->Defined,
26596 	       thys->DefStr,
26597 	       def[DEF_STANDARD],
26598 	       def[DEF_ADDITIONAL],
26599 	       def[DEF_DEFAULT]);
26600     else
26601     	acdLog("acdIsRequired '%S' Defined %B\n",
26602 	       thys->Name,
26603 	       thys->Defined);
26604 
26605     if(thys->Defined)
26606 	return ajFalse;
26607 
26608     if(!thys->DefStr)
26609 	return ajFalse;
26610 
26611     if(ajStrGetLen(def[DEF_STANDARD]))
26612     {
26613 	acdVarResolve(&def[DEF_STANDARD]);
26614 
26615 	if(!ajStrToBool(def[DEF_STANDARD], &required))
26616 	    acdErrorAcd(thys, "Bad standard flag %S\n",
26617 			def[DEF_STANDARD]);
26618 	return required;
26619     }
26620 
26621     if(acdOptions && ajStrGetLen(def[DEF_ADDITIONAL]))
26622     {
26623 	acdVarResolve(&def[DEF_ADDITIONAL]);
26624 
26625 	if(!ajStrToBool(def[DEF_ADDITIONAL], &required))
26626 	    acdErrorAcd(thys, "Bad additional flag %S\n",
26627 			def[DEF_ADDITIONAL]);
26628 	return required;
26629     }
26630 
26631     return ajFalse;
26632 }
26633 
26634 
26635 
26636 
26637 /* @funcstatic acdPromptCodon *************************************************
26638 **
26639 ** Sets the default prompt for this ACD object to be a codon usage file
26640 **
26641 ** @param [u] thys [AcdPAcd] Current ACD object.
26642 ** @return [const AjPStr] Generated standard prompt
26643 **
26644 ** @release 1.0.0
26645 ** @@
26646 ******************************************************************************/
26647 
acdPromptCodon(AcdPAcd thys)26648 static const AjPStr acdPromptCodon(AcdPAcd thys)
26649 {
26650     static ajint count=0;
26651 
26652     const AjPStr knowntype;
26653 
26654     knowntype = acdKnowntypeDesc(thys);
26655     if(ajStrGetLen(knowntype))
26656     {
26657 	count++;
26658 	acdPromptStandardS(thys, knowntype);
26659 	if(!ajStrSuffixC(knowntype, " file"))
26660 	   acdPromptStandardAppend(thys, " file");
26661     }
26662     else
26663 	acdPromptStandard(thys, "Codon usage file", &count);
26664 
26665     if(!acdAttrTestDefined(thys, "default") &&
26666        acdAttrTestDefined(thys, "nullok"))
26667 	acdPromptStandardAppend(thys, " (optional)");
26668 
26669     return thys->StdPrompt;
26670 }
26671 
26672 
26673 
26674 
26675 /* @funcstatic acdPromptDirectory *********************************************
26676 **
26677 ** Sets the default prompt for this ACD object to be a directory
26678 **
26679 ** @param [u] thys [AcdPAcd] Current ACD object.
26680 ** @return [const AjPStr] Generated standard prompt
26681 **
26682 ** @release 4.0.0
26683 ** @@
26684 ******************************************************************************/
26685 
acdPromptDirectory(AcdPAcd thys)26686 static const AjPStr acdPromptDirectory(AcdPAcd thys)
26687 {
26688     static ajint count=0;
26689 
26690     const AjPStr knowntype;
26691 
26692     knowntype = acdKnowntypeDesc(thys);
26693     if(ajStrGetLen(knowntype))
26694     {
26695 	count++;
26696 	acdPromptStandardS(thys, knowntype);
26697 
26698 	if(!ajStrSuffixC(knowntype, " directory"))
26699 	   acdPromptStandardAppend(thys, " directory");
26700     }
26701     else
26702 	acdPromptStandard(thys, "Directory of input files", &count);
26703 
26704     if(!acdAttrTestDefined(thys, "default") &&
26705        acdAttrTestDefined(thys, "nullok"))
26706 	acdPromptStandardAppend(thys, " (optional)");
26707 
26708     return thys->StdPrompt;
26709 }
26710 
26711 
26712 
26713 
26714 /* @funcstatic acdPromptDirlist ***********************************************
26715 **
26716 ** Sets the default prompt for this ACD object to be a dirlist
26717 **
26718 ** @param [u] thys [AcdPAcd] Current ACD object.
26719 ** @return [const AjPStr] Generated standard prompt
26720 **
26721 ** @release 1.9.0
26722 ** @@
26723 ******************************************************************************/
26724 
acdPromptDirlist(AcdPAcd thys)26725 static const AjPStr acdPromptDirlist(AcdPAcd thys)
26726 {
26727     static ajint count=0;
26728 
26729     const AjPStr knowntype;
26730 
26731     knowntype = acdKnowntypeDesc(thys);
26732     if(ajStrGetLen(knowntype))
26733     {
26734 	count++;
26735 	acdPromptStandardS(thys, knowntype);
26736 
26737 	if(!ajStrSuffixC(knowntype, " directories"))
26738 	   acdPromptStandardAppend(thys, " directories");
26739     }
26740     else
26741 	acdPromptStandard(thys, "Directories with files", &count);
26742 
26743     if(!acdAttrTestDefined(thys, "default") &&
26744        acdAttrTestDefined(thys, "nullok"))
26745 	acdPromptStandardAppend(thys, " (optional)");
26746 
26747     return thys->StdPrompt;
26748 }
26749 
26750 
26751 
26752 
26753 /* @funcstatic acdPromptFilelist **********************************************
26754 **
26755 ** Sets the default prompt for this ACD object to be a filelist
26756 **
26757 ** @param [u] thys [AcdPAcd] Current ACD object.
26758 ** @return [const AjPStr] Generated standard prompt
26759 **
26760 ** @release 2.5.0
26761 ** @@
26762 ******************************************************************************/
26763 
acdPromptFilelist(AcdPAcd thys)26764 static const AjPStr acdPromptFilelist(AcdPAcd thys)
26765 {
26766     static ajint count=0;
26767 
26768     const AjPStr knowntype;
26769 
26770     knowntype = acdKnowntypeDesc(thys);
26771     if(ajStrGetLen(knowntype))
26772     {
26773 	count++;
26774 	acdPromptStandardS(thys, knowntype);
26775 
26776 	if(!ajStrSuffixC(knowntype, " file list"))
26777 	   acdPromptStandardAppend(thys, " file list");
26778     }
26779     else
26780 	acdPromptStandard(thys, "Comma-separated file list", &count);
26781 
26782     if(!acdAttrTestDefined(thys, "default") &&
26783        acdAttrTestDefined(thys, "nullok"))
26784 	acdPromptStandardAppend(thys, " (optional)");
26785 
26786     return thys->StdPrompt;
26787 }
26788 
26789 
26790 
26791 
26792 /* @funcstatic acdPromptFeatures **********************************************
26793 **
26794 ** Sets the default prompt for this ACD object to be a feature table
26795 ** prompt with "first", "second" etc. added.
26796 **
26797 ** @param [u] thys [AcdPAcd] Current ACD object.
26798 ** @return [const AjPStr] Generated standard prompt
26799 **
26800 ** @release 6.0.0
26801 ** @@
26802 ******************************************************************************/
26803 
acdPromptFeatures(AcdPAcd thys)26804 static const AjPStr acdPromptFeatures(AcdPAcd thys)
26805 {
26806     static ajint count=0;
26807 
26808     const AjPStr knowntype;
26809 
26810     ajint maxreads = 0;
26811 
26812     acdAttrToInt(thys, "maxreads", 1, &maxreads);
26813 
26814     knowntype = acdKnowntypeDesc(thys);
26815     if(ajStrGetLen(knowntype))
26816     {
26817 	count++;
26818 	acdPromptStandardS(thys, knowntype);
26819 
26820 	if(!ajStrSuffixC(knowntype, " feature table"))
26821 	   acdPromptStandardAppend(thys, " feature table");
26822     }
26823     else
26824 	acdPromptStandard(thys, "input feature table", &count);
26825 
26826     if(maxreads > 1)
26827 	 acdPromptStandardAppend(thys, "(s)");
26828 
26829     if(!acdAttrTestDefined(thys, "default") &&
26830        acdAttrTestDefined(thys, "nullok"))
26831 	acdPromptStandardAppend(thys, " (optional)");
26832 
26833      return thys->StdPrompt;
26834 }
26835 
26836 
26837 
26838 
26839 /* @funcstatic acdPromptCpdb **************************************************
26840 **
26841 ** Sets the default prompt for this ACD object to be a clean PDB file
26842 **
26843 ** @param [u] thys [AcdPAcd] Current ACD object.
26844 ** @return [const AjPStr] Generated standard prompt
26845 **
26846 ** @release 1.8.0
26847 ** @@
26848 ******************************************************************************/
26849 
acdPromptCpdb(AcdPAcd thys)26850 static const AjPStr acdPromptCpdb(AcdPAcd thys)
26851 {
26852     static ajint count=0;
26853 
26854     const AjPStr knowntype;
26855 
26856     knowntype = acdKnowntypeDesc(thys);
26857     if(ajStrGetLen(knowntype))
26858     {
26859 	count++;
26860 	acdPromptStandardS(thys, knowntype);
26861 
26862 	if(ajStrSuffixC(knowntype, " file"))
26863 	   acdPromptStandardAppend(thys, " file");
26864     }
26865     else
26866 	acdPromptStandard(thys, "clean PDB file", &count);
26867 
26868     if(!acdAttrTestDefined(thys, "default") &&
26869        acdAttrTestDefined(thys, "nullok"))
26870 	acdPromptStandardAppend(thys, " (optional)");
26871 
26872     return thys->StdPrompt;
26873 }
26874 
26875 
26876 
26877 
26878 /* @funcstatic acdPromptScop **************************************************
26879 **
26880 ** Sets the default prompt for this ACD object to be a scop entry
26881 **
26882 ** @param [u] thys [AcdPAcd] Current ACD object.
26883 ** @return [const AjPStr] Generated standard prompt
26884 **
26885 ** @release 1.8.0
26886 ** @@
26887 ******************************************************************************/
26888 
acdPromptScop(AcdPAcd thys)26889 static const AjPStr acdPromptScop(AcdPAcd thys)
26890 {
26891     static ajint count=0;
26892 
26893     const AjPStr knowntype;
26894 
26895     knowntype = acdKnowntypeDesc(thys);
26896     if(ajStrGetLen(knowntype))
26897     {
26898 	count++;
26899 	acdPromptStandardS(thys, knowntype);
26900 
26901 	if(!ajStrSuffixC(knowntype, " file"))
26902 	   acdPromptStandardAppend(thys, " file");
26903     }
26904     else
26905 	acdPromptStandard(thys, "Scop entry vile", &count);
26906 
26907     if(!acdAttrTestDefined(thys, "default") &&
26908        acdAttrTestDefined(thys, "nullok"))
26909 	acdPromptStandardAppend(thys, " (optional)");
26910 
26911     return thys->StdPrompt;
26912 }
26913 
26914 
26915 
26916 
26917 /* @funcstatic acdHelpTextSeq *************************************************
26918 **
26919 ** Sets the help text for this ACD object to be a sequence
26920 ** description with the type included.
26921 **
26922 ** @param [r] thys [const AcdPAcd] Current ACD object.
26923 ** @param [w] Pstr [AjPStr*] Help text
26924 ** @return [void]
26925 **
26926 ** @release 4.0.0
26927 ** @@
26928 ******************************************************************************/
26929 
acdHelpTextSeq(const AcdPAcd thys,AjPStr * Pstr)26930 static void acdHelpTextSeq(const AcdPAcd thys, AjPStr* Pstr)
26931 {
26932     const AjPStr typestr = NULL;
26933     AjPStr tmptype = NULL;
26934     AjBool gaps = AJFALSE;
26935 
26936     typestr = acdAttrValue(thys, "type");
26937 
26938     ajSeqTypeSummary(typestr, &tmptype, &gaps);
26939     ajStrAssignClear(Pstr);
26940 
26941     if(ajStrGetLen(tmptype))
26942     {
26943 	ajStrAssignS(Pstr, tmptype);
26944 	ajStrAppendC(Pstr, " ");
26945 	ajStrDel(&tmptype);
26946     }
26947 
26948     ajStrAppendC(Pstr, "sequence");
26949 
26950 
26951     if(ajCharMatchC(acdType[thys->Type].Name, "seqset"))
26952     {
26953 	acdAttrToBool(thys, "aligned", gaps, &gaps);
26954 	ajStrAppendC(Pstr, " set");
26955 
26956 	if(gaps)
26957 	    ajStrInsertC(Pstr, 0, "(aligned) ");
26958     }
26959     else if(ajCharMatchC(acdType[thys->Type].Name, "seqsetall"))
26960     {
26961 	acdAttrToBool(thys, "aligned", gaps, &gaps);
26962 	ajStrAppendC(Pstr, " set(s)");
26963 
26964 	if(gaps)
26965 	    ajStrInsertC(Pstr, 0, "(aligned) ");
26966     }
26967     else if(ajCharMatchC(acdType[thys->Type].Name, "seqall"))
26968     {
26969 	ajStrAppendC(Pstr, "(s)");
26970 
26971 	if(gaps)
26972 	    ajStrInsertC(Pstr, 0, "(gapped) ");
26973     }
26974     else
26975     {
26976 	if(gaps)
26977 	    ajStrInsertC(Pstr, 0, "(gapped) ");
26978     }
26979 
26980     ajStrFmtTitle(Pstr);
26981 
26982     ajStrAppendC(Pstr,
26983 		 " filename and optional format, or reference (input USA)");
26984 
26985     return;
26986 }
26987 
26988 
26989 
26990 
26991 /* @funcstatic acdHelpTextSeqout **********************************************
26992 **
26993 ** Sets the help text for this ACD object to be an output sequence
26994 ** description with the type included.
26995 **
26996 ** @param [r] thys [const AcdPAcd] Current ACD object.
26997 ** @param [w] Pstr [AjPStr*] Help text
26998 ** @return [void]
26999 **
27000 ** @release 4.0.0
27001 ** @@
27002 ******************************************************************************/
27003 
acdHelpTextSeqout(const AcdPAcd thys,AjPStr * Pstr)27004 static void acdHelpTextSeqout(const AcdPAcd thys, AjPStr* Pstr)
27005 {
27006     const AjPStr typestr = NULL;
27007     AjPStr tmptype = NULL;
27008     AjBool gaps = AJFALSE;
27009 
27010     typestr = acdAttrValue(thys, "type");
27011 
27012     ajSeqTypeSummary(typestr, &tmptype, &gaps);
27013     ajStrAssignClear(Pstr);
27014 
27015     if(ajStrGetLen(tmptype))
27016     {
27017 	ajStrAssignS(Pstr, tmptype);
27018 	ajStrAppendC(Pstr, " ");
27019 	ajStrDel(&tmptype);
27020     }
27021 
27022     ajStrAppendC(Pstr, "sequence");
27023 
27024 
27025     if(ajCharMatchC(acdType[thys->Type].Name, "seqoutset"))
27026     {
27027 	ajStrAppendC(Pstr, " set");
27028 
27029 	if(gaps)
27030 	    ajStrInsertC(Pstr, 0, "(aligned) ");
27031     }
27032     else if(ajCharMatchC(acdType[thys->Type].Name, "seqoutall"))
27033     {
27034 	ajStrAppendC(Pstr, " set(s)");
27035 
27036 	if(gaps)
27037 	    ajStrInsertC(Pstr, 0, "(aligned) ");
27038     }
27039     else
27040     {
27041 	if(gaps)
27042 	    ajStrInsertC(Pstr, 0, "(gapped) ");
27043     }
27044 
27045     ajStrFmtTitle(Pstr);
27046 
27047     ajStrAppendC(Pstr, " filename and optional format (output USA)");
27048 
27049     return;
27050 }
27051 
27052 
27053 
27054 
27055 /* @funcstatic acdPromptSeq ***************************************************
27056 **
27057 ** Sets the default prompt for this ACD object to be a sequence
27058 ** prompt with "first", "second" etc. added.
27059 **
27060 ** @param [u] thys [AcdPAcd] Current ACD object.
27061 ** @return [const AjPStr] Generated standard prompt
27062 **
27063 ** @release 1.0.0
27064 ** @@
27065 ******************************************************************************/
27066 
acdPromptSeq(AcdPAcd thys)27067 static const AjPStr acdPromptSeq(AcdPAcd thys)
27068 {
27069     static ajint count=0;
27070     AjPStr tmptype = NULL;
27071     AjBool gaps = AJFALSE;
27072     AjPStr seqPrompt = NULL;
27073     AjPStr seqPromptAlt = NULL;
27074     const AjPStr knowntype;
27075     const AjPStr type = NULL;
27076     AjBool aligned=ajFalse;
27077 
27078     knowntype = acdKnowntypeDesc(thys);
27079 
27080     type = acdAttrValue(thys, "type");
27081 
27082     if(ajCharPrefixC(acdType[thys->Type].Name,"seqset"))
27083        acdAttrToBool(thys, "aligned", ajFalse, &aligned);
27084 
27085     ajSeqTypeSummary(type, &tmptype, &gaps);
27086 
27087     seqPrompt = ajStrNewRes(32);
27088     seqPromptAlt = ajStrNewRes(32);
27089 
27090     if(ajStrGetLen(knowntype))
27091 	ajFmtPrintAppS(&seqPromptAlt, "%S ", knowntype);
27092 
27093     if(ajStrGetLen(tmptype))
27094 	ajFmtPrintAppS(&seqPromptAlt, "%S ", tmptype);
27095 
27096     ajFmtPrintAppS(&seqPromptAlt, "sequence");
27097 
27098 
27099     if(ajCharMatchC(acdType[thys->Type].Name, "seqset"))
27100     {
27101 	ajStrAppendC(&seqPromptAlt, " set");
27102 
27103 	if(aligned)
27104 	    ajStrInsertC(&seqPromptAlt, 0, "(aligned) ");
27105     }
27106     else if(ajCharMatchC(acdType[thys->Type].Name, "seqsetall"))
27107     {
27108 	ajStrAppendC(&seqPromptAlt, " set(s)");
27109 	if(aligned)
27110 	    ajStrInsertC(&seqPromptAlt, 0, "(aligned) ");
27111     }
27112     else if(ajCharMatchC(acdType[thys->Type].Name, "seqall"))
27113     {
27114 	ajStrAppendC(&seqPromptAlt, "(s)");
27115 
27116 	if(gaps)
27117 	    ajStrInsertC(&seqPromptAlt, 0, "(gapped) ");
27118     }
27119     else
27120     {
27121 	if(gaps)
27122 	    ajStrInsertC(&seqPromptAlt, 0, "(gapped) ");
27123     }
27124 
27125     ajFmtPrintS(&seqPrompt, "Input %S", seqPromptAlt);
27126 
27127     if(knowntype)
27128     {
27129 	count++;
27130 	acdPromptStandardS(thys, seqPromptAlt);
27131     }
27132     else
27133 	acdPromptStandardAlt(thys, ajStrGetPtr(seqPrompt),
27134 			     ajStrGetPtr(seqPromptAlt), &count);
27135 
27136     if(!acdAttrTestDefined(thys, "default") &&
27137        acdAttrTestDefined(thys, "nullok"))
27138 	acdPromptStandardAppend(thys, " (optional)");
27139 
27140     ajStrDel(&tmptype);
27141     ajStrDel(&seqPrompt);
27142     ajStrDel(&seqPromptAlt);
27143 
27144     return thys->StdPrompt;
27145 }
27146 
27147 
27148 
27149 
27150 /* @funcstatic acdPromptTree **************************************************
27151 **
27152 ** Sets the default prompt for this ACD object to be a tree file
27153 ** prompt with "first", "second" etc. added.
27154 **
27155 ** @param [u] thys [AcdPAcd] Current ACD object.
27156 ** @return [const AjPStr] Generated standard prompt
27157 **
27158 ** @release 2.8.0
27159 ** @@
27160 ******************************************************************************/
27161 
acdPromptTree(AcdPAcd thys)27162 static const AjPStr acdPromptTree(AcdPAcd thys)
27163 {
27164     static ajint count=0;
27165 
27166     const AjPStr knowntype;
27167 
27168     knowntype = acdKnowntypeDesc(thys);
27169 
27170     if(ajStrGetLen(knowntype))
27171     {
27172 	count++;
27173 	acdPromptStandardS(thys, knowntype);
27174 
27175 	if(!ajStrSuffixC(knowntype, " file"))
27176 	   acdPromptStandardAppend(thys, " file");
27177     }
27178     else
27179 	acdPromptStandardAlt(thys, "Input tree file", "tree file", &count);
27180 
27181     if(!acdAttrTestDefined(thys, "default") &&
27182        acdAttrTestDefined(thys, "nullok"))
27183 	acdPromptStandardAppend(thys, " (optional)");
27184 
27185     return thys->StdPrompt;
27186 }
27187 
27188 
27189 
27190 
27191 /* @funcstatic acdPromptGraph *************************************************
27192 **
27193 ** Sets the default prompt for this ACD object to be a sequence
27194 ** prompt with "first", "second" etc. added.
27195 **
27196 ** @param [u] thys [AcdPAcd] Current ACD object.
27197 ** @return [const AjPStr] Generated standard prompt
27198 **
27199 ** @release 1.0.0
27200 ** @@
27201 ******************************************************************************/
27202 
acdPromptGraph(AcdPAcd thys)27203 static const AjPStr acdPromptGraph(AcdPAcd thys)
27204 {
27205     static ajint count=0;
27206 
27207     const AjPStr knowntype;
27208 
27209     knowntype = acdKnowntypeDesc(thys);
27210 
27211     if(ajStrGetLen(knowntype))
27212     {
27213 	count++;
27214 	acdPromptStandardS(thys, knowntype);
27215 	if(!ajStrSuffixC(knowntype, " graph"))
27216 	   acdPromptStandardAppend(thys, " graph");
27217     }
27218     else
27219 	acdPromptStandard(thys, "graph type", &count);
27220 
27221     if(!acdAttrTestDefined(thys, "default") &&
27222        acdAttrTestDefined(thys, "nullok"))
27223 	acdPromptStandardAppend(thys, " (optional)");
27224 
27225     return thys->StdPrompt;
27226 }
27227 
27228 
27229 
27230 
27231 /* @funcstatic acdPromptFeatout ***********************************************
27232 **
27233 ** Sets the default prompt for this ACD object to be a features output
27234 ** prompt with "first", "second" etc. added.
27235 **
27236 ** @param [u] thys [AcdPAcd] Current ACD object.
27237 ** @return [const AjPStr] Generated standard prompt
27238 **
27239 ** @release 1.0.0
27240 ** @@
27241 ******************************************************************************/
27242 
acdPromptFeatout(AcdPAcd thys)27243 static const AjPStr acdPromptFeatout(AcdPAcd thys)
27244 {
27245     static ajint count=0;
27246 
27247     const AjPStr knowntype;
27248 
27249     knowntype = acdKnowntypeDesc(thys);
27250 
27251     if(ajStrGetLen(knowntype))
27252     {
27253 	count++;
27254 	acdPromptStandardS(thys, knowntype);
27255 	if(ajStrSuffixC(knowntype, " features"))
27256 	   acdPromptStandardAppend(thys, " features");
27257 	acdPromptStandardAppend(thys, " output");
27258     }
27259     else
27260 	acdPromptStandard(thys, "features output", &count);
27261 
27262     if(!acdAttrTestDefined(thys, "default") &&
27263        acdAttrTestDefined(thys, "nullok"))
27264 	acdPromptStandardAppend(thys, " (optional)");
27265 
27266     return thys->StdPrompt;
27267 }
27268 
27269 
27270 
27271 
27272 /* @funcstatic acdPromptAlign *************************************************
27273 **
27274 ** Sets the default prompt for this ACD object to be a report output
27275 ** prompt with "first", "second" etc. added.
27276 **
27277 ** @param [u] thys [AcdPAcd] Current ACD object.
27278 ** @return [const AjPStr] Generated standard prompt
27279 **
27280 ** @release 2.1.0
27281 ** @@
27282 ******************************************************************************/
27283 
acdPromptAlign(AcdPAcd thys)27284 static const AjPStr acdPromptAlign(AcdPAcd thys)
27285 {
27286     static ajint count=0;
27287 
27288     const AjPStr knowntype;
27289 
27290     knowntype = acdKnowntypeDesc(thys);
27291 
27292     if(ajStrGetLen(knowntype))
27293     {
27294 	count++;
27295 	acdPromptStandardS(thys, knowntype);
27296 
27297 	if(ajStrSuffixC(knowntype, " output"))
27298 	   acdPromptStandardAppend(thys, " alignment");
27299 	else
27300 	   acdPromptStandardAppend(thys, " output alignment");
27301     }
27302     else
27303 	acdPromptStandard(thys, "output alignment", &count);
27304 
27305     if(!acdAttrTestDefined(thys, "default") &&
27306        acdAttrTestDefined(thys, "nullok"))
27307 	acdPromptStandardAppend(thys, " (optional)");
27308 
27309     return thys->StdPrompt;
27310 }
27311 
27312 
27313 
27314 
27315 /* @funcstatic acdPromptReport ************************************************
27316 **
27317 ** Sets the default prompt for this ACD object to be a report output
27318 ** prompt with "first", "second" etc. added.
27319 **
27320 ** @param [u] thys [AcdPAcd] Current ACD object.
27321 ** @return [const AjPStr] Generated standard prompt
27322 **
27323 ** @release 2.0.0
27324 ** @@
27325 ******************************************************************************/
27326 
acdPromptReport(AcdPAcd thys)27327 static const AjPStr acdPromptReport(AcdPAcd thys)
27328 {
27329     static ajint count=0;
27330 
27331     const AjPStr knowntype;
27332 
27333     knowntype = acdKnowntypeDesc(thys);
27334     if(ajStrGetLen(knowntype))
27335     {
27336 	count++;
27337 	acdPromptStandardS(thys, knowntype);
27338 
27339 	if(ajStrSuffixC(knowntype, " output"))
27340 	   acdPromptStandardAppend(thys, " report");
27341 	else
27342 	   acdPromptStandardAppend(thys, " output report");
27343     }
27344     else
27345     acdPromptStandard(thys, "output report", &count);
27346 
27347     if(!acdAttrTestDefined(thys, "default") &&
27348        acdAttrTestDefined(thys, "nullok"))
27349 	acdPromptStandardAppend(thys, " (optional)");
27350 
27351     return thys->StdPrompt;
27352 }
27353 
27354 
27355 
27356 
27357 /* @funcstatic acdPromptSeqout ************************************************
27358 **
27359 ** Sets the default prompt for this ACD object to be a sequence output
27360 ** prompt with "first", "second" etc. added.
27361 **
27362 ** @param [u] thys [AcdPAcd] Current ACD object.
27363 ** @return [const AjPStr] Generated standard prompt
27364 **
27365 ** @release 1.0.0
27366 ** @@
27367 ******************************************************************************/
27368 
acdPromptSeqout(AcdPAcd thys)27369 static const AjPStr acdPromptSeqout(AcdPAcd thys)
27370 {
27371     static ajint count=0;
27372     AjPStr tmptype = NULL;
27373     AjBool gaps = AJFALSE;
27374     AjPStr seqPrompt = NULL;
27375     AjPStr seqPromptAlt = NULL;
27376     const AjPStr knowntype;
27377     const AjPStr type = NULL;
27378     AjBool aligned=ajFalse;
27379 
27380     knowntype = acdKnowntypeDesc(thys);
27381 
27382     type = acdAttrValue(thys, "type");
27383 
27384     if(ajCharPrefixC(acdType[thys->Type].Name,"seqoutset"))
27385        acdAttrToBool(thys, "aligned", ajFalse, &aligned);
27386 
27387     ajSeqTypeSummary(type, &tmptype, &gaps);
27388 
27389     seqPrompt = ajStrNewRes(32);
27390     seqPromptAlt = ajStrNewRes(32);
27391 
27392     if(ajStrGetLen(knowntype))
27393 	ajFmtPrintAppS(&seqPromptAlt, "%S ", knowntype);
27394 
27395     if(ajStrGetLen(tmptype))
27396 	ajFmtPrintAppS(&seqPromptAlt, "%S ", tmptype);
27397 
27398     ajFmtPrintAppS(&seqPromptAlt, "output sequence");
27399 
27400 
27401     if(ajCharMatchC(acdType[thys->Type].Name, "seqoutset"))
27402     {
27403 	ajStrAppendC(&seqPromptAlt, " set");
27404 	if(aligned)
27405 	    ajStrInsertC(&seqPromptAlt, 0, "(aligned) ");
27406     }
27407     else if(ajCharMatchC(acdType[thys->Type].Name, "seqoutsetall"))
27408     {
27409 	ajStrAppendC(&seqPromptAlt, " set(s)");
27410 
27411 	if(aligned)
27412 	    ajStrInsertC(&seqPromptAlt, 0, "(aligned) ");
27413     }
27414     else if(ajCharMatchC(acdType[thys->Type].Name, "seqoutall"))
27415     {
27416 	ajStrAppendC(&seqPromptAlt, "(s)");
27417 
27418 	if(gaps)
27419 	    ajStrInsertC(&seqPromptAlt, 0, "(gapped) ");
27420     }
27421     else
27422     {
27423 	if(gaps)
27424 	    ajStrInsertC(&seqPromptAlt, 0, "(gapped) ");
27425     }
27426 
27427     ajFmtPrintS(&seqPrompt, "%S", seqPromptAlt);
27428 
27429     if(knowntype)
27430     {
27431 	count++;
27432 	acdPromptStandardS(thys, seqPromptAlt);
27433     }
27434     else
27435 	acdPromptStandardAlt(thys, ajStrGetPtr(seqPrompt),
27436 			     ajStrGetPtr(seqPromptAlt), &count);
27437 
27438     if(!acdAttrTestDefined(thys, "default") &&
27439        acdAttrTestDefined(thys, "nullok"))
27440 	acdPromptStandardAppend(thys, " (optional)");
27441 
27442     ajStrDel(&tmptype);
27443     ajStrDel(&seqPrompt);
27444     ajStrDel(&seqPromptAlt);
27445     return thys->StdPrompt;
27446 }
27447 
27448 
27449 
27450 
27451 /* @funcstatic acdHelpTextObo *************************************************
27452 **
27453 ** Sets the help text for this ACD object to be an obo term description
27454 **
27455 ** @param [r] thys [const AcdPAcd] Current ACD object.
27456 ** @param [w] Pstr [AjPStr*] Help text
27457 ** @return [void]
27458 **
27459 ** @release 6.4.0
27460 ** @@
27461 ******************************************************************************/
27462 
acdHelpTextObo(const AcdPAcd thys,AjPStr * Pstr)27463 static void acdHelpTextObo(const AcdPAcd thys, AjPStr* Pstr)
27464 {
27465     ajint maxreads;
27466 
27467     ajStrAssignClear(Pstr);
27468 
27469     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27470 
27471     if(maxreads <= 1)
27472         ajStrAssignC(Pstr, "obo term");
27473     else
27474         ajStrAssignC(Pstr, "obo term(s)");
27475 
27476     ajStrFmtTitle(Pstr);
27477 
27478     ajStrAppendC(Pstr,
27479 		 " filename and optional format, or reference (input query)");
27480 
27481     return;
27482 }
27483 
27484 
27485 
27486 
27487 /* @funcstatic acdHelpTextTaxon ***********************************************
27488 **
27489 ** Sets the help text for this ACD object to be an NCBI taxonomy entry
27490 **
27491 ** @param [r] thys [const AcdPAcd] Current ACD object.
27492 ** @param [w] Pstr [AjPStr*] Help text
27493 ** @return [void]
27494 **
27495 ** @release 6.4.0
27496 ** @@
27497 ******************************************************************************/
27498 
acdHelpTextTaxon(const AcdPAcd thys,AjPStr * Pstr)27499 static void acdHelpTextTaxon(const AcdPAcd thys, AjPStr* Pstr)
27500 {
27501     ajint maxreads;
27502 
27503     ajStrAssignClear(Pstr);
27504 
27505     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27506 
27507     if(maxreads <= 1)
27508         ajStrAssignC(Pstr, "taxon");
27509     else
27510         ajStrAssignC(Pstr, "taxon(s)");
27511 
27512     ajStrFmtTitle(Pstr);
27513 
27514     ajStrAppendC(Pstr,
27515 		 " filename and optional format, or reference (input query)");
27516 
27517     return;
27518 }
27519 
27520 
27521 
27522 
27523 /* @funcstatic acdHelpTextText ************************************************
27524 **
27525 ** Sets the help text for this ACD object to be a text entry
27526 **
27527 ** @param [r] thys [const AcdPAcd] Current ACD object.
27528 ** @param [w] Pstr [AjPStr*] Help text
27529 ** @return [void]
27530 **
27531 ** @release 6.4.0
27532 ** @@
27533 ******************************************************************************/
27534 
acdHelpTextText(const AcdPAcd thys,AjPStr * Pstr)27535 static void acdHelpTextText(const AcdPAcd thys, AjPStr* Pstr)
27536 {
27537     ajint maxreads;
27538 
27539     ajStrAssignClear(Pstr);
27540 
27541     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27542 
27543     if(maxreads <= 1)
27544         ajStrAssignC(Pstr, "text");
27545     else
27546         ajStrAssignC(Pstr, "text(s)");
27547 
27548     ajStrFmtTitle(Pstr);
27549 
27550     ajStrAppendC(Pstr,
27551 		 " filename and optional format, or reference (input query)");
27552 
27553     return;
27554 }
27555 
27556 
27557 
27558 
27559 /* @funcstatic acdHelpTextUrl *************************************************
27560 **
27561 ** Sets the help text for this ACD object to be a URL data entry
27562 **
27563 ** @param [r] thys [const AcdPAcd] Current ACD object.
27564 ** @param [w] Pstr [AjPStr*] Help text
27565 ** @return [void]
27566 **
27567 ** @release 6.4.0
27568 ** @@
27569 ******************************************************************************/
27570 
acdHelpTextUrl(const AcdPAcd thys,AjPStr * Pstr)27571 static void acdHelpTextUrl(const AcdPAcd thys, AjPStr* Pstr)
27572 {
27573     ajint maxreads;
27574 
27575     ajStrAssignClear(Pstr);
27576 
27577     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27578 
27579     if(maxreads <= 1)
27580         ajStrAssignC(Pstr, "url");
27581     else
27582         ajStrAssignC(Pstr, "url(s)");
27583 
27584     ajStrFmtTitle(Pstr);
27585 
27586     ajStrAppendC(Pstr,
27587 		 " filename and optional format, or reference (input query)");
27588 
27589     return;
27590 }
27591 
27592 
27593 
27594 
27595 /* @funcstatic acdHelpTextVariation *******************************************
27596 **
27597 ** Sets the help text for this ACD object to be a variation data entry
27598 **
27599 ** @param [r] thys [const AcdPAcd] Current ACD object.
27600 ** @param [w] Pstr [AjPStr*] Help text
27601 ** @return [void]
27602 **
27603 ** @release 6.4.0
27604 ** @@
27605 ******************************************************************************/
27606 
acdHelpTextVariation(const AcdPAcd thys,AjPStr * Pstr)27607 static void acdHelpTextVariation(const AcdPAcd thys, AjPStr* Pstr)
27608 {
27609     ajint maxreads;
27610 
27611     ajStrAssignClear(Pstr);
27612 
27613     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27614 
27615     if(maxreads <= 1)
27616         ajStrAssignC(Pstr, "variation");
27617     else
27618         ajStrAssignC(Pstr, "variation(s)");
27619 
27620     ajStrFmtTitle(Pstr);
27621 
27622     ajStrAppendC(Pstr,
27623 		 " filename and optional format, or reference (input query)");
27624 
27625     return;
27626 }
27627 
27628 
27629 
27630 
27631 /* @funcstatic acdHelpTextXml *************************************************
27632 **
27633 ** Sets the help text for this ACD object to be a xml description
27634 **
27635 ** @param [r] thys [const AcdPAcd] Current ACD object.
27636 ** @param [w] Pstr [AjPStr*] Help text
27637 ** @return [void]
27638 **
27639 ** @release 6.6.0
27640 ** @@
27641 ******************************************************************************/
27642 
acdHelpTextXml(const AcdPAcd thys,AjPStr * Pstr)27643 static void acdHelpTextXml(const AcdPAcd thys, AjPStr* Pstr)
27644 {
27645     ajint maxreads;
27646 
27647     ajStrAssignClear(Pstr);
27648 
27649     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27650 
27651     if(maxreads <= 1)
27652         ajStrAssignC(Pstr, "xml");
27653     else
27654         ajStrAssignC(Pstr, "xml(s)");
27655 
27656     ajStrFmtTitle(Pstr);
27657 
27658     ajStrAppendC(Pstr,
27659 		 " filename and optional format, or reference (input query)");
27660 
27661     return;
27662 }
27663 
27664 
27665 
27666 
27667 /* @funcstatic acdPromptAssembly **********************************************
27668 **
27669 ** Sets the default prompt for this ACD object to be an assembly
27670 ** prompt with "first", "second" etc. added.
27671 **
27672 ** @param [u] thys [AcdPAcd] Current ACD object.
27673 ** @return [const AjPStr] Generated standard prompt
27674 **
27675 ** @release 6.5.0
27676 ** @@
27677 ******************************************************************************/
27678 
acdPromptAssembly(AcdPAcd thys)27679 static const AjPStr acdPromptAssembly(AcdPAcd thys)
27680 {
27681     static ajint count=0;
27682     AjPStr assemPrompt = NULL;
27683     AjPStr assemPromptAlt = NULL;
27684     const AjPStr knowntype;
27685 
27686     knowntype = acdKnowntypeDesc(thys);
27687 
27688     assemPrompt = ajStrNewRes(32);
27689     assemPromptAlt = ajStrNewRes(32);
27690 
27691     if(ajStrGetLen(knowntype))
27692 	ajFmtPrintAppS(&assemPromptAlt, "%S ", knowntype);
27693 
27694     ajFmtPrintAppS(&assemPromptAlt, "assembly");
27695 
27696     ajFmtPrintS(&assemPrompt, "Input %S", assemPromptAlt);
27697 
27698     if(knowntype)
27699     {
27700 	count++;
27701 	acdPromptStandardS(thys, assemPromptAlt);
27702     }
27703     else
27704 	acdPromptStandardAlt(thys, ajStrGetPtr(assemPrompt),
27705 			     ajStrGetPtr(assemPromptAlt), &count);
27706 
27707     if(!acdAttrTestDefined(thys, "default") &&
27708        acdAttrTestDefined(thys, "nullok"))
27709 	acdPromptStandardAppend(thys, " (optional)");
27710 
27711     ajStrDel(&assemPrompt);
27712     ajStrDel(&assemPromptAlt);
27713 
27714     return thys->StdPrompt;
27715 }
27716 
27717 
27718 
27719 
27720 /* @funcstatic acdPromptObo ***************************************************
27721 **
27722 ** Sets the default prompt for this ACD object to be an obo term
27723 ** prompt with "first", "second" etc. added.
27724 **
27725 ** @param [u] thys [AcdPAcd] Current ACD object.
27726 ** @return [const AjPStr] Generated standard prompt
27727 **
27728 ** @release 6.4.0
27729 ** @@
27730 ******************************************************************************/
27731 
acdPromptObo(AcdPAcd thys)27732 static const AjPStr acdPromptObo(AcdPAcd thys)
27733 {
27734     static ajint count=0;
27735     AjPStr oboPrompt = NULL;
27736     AjPStr oboPromptAlt = NULL;
27737     const AjPStr knowntype;
27738     ajint maxreads = 0;
27739 
27740     acdAttrToInt(thys, "maxreads", 1, &maxreads);
27741 
27742     knowntype = acdKnowntypeDesc(thys);
27743 
27744     oboPrompt = ajStrNewRes(32);
27745     oboPromptAlt = ajStrNewRes(32);
27746 
27747     if(ajStrGetLen(knowntype))
27748 	ajFmtPrintAppS(&oboPromptAlt, "%S ", knowntype);
27749 
27750     ajFmtPrintAppS(&oboPromptAlt, "obo term");
27751 
27752     if(maxreads > 1)
27753 	ajStrAppendC(&oboPromptAlt, "(s)");
27754 
27755     ajFmtPrintS(&oboPrompt, "Input %S", oboPromptAlt);
27756 
27757     if(knowntype)
27758     {
27759 	count++;
27760 	acdPromptStandardS(thys, oboPromptAlt);
27761     }
27762     else
27763 	acdPromptStandardAlt(thys, ajStrGetPtr(oboPrompt),
27764 			     ajStrGetPtr(oboPromptAlt), &count);
27765 
27766     if(!acdAttrTestDefined(thys, "default") &&
27767        acdAttrTestDefined(thys, "nullok"))
27768 	acdPromptStandardAppend(thys, " (optional)");
27769 
27770     ajStrDel(&oboPrompt);
27771     ajStrDel(&oboPromptAlt);
27772 
27773     return thys->StdPrompt;
27774 }
27775 
27776 
27777 
27778 
27779 /* @funcstatic acdPromptOutassembly *******************************************
27780 **
27781 ** Sets the default prompt for this ACD object to be a simple
27782 ** prompt with "second", "third" etc. added.
27783 **
27784 ** @param [u] thys [AcdPAcd] Current ACD object.
27785 ** @return [const AjPStr] Generated standard prompt
27786 **
27787 ** @release 2.9.0
27788 ** @@
27789 ******************************************************************************/
27790 
acdPromptOutassembly(AcdPAcd thys)27791 static const AjPStr acdPromptOutassembly(AcdPAcd thys)
27792 {
27793     static ajint count=0;
27794 
27795     const AjPStr knowntype;
27796 
27797     knowntype = acdKnowntypeDesc(thys);
27798 
27799     if(ajStrGetLen(knowntype))
27800     {
27801 	count++;
27802 	acdPromptStandardS(thys, knowntype);
27803 	acdPromptStandardAppend(thys, " output file");
27804     }
27805     else
27806 	acdPromptStandard(thys, "assembly output file", &count);
27807 
27808     if(!acdAttrTestDefined(thys, "default") &&
27809        acdAttrTestDefined(thys, "nullok"))
27810 	acdPromptStandardAppend(thys, " (optional)");
27811 
27812     return thys->StdPrompt;
27813 }
27814 
27815 
27816 
27817 
27818 /* @funcstatic acdPromptOutcodon **********************************************
27819 **
27820 ** Sets the default prompt for this ACD object to be a simple
27821 ** prompt with "second", "third" etc. added.
27822 **
27823 ** @param [u] thys [AcdPAcd] Current ACD object.
27824 ** @return [const AjPStr] Generated standard prompt
27825 **
27826 ** @release 2.9.0
27827 ** @@
27828 ******************************************************************************/
27829 
acdPromptOutcodon(AcdPAcd thys)27830 static const AjPStr acdPromptOutcodon(AcdPAcd thys)
27831 {
27832     static ajint count=0;
27833 
27834     const AjPStr knowntype;
27835 
27836     knowntype = acdKnowntypeDesc(thys);
27837 
27838     if(ajStrGetLen(knowntype))
27839     {
27840 	count++;
27841 	acdPromptStandardS(thys, knowntype);
27842 	acdPromptStandardAppend(thys, " output file");
27843     }
27844     else
27845 	acdPromptStandard(thys, "codon usage output file", &count);
27846 
27847     if(!acdAttrTestDefined(thys, "default") &&
27848        acdAttrTestDefined(thys, "nullok"))
27849 	acdPromptStandardAppend(thys, " (optional)");
27850 
27851     return thys->StdPrompt;
27852 }
27853 
27854 
27855 
27856 
27857 /* @funcstatic acdPromptOutcpdb ***********************************************
27858 **
27859 ** Sets the default prompt for this ACD object to be a simple
27860 ** prompt with "second", "third" etc. added.
27861 **
27862 ** @param [u] thys [AcdPAcd] Current ACD object.
27863 ** @return [const AjPStr] Generated standard prompt
27864 **
27865 ** @release 2.9.0
27866 ** @@
27867 ******************************************************************************/
27868 
acdPromptOutcpdb(AcdPAcd thys)27869 static const AjPStr acdPromptOutcpdb(AcdPAcd thys)
27870 {
27871     static ajint count=0;
27872 
27873     const AjPStr knowntype;
27874 
27875     knowntype = acdKnowntypeDesc(thys);
27876 
27877     if(ajStrGetLen(knowntype))
27878     {
27879 	count++;
27880 	acdPromptStandardS(thys, knowntype);
27881 	acdPromptStandardAppend(thys, " output file");
27882     }
27883     else
27884 	acdPromptStandard(thys, "clean PDB output file", &count);
27885 
27886     if(!acdAttrTestDefined(thys, "default") &&
27887        acdAttrTestDefined(thys, "nullok"))
27888 	acdPromptStandardAppend(thys, " (optional)");
27889 
27890     return thys->StdPrompt;
27891 }
27892 
27893 
27894 
27895 
27896 /* @funcstatic acdPromptOutdata ***********************************************
27897 **
27898 ** Sets the default prompt for this ACD object to be a simple
27899 ** prompt with "second", "third" etc. added.
27900 **
27901 ** @param [u] thys [AcdPAcd] Current ACD object.
27902 ** @return [const AjPStr] Generated standard prompt
27903 **
27904 ** @release 2.9.0
27905 ** @@
27906 ******************************************************************************/
27907 
acdPromptOutdata(AcdPAcd thys)27908 static const AjPStr acdPromptOutdata(AcdPAcd thys)
27909 {
27910     static ajint count=0;
27911 
27912     const AjPStr knowntype;
27913 
27914     knowntype = acdKnowntypeDesc(thys);
27915 
27916     if(ajStrGetLen(knowntype))
27917     {
27918 	count++;
27919 	acdPromptStandardS(thys, knowntype);
27920 	acdPromptStandardAppend(thys, " output file");
27921     }
27922     else
27923 	acdPromptStandard(thys, "output data file", &count);
27924 
27925     if(!acdAttrTestDefined(thys, "default") &&
27926        acdAttrTestDefined(thys, "nullok"))
27927 	acdPromptStandardAppend(thys, " (optional)");
27928 
27929     return thys->StdPrompt;
27930 }
27931 
27932 
27933 
27934 
27935 /* @funcstatic acdPromptOutdir ************************************************
27936 **
27937 ** Sets the default prompt for this ACD object to be a simple
27938 ** prompt with "second", "third" etc. added.
27939 **
27940 ** @param [u] thys [AcdPAcd] Current ACD object.
27941 ** @return [const AjPStr] Generated standard prompt
27942 **
27943 ** @release 2.9.0
27944 ** @@
27945 ******************************************************************************/
27946 
acdPromptOutdir(AcdPAcd thys)27947 static const AjPStr acdPromptOutdir(AcdPAcd thys)
27948 {
27949     static ajint count=0;
27950 
27951     const AjPStr knowntype;
27952 
27953     knowntype = acdKnowntypeDesc(thys);
27954 
27955     if(ajStrGetLen(knowntype))
27956     {
27957 	count++;
27958 	acdPromptStandardS(thys, knowntype);
27959 
27960 	if(!ajStrSuffixC(knowntype, " file"))
27961 	    acdPromptStandardAppend(thys, " file");
27962 	acdPromptStandardAppend(thys, " output directory");
27963     }
27964     else
27965 	acdPromptStandard(thys, "output directory", &count);
27966 
27967     if(!acdAttrTestDefined(thys, "default") &&
27968        acdAttrTestDefined(thys, "nullok"))
27969 	acdPromptStandardAppend(thys, " (optional)");
27970 
27971     return thys->StdPrompt;
27972 }
27973 
27974 
27975 
27976 
27977 /* @funcstatic acdPromptOutdiscrete *******************************************
27978 **
27979 ** Sets the default prompt for this ACD object to be a simple
27980 ** prompt with "second", "third" etc. added.
27981 **
27982 ** @param [u] thys [AcdPAcd] Current ACD object.
27983 ** @return [const AjPStr] Generated standard prompt
27984 **
27985 ** @release 2.9.0
27986 ** @@
27987 ******************************************************************************/
27988 
acdPromptOutdiscrete(AcdPAcd thys)27989 static const AjPStr acdPromptOutdiscrete(AcdPAcd thys)
27990 {
27991     static ajint count=0;
27992 
27993     const AjPStr knowntype;
27994 
27995     knowntype = acdKnowntypeDesc(thys);
27996 
27997     if(ajStrGetLen(knowntype))
27998     {
27999 	count++;
28000 	acdPromptStandardS(thys, knowntype);
28001 	acdPromptStandardAppend(thys, " output discrete data file");
28002     }
28003     else
28004 	acdPromptStandard(thys, "discrete data output file", &count);
28005 
28006     if(!acdAttrTestDefined(thys, "default") &&
28007        acdAttrTestDefined(thys, "nullok"))
28008 	acdPromptStandardAppend(thys, " (optional)");
28009 
28010     return thys->StdPrompt;
28011 }
28012 
28013 
28014 
28015 
28016 /* @funcstatic acdPromptOutdistance *******************************************
28017 **
28018 ** Sets the default prompt for this ACD object to be a simple
28019 ** prompt with "second", "third" etc. added.
28020 **
28021 ** @param [u] thys [AcdPAcd] Current ACD object.
28022 ** @return [const AjPStr] Generated standard prompt
28023 **
28024 ** @release 2.9.0
28025 ** @@
28026 ******************************************************************************/
28027 
acdPromptOutdistance(AcdPAcd thys)28028 static const AjPStr acdPromptOutdistance(AcdPAcd thys)
28029 {
28030     static ajint count=0;
28031 
28032     const AjPStr knowntype;
28033 
28034     knowntype = acdKnowntypeDesc(thys);
28035     if(ajStrGetLen(knowntype))
28036     {
28037 	count++;
28038 	acdPromptStandardS(thys, knowntype);
28039 	acdPromptStandardAppend(thys, " distance data output file");
28040     }
28041     else
28042 	acdPromptStandard(thys, "output distance data file", &count);
28043 
28044     if(!acdAttrTestDefined(thys, "default") &&
28045        acdAttrTestDefined(thys, "nullok"))
28046 	acdPromptStandardAppend(thys, " (optional)");
28047 
28048     return thys->StdPrompt;
28049 }
28050 
28051 
28052 
28053 
28054 /* @funcstatic acdPromptOutfreq ***********************************************
28055 **
28056 ** Sets the default prompt for this ACD object to be a simple
28057 ** prompt with "second", "third" etc. added.
28058 **
28059 ** @param [u] thys [AcdPAcd] Current ACD object.
28060 ** @return [const AjPStr] Generated standard prompt
28061 **
28062 ** @release 2.9.0
28063 ** @@
28064 ******************************************************************************/
28065 
acdPromptOutfreq(AcdPAcd thys)28066 static const AjPStr acdPromptOutfreq(AcdPAcd thys)
28067 {
28068     static ajint count=0;
28069 
28070     const AjPStr knowntype;
28071 
28072     knowntype = acdKnowntypeDesc(thys);
28073 
28074     if(ajStrGetLen(knowntype))
28075     {
28076 	count++;
28077 	acdPromptStandardS(thys, knowntype);
28078 	acdPromptStandardAppend(thys, " frequency data output file");
28079     }
28080     else
28081     acdPromptStandard(thys, "frequency data output file", &count);
28082 
28083     if(!acdAttrTestDefined(thys, "default") &&
28084        acdAttrTestDefined(thys, "nullok"))
28085 	acdPromptStandardAppend(thys, " (optional)");
28086 
28087     return thys->StdPrompt;
28088 }
28089 
28090 
28091 
28092 
28093 /* @funcstatic acdPromptOutmatrix *********************************************
28094 **
28095 ** Sets the default prompt for this ACD object to be a simple
28096 ** prompt with "second", "third" etc. added.
28097 **
28098 ** @param [u] thys [AcdPAcd] Current ACD object.
28099 ** @return [const AjPStr] Generated standard prompt
28100 **
28101 ** @release 2.9.0
28102 ** @@
28103 ******************************************************************************/
28104 
acdPromptOutmatrix(AcdPAcd thys)28105 static const AjPStr acdPromptOutmatrix(AcdPAcd thys)
28106 {
28107     static ajint count=0;
28108 
28109     const AjPStr knowntype;
28110 
28111     knowntype = acdKnowntypeDesc(thys);
28112     if(ajStrGetLen(knowntype))
28113     {
28114 	count++;
28115 	acdPromptStandardS(thys, knowntype);
28116 	acdPromptStandardAppend(thys, " matrix output file");
28117     }
28118     else
28119 	acdPromptStandard(thys, "matrix output file", &count);
28120 
28121     if(!acdAttrTestDefined(thys, "default") &&
28122        acdAttrTestDefined(thys, "nullok"))
28123 	acdPromptStandardAppend(thys, " (optional)");
28124 
28125     return thys->StdPrompt;
28126 }
28127 
28128 
28129 
28130 
28131 /* @funcstatic acdPromptOutobo ************************************************
28132 **
28133 ** Sets the default prompt for this ACD object to be a simple
28134 ** prompt with "second", "third" etc. added.
28135 **
28136 ** @param [u] thys [AcdPAcd] Current ACD object.
28137 ** @return [const AjPStr] Generated standard prompt
28138 **
28139 ** @release 6.4.0
28140 ** @@
28141 ******************************************************************************/
28142 
acdPromptOutobo(AcdPAcd thys)28143 static const AjPStr acdPromptOutobo(AcdPAcd thys)
28144 {
28145     static ajint count=0;
28146 
28147     const AjPStr knowntype;
28148 
28149     knowntype = acdKnowntypeDesc(thys);
28150 
28151     if(ajStrGetLen(knowntype))
28152     {
28153 	count++;
28154 	acdPromptStandardS(thys, knowntype);
28155 	acdPromptStandardAppend(thys, " obo output file");
28156     }
28157     else
28158 	acdPromptStandard(thys, "obo output file", &count);
28159 
28160     if(!acdAttrTestDefined(thys, "default") &&
28161        acdAttrTestDefined(thys, "nullok"))
28162 	acdPromptStandardAppend(thys, " (optional)");
28163 
28164     return thys->StdPrompt;
28165 }
28166 
28167 
28168 
28169 
28170 /* @funcstatic acdPromptOutproperties *****************************************
28171 **
28172 ** Sets the default prompt for this ACD object to be a simple
28173 ** prompt with "second", "third" etc. added.
28174 **
28175 ** @param [u] thys [AcdPAcd] Current ACD object.
28176 ** @return [const AjPStr] Generated standard prompt
28177 **
28178 ** @release 2.9.0
28179 ** @@
28180 ******************************************************************************/
28181 
acdPromptOutproperties(AcdPAcd thys)28182 static const AjPStr acdPromptOutproperties(AcdPAcd thys)
28183 {
28184     static ajint count=0;
28185 
28186     const AjPStr knowntype;
28187 
28188     knowntype = acdKnowntypeDesc(thys);
28189 
28190     if(ajStrGetLen(knowntype))
28191     {
28192 	count++;
28193 	acdPromptStandardS(thys, knowntype);
28194 	acdPromptStandardAppend(thys, " properties data output file");
28195     }
28196     else
28197 	acdPromptStandard(thys, "properties data output file", &count);
28198 
28199     if(!acdAttrTestDefined(thys, "default") &&
28200        acdAttrTestDefined(thys, "nullok"))
28201 	acdPromptStandardAppend(thys, " (optional)");
28202 
28203     return thys->StdPrompt;
28204 }
28205 
28206 
28207 
28208 
28209 /* @funcstatic acdPromptOutrefseq *********************************************
28210 **
28211 ** Sets the default prompt for this ACD object to be a simple
28212 ** prompt with "second", "third" etc. added.
28213 **
28214 ** @param [u] thys [AcdPAcd] Current ACD object.
28215 ** @return [const AjPStr] Generated standard prompt
28216 **
28217 ** @release 2.9.0
28218 ** @@
28219 ******************************************************************************/
28220 
acdPromptOutrefseq(AcdPAcd thys)28221 static const AjPStr acdPromptOutrefseq(AcdPAcd thys)
28222 {
28223     static ajint count=0;
28224 
28225     const AjPStr knowntype;
28226 
28227     knowntype = acdKnowntypeDesc(thys);
28228 
28229     if(ajStrGetLen(knowntype))
28230     {
28231 	count++;
28232 	acdPromptStandardS(thys, knowntype);
28233 	acdPromptStandardAppend(thys, " output file");
28234     }
28235     else
28236 	acdPromptStandard(thys, "reference sequence output file", &count);
28237 
28238     if(!acdAttrTestDefined(thys, "default") &&
28239        acdAttrTestDefined(thys, "nullok"))
28240 	acdPromptStandardAppend(thys, " (optional)");
28241 
28242     return thys->StdPrompt;
28243 }
28244 
28245 
28246 
28247 
28248 /* @funcstatic acdPromptOutresource *******************************************
28249 **
28250 ** Sets the default prompt for this ACD object to be a simple
28251 ** prompt with "second", "third" etc. added.
28252 **
28253 ** @param [u] thys [AcdPAcd] Current ACD object.
28254 ** @return [const AjPStr] Generated standard prompt
28255 **
28256 ** @release 6.4.0
28257 ** @@
28258 ******************************************************************************/
28259 
acdPromptOutresource(AcdPAcd thys)28260 static const AjPStr acdPromptOutresource(AcdPAcd thys)
28261 {
28262     static ajint count=0;
28263 
28264     const AjPStr knowntype;
28265 
28266     knowntype = acdKnowntypeDesc(thys);
28267 
28268     if(ajStrGetLen(knowntype))
28269     {
28270 	count++;
28271 	acdPromptStandardS(thys, knowntype);
28272 	acdPromptStandardAppend(thys, " data resource output file");
28273     }
28274     else
28275 	acdPromptStandard(thys, "data resource output file", &count);
28276 
28277     if(!acdAttrTestDefined(thys, "default") &&
28278        acdAttrTestDefined(thys, "nullok"))
28279 	acdPromptStandardAppend(thys, " (optional)");
28280 
28281     return thys->StdPrompt;
28282 }
28283 
28284 
28285 
28286 
28287 /* @funcstatic acdPromptOutscop ***********************************************
28288 **
28289 ** Sets the default prompt for this ACD object to be a simple
28290 ** prompt with "second", "third" etc. added.
28291 **
28292 ** @param [u] thys [AcdPAcd] Current ACD object.
28293 ** @return [const AjPStr] Generated standard prompt
28294 **
28295 ** @release 2.9.0
28296 ** @@
28297 ******************************************************************************/
28298 
acdPromptOutscop(AcdPAcd thys)28299 static const AjPStr acdPromptOutscop(AcdPAcd thys)
28300 {
28301     static ajint count=0;
28302 
28303     const AjPStr knowntype;
28304 
28305     knowntype = acdKnowntypeDesc(thys);
28306 
28307     if(ajStrGetLen(knowntype))
28308     {
28309 	count++;
28310 	acdPromptStandardS(thys, knowntype);
28311 	acdPromptStandardAppend(thys, " scop output file");
28312     }
28313     else
28314 	acdPromptStandard(thys, "scop output file", &count);
28315 
28316     if(!acdAttrTestDefined(thys, "default") &&
28317        acdAttrTestDefined(thys, "nullok"))
28318 	acdPromptStandardAppend(thys, " (optional)");
28319 
28320     return thys->StdPrompt;
28321 }
28322 
28323 
28324 
28325 
28326 /* @funcstatic acdPromptOuttaxon **********************************************
28327 **
28328 ** Sets the default prompt for this ACD object to be a simple
28329 ** prompt with "second", "third" etc. added.
28330 **
28331 ** @param [u] thys [AcdPAcd] Current ACD object.
28332 ** @return [const AjPStr] Generated standard prompt
28333 **
28334 ** @release 6.4.0
28335 ** @@
28336 ******************************************************************************/
28337 
acdPromptOuttaxon(AcdPAcd thys)28338 static const AjPStr acdPromptOuttaxon(AcdPAcd thys)
28339 {
28340     static ajint count=0;
28341 
28342     const AjPStr knowntype;
28343 
28344     knowntype = acdKnowntypeDesc(thys);
28345 
28346     if(ajStrGetLen(knowntype))
28347     {
28348 	count++;
28349 	acdPromptStandardS(thys, knowntype);
28350 	acdPromptStandardAppend(thys, " taxon output file");
28351     }
28352     else
28353 	acdPromptStandard(thys, "taxon output file", &count);
28354 
28355     if(!acdAttrTestDefined(thys, "default") &&
28356        acdAttrTestDefined(thys, "nullok"))
28357 	acdPromptStandardAppend(thys, " (optional)");
28358 
28359     return thys->StdPrompt;
28360 }
28361 
28362 
28363 
28364 
28365 /* @funcstatic acdPromptOuttext ***********************************************
28366 **
28367 ** Sets the default prompt for this ACD object to be a simple
28368 ** prompt with "second", "third" etc. added.
28369 **
28370 ** @param [u] thys [AcdPAcd] Current ACD object.
28371 ** @return [const AjPStr] Generated standard prompt
28372 **
28373 ** @release 6.4.0
28374 ** @@
28375 ******************************************************************************/
28376 
acdPromptOuttext(AcdPAcd thys)28377 static const AjPStr acdPromptOuttext(AcdPAcd thys)
28378 {
28379     static ajint count=0;
28380 
28381     const AjPStr knowntype;
28382 
28383     knowntype = acdKnowntypeDesc(thys);
28384 
28385     if(ajStrGetLen(knowntype))
28386     {
28387 	count++;
28388 	acdPromptStandardS(thys, knowntype);
28389 	acdPromptStandardAppend(thys, " text output file");
28390     }
28391     else
28392 	acdPromptStandard(thys, "text output file", &count);
28393 
28394     if(!acdAttrTestDefined(thys, "default") &&
28395        acdAttrTestDefined(thys, "nullok"))
28396 	acdPromptStandardAppend(thys, " (optional)");
28397 
28398     return thys->StdPrompt;
28399 }
28400 
28401 
28402 
28403 
28404 /* @funcstatic acdPromptOuttree ***********************************************
28405 **
28406 ** Sets the default prompt for this ACD object to be a simple
28407 ** prompt with "second", "third" etc. added.
28408 **
28409 ** @param [u] thys [AcdPAcd] Current ACD object.
28410 ** @return [const AjPStr] Generated standard prompt
28411 **
28412 ** @release 2.9.0
28413 ** @@
28414 ******************************************************************************/
28415 
acdPromptOuttree(AcdPAcd thys)28416 static const AjPStr acdPromptOuttree(AcdPAcd thys)
28417 {
28418     static ajint count=0;
28419 
28420     const AjPStr knowntype;
28421 
28422     knowntype = acdKnowntypeDesc(thys);
28423 
28424     if(ajStrGetLen(knowntype))
28425     {
28426 	count++;
28427 	acdPromptStandardS(thys, knowntype);
28428 	acdPromptStandardAppend(thys, " tree output file");
28429     }
28430     else
28431 	acdPromptStandard(thys, "tree output file", &count);
28432 
28433     if(!acdAttrTestDefined(thys, "default") &&
28434        acdAttrTestDefined(thys, "nullok"))
28435 	acdPromptStandardAppend(thys, " (optional)");
28436 
28437     return thys->StdPrompt;
28438 }
28439 
28440 
28441 
28442 
28443 /* @funcstatic acdPromptOuturl ************************************************
28444 **
28445 ** Sets the default prompt for this ACD object to be a simple
28446 ** prompt with "second", "third" etc. added.
28447 **
28448 ** @param [u] thys [AcdPAcd] Current ACD object.
28449 ** @return [const AjPStr] Generated standard prompt
28450 **
28451 ** @release 6.4.0
28452 ** @@
28453 ******************************************************************************/
28454 
acdPromptOuturl(AcdPAcd thys)28455 static const AjPStr acdPromptOuturl(AcdPAcd thys)
28456 {
28457     static ajint count=0;
28458 
28459     const AjPStr knowntype;
28460 
28461     knowntype = acdKnowntypeDesc(thys);
28462 
28463     if(ajStrGetLen(knowntype))
28464     {
28465 	count++;
28466 	acdPromptStandardS(thys, knowntype);
28467 	acdPromptStandardAppend(thys, " URL output file");
28468     }
28469     else
28470 	acdPromptStandard(thys, "URL output file", &count);
28471 
28472     if(!acdAttrTestDefined(thys, "default") &&
28473        acdAttrTestDefined(thys, "nullok"))
28474 	acdPromptStandardAppend(thys, " (optional)");
28475 
28476     return thys->StdPrompt;
28477 }
28478 
28479 
28480 
28481 
28482 /* @funcstatic acdPromptOutvariation ******************************************
28483 **
28484 ** Sets the default prompt for this ACD object to be a simple
28485 ** prompt with "second", "third" etc. added.
28486 **
28487 ** @param [u] thys [AcdPAcd] Current ACD object.
28488 ** @return [const AjPStr] Generated standard prompt
28489 **
28490 ** @release 6.4.0
28491 ** @@
28492 ******************************************************************************/
28493 
acdPromptOutvariation(AcdPAcd thys)28494 static const AjPStr acdPromptOutvariation(AcdPAcd thys)
28495 {
28496     static ajint count=0;
28497 
28498     const AjPStr knowntype;
28499 
28500     knowntype = acdKnowntypeDesc(thys);
28501 
28502     if(ajStrGetLen(knowntype))
28503     {
28504 	count++;
28505 	acdPromptStandardS(thys, knowntype);
28506 	acdPromptStandardAppend(thys, " variation output file");
28507     }
28508     else
28509 	acdPromptStandard(thys, "variation output file", &count);
28510 
28511     if(!acdAttrTestDefined(thys, "default") &&
28512        acdAttrTestDefined(thys, "nullok"))
28513 	acdPromptStandardAppend(thys, " (optional)");
28514 
28515     return thys->StdPrompt;
28516 }
28517 
28518 
28519 
28520 
28521 /* @funcstatic acdPromptOutxml ************************************************
28522 **
28523 ** Sets the default prompt for this ACD object to be a simple
28524 ** prompt with "second", "third" etc. added.
28525 **
28526 ** @param [u] thys [AcdPAcd] Current ACD object.
28527 ** @return [const AjPStr] Generated standard prompt
28528 **
28529 ** @release 6.6.0
28530 ** @@
28531 ******************************************************************************/
28532 
acdPromptOutxml(AcdPAcd thys)28533 static const AjPStr acdPromptOutxml(AcdPAcd thys)
28534 {
28535     static ajint count=0;
28536 
28537     const AjPStr knowntype;
28538 
28539     knowntype = acdKnowntypeDesc(thys);
28540 
28541     if(ajStrGetLen(knowntype))
28542     {
28543 	count++;
28544 	acdPromptStandardS(thys, knowntype);
28545 	acdPromptStandardAppend(thys, " output file");
28546     }
28547     else
28548 	acdPromptStandard(thys, "xml output file", &count);
28549 
28550     if(!acdAttrTestDefined(thys, "default") &&
28551        acdAttrTestDefined(thys, "nullok"))
28552 	acdPromptStandardAppend(thys, " (optional)");
28553 
28554     return thys->StdPrompt;
28555 }
28556 
28557 
28558 
28559 
28560 /* @funcstatic acdPromptRefseq **********************************************
28561 **
28562 ** Sets the default prompt for this ACD object to be a reference sequence
28563 ** prompt with "first", "second" etc. added.
28564 **
28565 ** @param [u] thys [AcdPAcd] Current ACD object.
28566 ** @return [const AjPStr] Generated standard prompt
28567 **
28568 ** @release 6.5.0
28569 ** @@
28570 ******************************************************************************/
28571 
acdPromptRefseq(AcdPAcd thys)28572 static const AjPStr acdPromptRefseq(AcdPAcd thys)
28573 {
28574     static ajint count=0;
28575     AjPStr refseqPrompt = NULL;
28576     AjPStr refseqPromptAlt = NULL;
28577     const AjPStr knowntype;
28578 
28579     knowntype = acdKnowntypeDesc(thys);
28580 
28581     refseqPrompt = ajStrNewRes(32);
28582     refseqPromptAlt = ajStrNewRes(32);
28583 
28584     if(ajStrGetLen(knowntype))
28585 	ajFmtPrintAppS(&refseqPromptAlt, "%S ", knowntype);
28586 
28587     ajFmtPrintAppS(&refseqPromptAlt, "reference sequence");
28588 
28589     ajFmtPrintS(&refseqPrompt, "Input %S", refseqPromptAlt);
28590 
28591     if(knowntype)
28592     {
28593 	count++;
28594 	acdPromptStandardS(thys, refseqPromptAlt);
28595     }
28596     else
28597 	acdPromptStandardAlt(thys, ajStrGetPtr(refseqPrompt),
28598 			     ajStrGetPtr(refseqPromptAlt), &count);
28599 
28600     if(!acdAttrTestDefined(thys, "default") &&
28601        acdAttrTestDefined(thys, "nullok"))
28602 	acdPromptStandardAppend(thys, " (optional)");
28603 
28604     ajStrDel(&refseqPrompt);
28605     ajStrDel(&refseqPromptAlt);
28606 
28607     return thys->StdPrompt;
28608 }
28609 
28610 
28611 
28612 
28613 /* @funcstatic acdPromptTaxon *************************************************
28614 **
28615 ** Sets the default prompt for this ACD object to be an NCBI taxonomy entry
28616 ** prompt with "first", "second" etc. added.
28617 **
28618 ** @param [u] thys [AcdPAcd] Current ACD object.
28619 ** @return [const AjPStr] Generated standard prompt
28620 **
28621 ** @release 6.4.0
28622 ** @@
28623 ******************************************************************************/
28624 
acdPromptTaxon(AcdPAcd thys)28625 static const AjPStr acdPromptTaxon(AcdPAcd thys)
28626 {
28627     static ajint count=0;
28628     AjPStr taxPrompt = NULL;
28629     AjPStr taxPromptAlt = NULL;
28630     const AjPStr knowntype;
28631     ajint maxreads = 0;
28632 
28633     acdAttrToInt(thys, "maxreads", 1, &maxreads);
28634 
28635     knowntype = acdKnowntypeDesc(thys);
28636 
28637     taxPrompt = ajStrNewRes(32);
28638     taxPromptAlt = ajStrNewRes(32);
28639 
28640     if(ajStrGetLen(knowntype))
28641 	ajFmtPrintAppS(&taxPromptAlt, "%S ", knowntype);
28642 
28643     ajFmtPrintAppS(&taxPromptAlt, "taxon");
28644 
28645     if(maxreads > 1)
28646 	ajStrAppendC(&taxPromptAlt, "(s)");
28647 
28648     ajFmtPrintS(&taxPrompt, "Input %S", taxPromptAlt);
28649 
28650     if(knowntype)
28651     {
28652 	count++;
28653 	acdPromptStandardS(thys, taxPromptAlt);
28654     }
28655     else
28656 	acdPromptStandardAlt(thys, ajStrGetPtr(taxPrompt),
28657 			     ajStrGetPtr(taxPromptAlt), &count);
28658 
28659     if(!acdAttrTestDefined(thys, "default") &&
28660        acdAttrTestDefined(thys, "nullok"))
28661 	acdPromptStandardAppend(thys, " (optional)");
28662 
28663     ajStrDel(&taxPrompt);
28664     ajStrDel(&taxPromptAlt);
28665 
28666     return thys->StdPrompt;
28667 }
28668 
28669 
28670 
28671 
28672 /* @funcstatic acdPromptText **************************************************
28673 **
28674 ** Sets the default prompt for this ACD object to be a text entry
28675 ** prompt with "first", "second" etc. added.
28676 **
28677 ** @param [u] thys [AcdPAcd] Current ACD object.
28678 ** @return [const AjPStr] Generated standard prompt
28679 **
28680 ** @release 6.4.0
28681 ** @@
28682 ******************************************************************************/
28683 
acdPromptText(AcdPAcd thys)28684 static const AjPStr acdPromptText(AcdPAcd thys)
28685 {
28686     static ajint count=0;
28687     AjPStr taxPrompt = NULL;
28688     AjPStr taxPromptAlt = NULL;
28689     const AjPStr knowntype;
28690     ajint maxreads = 0;
28691 
28692     acdAttrToInt(thys, "maxreads", 1, &maxreads);
28693 
28694     knowntype = acdKnowntypeDesc(thys);
28695 
28696     taxPrompt = ajStrNewRes(32);
28697     taxPromptAlt = ajStrNewRes(32);
28698 
28699     if(ajStrGetLen(knowntype))
28700 	ajFmtPrintAppS(&taxPromptAlt, "%S ", knowntype);
28701 
28702     ajFmtPrintAppS(&taxPromptAlt, "text");
28703 
28704     if(maxreads > 1)
28705 	ajStrAppendC(&taxPromptAlt, "(s)");
28706 
28707     ajFmtPrintS(&taxPrompt, "Input %S", taxPromptAlt);
28708 
28709     if(knowntype)
28710     {
28711 	count++;
28712 	acdPromptStandardS(thys, taxPromptAlt);
28713     }
28714     else
28715 	acdPromptStandardAlt(thys, ajStrGetPtr(taxPrompt),
28716 			     ajStrGetPtr(taxPromptAlt), &count);
28717 
28718     if(!acdAttrTestDefined(thys, "default") &&
28719        acdAttrTestDefined(thys, "nullok"))
28720 	acdPromptStandardAppend(thys, " (optional)");
28721 
28722     ajStrDel(&taxPrompt);
28723     ajStrDel(&taxPromptAlt);
28724 
28725     return thys->StdPrompt;
28726 }
28727 
28728 
28729 
28730 
28731 /* @funcstatic acdPromptUrl ***************************************************
28732 **
28733 ** Sets the default prompt for this ACD object to be a URL data entry
28734 ** prompt with "first", "second" etc. added.
28735 **
28736 ** @param [u] thys [AcdPAcd] Current ACD object.
28737 ** @return [const AjPStr] Generated standard prompt
28738 **
28739 ** @release 6.4.0
28740 ** @@
28741 ******************************************************************************/
28742 
acdPromptUrl(AcdPAcd thys)28743 static const AjPStr acdPromptUrl(AcdPAcd thys)
28744 {
28745     static ajint count=0;
28746     AjPStr urlPrompt = NULL;
28747     AjPStr urlPromptAlt = NULL;
28748     const AjPStr knowntype;
28749     ajint maxreads = 0;
28750 
28751     acdAttrToInt(thys, "maxreads", 1, &maxreads);
28752 
28753     knowntype = acdKnowntypeDesc(thys);
28754 
28755     urlPrompt = ajStrNewRes(32);
28756     urlPromptAlt = ajStrNewRes(32);
28757 
28758     if(ajStrGetLen(knowntype))
28759 	ajFmtPrintAppS(&urlPromptAlt, "%S ", knowntype);
28760 
28761     ajFmtPrintAppS(&urlPromptAlt, "url");
28762 
28763     if(maxreads > 1)
28764 	ajStrAppendC(&urlPromptAlt, "(s)");
28765 
28766     ajFmtPrintS(&urlPrompt, "Input %S", urlPromptAlt);
28767 
28768     if(knowntype)
28769     {
28770 	count++;
28771 	acdPromptStandardS(thys, urlPromptAlt);
28772     }
28773     else
28774 	acdPromptStandardAlt(thys, ajStrGetPtr(urlPrompt),
28775 			     ajStrGetPtr(urlPromptAlt), &count);
28776 
28777     if(!acdAttrTestDefined(thys, "default") &&
28778        acdAttrTestDefined(thys, "nullok"))
28779 	acdPromptStandardAppend(thys, " (optional)");
28780 
28781     ajStrDel(&urlPrompt);
28782     ajStrDel(&urlPromptAlt);
28783 
28784     return thys->StdPrompt;
28785 }
28786 
28787 
28788 
28789 
28790 /* @funcstatic acdPromptVariation *********************************************
28791 **
28792 ** Sets the default prompt for this ACD object to be a variation entry
28793 ** prompt with "first", "second" etc. added.
28794 **
28795 ** @param [u] thys [AcdPAcd] Current ACD object.
28796 ** @return [const AjPStr] Generated standard prompt
28797 **
28798 ** @release 6.4.0
28799 ** @@
28800 ******************************************************************************/
28801 
acdPromptVariation(AcdPAcd thys)28802 static const AjPStr acdPromptVariation(AcdPAcd thys)
28803 {
28804     static ajint count=0;
28805     AjPStr varPrompt = NULL;
28806     AjPStr varPromptAlt = NULL;
28807     const AjPStr knowntype;
28808     ajint maxreads = 0;
28809 
28810     acdAttrToInt(thys, "maxreads", 1, &maxreads);
28811 
28812     knowntype = acdKnowntypeDesc(thys);
28813 
28814     varPrompt = ajStrNewRes(32);
28815     varPromptAlt = ajStrNewRes(32);
28816 
28817     if(ajStrGetLen(knowntype))
28818 	ajFmtPrintAppS(&varPromptAlt, "%S ", knowntype);
28819 
28820     ajFmtPrintAppS(&varPromptAlt, "variation");
28821 
28822     if(maxreads > 1)
28823 	ajStrAppendC(&varPromptAlt, "(s)");
28824 
28825     ajFmtPrintS(&varPrompt, "Input %S", varPromptAlt);
28826 
28827     if(knowntype)
28828     {
28829 	count++;
28830 	acdPromptStandardS(thys, varPromptAlt);
28831     }
28832     else
28833 	acdPromptStandardAlt(thys, ajStrGetPtr(varPrompt),
28834 			     ajStrGetPtr(varPromptAlt), &count);
28835 
28836     if(!acdAttrTestDefined(thys, "default") &&
28837        acdAttrTestDefined(thys, "nullok"))
28838 	acdPromptStandardAppend(thys, " (optional)");
28839 
28840     ajStrDel(&varPrompt);
28841     ajStrDel(&varPromptAlt);
28842 
28843     return thys->StdPrompt;
28844 }
28845 
28846 
28847 
28848 
28849 /* @funcstatic acdPromptXml ***************************************************
28850 **
28851 ** Sets the default prompt for this ACD object to be a xml
28852 ** prompt with "first", "second" etc. added.
28853 **
28854 ** @param [u] thys [AcdPAcd] Current ACD object.
28855 ** @return [const AjPStr] Generated standard prompt
28856 **
28857 ** @release 6.6.0
28858 ** @@
28859 ******************************************************************************/
28860 
acdPromptXml(AcdPAcd thys)28861 static const AjPStr acdPromptXml(AcdPAcd thys)
28862 {
28863     static ajint count=0;
28864     AjPStr xmlPrompt = NULL;
28865     AjPStr xmlPromptAlt = NULL;
28866     const AjPStr knowntype;
28867     ajint maxreads = 0;
28868 
28869     acdAttrToInt(thys, "maxreads", 1, &maxreads);
28870 
28871     knowntype = acdKnowntypeDesc(thys);
28872 
28873     xmlPrompt = ajStrNewRes(32);
28874     xmlPromptAlt = ajStrNewRes(32);
28875 
28876     if(ajStrGetLen(knowntype))
28877 	ajFmtPrintAppS(&xmlPromptAlt, "%S ", knowntype);
28878 
28879     ajFmtPrintAppS(&xmlPromptAlt, "xml");
28880 
28881     if(maxreads > 1)
28882 	ajStrAppendC(&xmlPromptAlt, "(s)");
28883 
28884     ajFmtPrintS(&xmlPrompt, "Input %S", xmlPromptAlt);
28885 
28886     if(knowntype)
28887     {
28888 	count++;
28889 	acdPromptStandardS(thys, xmlPromptAlt);
28890     }
28891     else
28892 	acdPromptStandardAlt(thys, ajStrGetPtr(xmlPrompt),
28893 			     ajStrGetPtr(xmlPromptAlt), &count);
28894 
28895     if(!acdAttrTestDefined(thys, "default") &&
28896        acdAttrTestDefined(thys, "nullok"))
28897 	acdPromptStandardAppend(thys, " (optional)");
28898 
28899     ajStrDel(&xmlPrompt);
28900     ajStrDel(&xmlPromptAlt);
28901 
28902     return thys->StdPrompt;
28903 }
28904 
28905 
28906 
28907 
28908 /* @funcstatic acdPromptStandard **********************************************
28909 **
28910 ** Sets the default prompt for this ACD object to be an output
28911 ** file with "first", "second" etc. added.
28912 **
28913 ** @param [u] thys [AcdPAcd] Current ACD object.
28914 ** @param [r] type [const char*] Data type for prompt
28915 ** @param [w] count [ajint*] count for number of calls
28916 ** @return [void]
28917 **
28918 ** @release 2.9.0
28919 ** @@
28920 ******************************************************************************/
28921 
acdPromptStandard(AcdPAcd thys,const char * type,ajint * count)28922 static void acdPromptStandard(AcdPAcd thys, const char* type, ajint* count)
28923 {
28924     AjPStr *prompt;
28925 
28926     (*count)++;
28927 
28928     acdLog("acdPromptStandard '%s' count %d\n", type, *count);
28929 
28930     if(!thys->DefStr)
28931     {
28932 	acdLog("acdPromptStandard '%s' thys->DefStr NULL\n", type);
28933 	return;
28934     }
28935 
28936     prompt = &thys->DefStr[DEF_PROMPT];
28937 
28938     if(ajStrGetLen(*prompt))
28939     {
28940 	acdLog("acdPromptStandard '%s' found thys->DefStr[DEF_PROMPT] '%S'\n",
28941 	       type, *prompt);
28942 	/*ajStrTrace(*prompt);*/
28943 	/*ajStrTrace(thys->DefStr[DEF_PROMPT]);*/
28944 	return;
28945     }
28946 
28947     switch(*count)
28948     {
28949         case 1:
28950             ajFmtPrintS(&thys->StdPrompt,
28951                         "%s", type);
28952             ajStrFmtTitle(&thys->StdPrompt);
28953             break;
28954         case 2:
28955             ajFmtPrintS(&thys->StdPrompt,
28956                             "Second %s", type);
28957             break;
28958         case 3:
28959             ajFmtPrintS(&thys->StdPrompt,
28960                             "Third %s", type);
28961             break;
28962         case 11:
28963         case 12:
28964         case 13:
28965             ajFmtPrintS(&thys->StdPrompt,
28966                         "%dth %s", count, type);
28967             break;
28968         default:
28969             switch(*count % 10)
28970             {
28971                 case 1:
28972                     ajFmtPrintS(&thys->StdPrompt,
28973                                     "%dst %s", count, type);
28974                     break;
28975                 case 2:
28976                     ajFmtPrintS(&thys->StdPrompt,
28977                                     "%dnd %s", count, type);
28978                     break;
28979                 case 3:
28980                     ajFmtPrintS(&thys->StdPrompt,
28981                                     "%drd %s", count, type);
28982                     break;
28983                 default:
28984                     ajFmtPrintS(&thys->StdPrompt,
28985                                      "%dth %s", count, type);
28986                     break;
28987             }
28988             break;
28989     }
28990 
28991     return;
28992 }
28993 
28994 
28995 
28996 
28997 /* @funcstatic acdPromptStandardAlt *******************************************
28998 **
28999 ** Sets the default prompt for this ACD object to as specified, with
29000 ** "second", "third" etc. added.
29001 **
29002 ** @param [u] thys [AcdPAcd] Current ACD object.
29003 ** @param [r] firsttype [const char*] Data type for prompt first time
29004 ** @param [r] type [const char*] Data type for prompt subsequent times
29005 ** @param [w] count [ajint*] count for number of calls
29006 ** @return [void]
29007 **
29008 ** @release 2.9.0
29009 ** @@
29010 ******************************************************************************/
29011 
acdPromptStandardAlt(AcdPAcd thys,const char * firsttype,const char * type,ajint * count)29012 static void acdPromptStandardAlt(AcdPAcd thys, const char* firsttype,
29013 				 const char* type, ajint* count)
29014 {
29015     AjPStr *prompt;
29016 
29017     (*count)++;
29018 
29019     acdLog("acdPromptStandardAlt '%s' count %d\n", type, *count);
29020 
29021     if(!thys->DefStr)
29022     {
29023 	acdLog("acdPromptStandardAlt '%s' thys->DefStr NULL\n", type);
29024 	return;
29025     }
29026 
29027     prompt = &thys->DefStr[DEF_PROMPT];
29028 
29029     if(ajStrGetLen(*prompt))
29030     {
29031 	acdLog("acdPromptStandardAlt '%s' "
29032 	       "found thys->DefStr[DEF_PROMPT] '%S'\n",
29033 	       type, *prompt);
29034 	/*ajStrTrace(*prompt);*/
29035 	/*ajStrTrace(thys->DefStr[DEF_PROMPT]);*/
29036 	return;
29037     }
29038 
29039     switch(*count)
29040     {
29041         case 1:
29042             ajFmtPrintS(&thys->StdPrompt,
29043                         "%s", firsttype);
29044             break;
29045         case 2:
29046             ajFmtPrintS(&thys->StdPrompt,
29047                             "Second %s", type);
29048             break;
29049         case 3:
29050             ajFmtPrintS(&thys->StdPrompt,
29051                             "Third %s", type);
29052             break;
29053         case 11:
29054         case 12:
29055         case 13:
29056             ajFmtPrintS(&thys->StdPrompt,
29057                         "%dth %s", count, type);
29058             break;
29059         default:
29060             switch(*count % 10)
29061             {
29062                 case 1:
29063                     ajFmtPrintS(&thys->StdPrompt,
29064                                     "%dst %s", count, type);
29065                     break;
29066                 case 2:
29067                     ajFmtPrintS(&thys->StdPrompt,
29068                                     "%dnd %s", count, type);
29069                     break;
29070                 case 3:
29071                     ajFmtPrintS(&thys->StdPrompt,
29072                                     "%drd %s", count, type);
29073                     break;
29074                 default:
29075                     ajFmtPrintS(&thys->StdPrompt,
29076                                      "%dth %s", count, type);
29077                     break;
29078             }
29079             break;
29080     }
29081 
29082     return;
29083 }
29084 
29085 
29086 
29087 
29088 /* @funcstatic acdPromptStandardAppend ****************************************
29089 **
29090 ** Appends to the default prompt for this ACD object
29091 **
29092 ** @param [u] thys [AcdPAcd] Current ACD object.
29093 ** @param [r] str[const char*] Suffix to append to prompt
29094 ** @return [void]
29095 **
29096 ** @release 4.0.0
29097 ** @@
29098 ******************************************************************************/
29099 
acdPromptStandardAppend(AcdPAcd thys,const char * str)29100 static void acdPromptStandardAppend(AcdPAcd thys, const char* str)
29101 {
29102     ajStrAppendC(&thys->StdPrompt, str);
29103 }
29104 
29105 
29106 
29107 
29108 /* @funcstatic acdPromptStandardS *********************************************
29109 **
29110 ** Appends to the default prompt for this ACD object
29111 **
29112 ** @param [u] thys [AcdPAcd] Current ACD object.
29113 ** @param [r] str [const AjPStr] Data type for prompt
29114 ** @return [void]
29115 **
29116 ** @release 4.0.0
29117 ** @@
29118 ******************************************************************************/
29119 
acdPromptStandardS(AcdPAcd thys,const AjPStr str)29120 static void acdPromptStandardS(AcdPAcd thys, const AjPStr str)
29121 {
29122     ajStrAssignS(&thys->StdPrompt, str);
29123 }
29124 
29125 
29126 
29127 
29128 /* @funcstatic acdPromptOutfile ***********************************************
29129 **
29130 ** Sets the default prompt for this ACD object to be an output
29131 ** file with "first", "second" etc. added.
29132 **
29133 ** @param [u] thys [AcdPAcd] Current ACD object.
29134 ** @return [const AjPStr] Generated standard prompt
29135 **
29136 ** @release 1.0.0
29137 ** @@
29138 ******************************************************************************/
29139 
acdPromptOutfile(AcdPAcd thys)29140 static const AjPStr acdPromptOutfile(AcdPAcd thys)
29141 {
29142     static ajint count = 0;
29143 
29144     const AjPStr knowntype;
29145 
29146     knowntype = acdKnowntypeDesc(thys);
29147 
29148     if(ajStrGetLen(knowntype))
29149     {
29150 	count++;
29151 	acdPromptStandardS(thys, knowntype);
29152 
29153 	if(ajStrSuffixC(knowntype, " output"))
29154 	   acdPromptStandardAppend(thys, " file");
29155 	else
29156 	   acdPromptStandardAppend(thys, " output file");
29157     }
29158     else
29159 	acdPromptStandard(thys, "output file", &count);
29160 
29161     if(!acdAttrTestDefined(thys, "default") &&
29162        acdAttrTestDefined(thys, "nullok"))
29163 	acdPromptStandardAppend(thys, " (optional)");
29164 
29165     return thys->StdPrompt;
29166 }
29167 
29168 
29169 
29170 
29171 /* @funcstatic acdPromptInfile ************************************************
29172 **
29173 ** Sets the default prompt for this ACD object to be an input
29174 ** file with "first", "second" etc. added.
29175 **
29176 ** @param [u] thys [AcdPAcd] Current ACD object.
29177 ** @return [const AjPStr] Generated standard prompt
29178 **
29179 ** @release 1.0.0
29180 ** @@
29181 ******************************************************************************/
29182 
acdPromptInfile(AcdPAcd thys)29183 static const AjPStr acdPromptInfile(AcdPAcd thys)
29184 {
29185     static ajint count = 0;
29186 
29187     const AjPStr knowntype;
29188 
29189     knowntype = acdKnowntypeDesc(thys);
29190 
29191     if(ajStrGetLen(knowntype))
29192     {
29193 	count++;
29194 	acdPromptStandardS(thys, knowntype);
29195 
29196 	if(!ajStrSuffixC(knowntype, " file"))
29197 	   acdPromptStandardAppend(thys, " file");
29198     }
29199     else
29200 	acdPromptStandard(thys, "input file", &count);
29201 
29202     if(!acdAttrTestDefined(thys, "default") &&
29203        acdAttrTestDefined(thys, "nullok"))
29204 	acdPromptStandardAppend(thys, " (optional)");
29205 
29206     return thys->StdPrompt;
29207 }
29208 
29209 
29210 
29211 
29212 /* @funcstatic acdPromptDatafile **********************************************
29213 **
29214 ** Sets the default prompt for this ACD object to be an input data
29215 ** file with "first", "second" etc. added.
29216 **
29217 ** @param [u] thys [AcdPAcd] Current ACD object.
29218 ** @return [const AjPStr] Generated standard prompt
29219 **
29220 ** @release 4.0.0
29221 ** @@
29222 ******************************************************************************/
29223 
acdPromptDatafile(AcdPAcd thys)29224 static const AjPStr acdPromptDatafile(AcdPAcd thys)
29225 {
29226     static ajint count = 0;
29227 
29228     const AjPStr knowntype;
29229 
29230     knowntype = acdKnowntypeDesc(thys);
29231 
29232     if(ajStrGetLen(knowntype))
29233     {
29234 	count++;
29235 	acdPromptStandardS(thys, knowntype);
29236 
29237 	if(ajStrSuffixC(knowntype, " data"))
29238 	   acdPromptStandardAppend(thys, " file");
29239 	else
29240 	   acdPromptStandardAppend(thys, " data file");
29241     }
29242     else
29243 	acdPromptStandard(thys, "data file", &count);
29244 
29245     if(!acdAttrTestDefined(thys, "default") &&
29246        acdAttrTestDefined(thys, "nullok"))
29247 	acdPromptStandardAppend(thys, " (optional)");
29248 
29249     return thys->StdPrompt;
29250 }
29251 
29252 
29253 
29254 
29255 /* @funcstatic acdPromptMatrix ************************************************
29256 **
29257 ** Sets the default prompt for this ACD object to be an input data
29258 ** file with "first", "second" etc. added.
29259 **
29260 ** @param [u] thys [AcdPAcd] Current ACD object.
29261 ** @return [const AjPStr] Generated standard prompt
29262 **
29263 ** @release 4.0.0
29264 ** @@
29265 ******************************************************************************/
29266 
acdPromptMatrix(AcdPAcd thys)29267 static const AjPStr acdPromptMatrix(AcdPAcd thys)
29268 {
29269     static ajint count = 0;
29270     AjBool protein = ajFalse;
29271 
29272     const AjPStr knowntype;
29273 
29274     acdAttrToBool(thys, "protein", ajFalse, &protein);
29275 
29276     knowntype = acdKnowntypeDesc(thys);
29277 
29278     if(ajStrGetLen(knowntype))
29279     {
29280 	count++;
29281 	acdPromptStandardS(thys, knowntype);
29282 
29283 	if(!ajStrSuffixC(knowntype, " file"))
29284 	   acdPromptStandardAppend(thys, " file");
29285     }
29286     else
29287     {
29288 	if(acdDoValid)
29289 	    acdPromptStandard(thys, "comparison matrix file",
29290 			      &count);
29291 	else
29292 	{
29293 	    if(protein)
29294 		acdPromptStandard(thys, "(protein) comparison matrix file",
29295 				  &count);
29296 	    else
29297 		acdPromptStandard(thys, "(nucleotide) comparison matrix file",
29298 				  &count);
29299 	}
29300     }
29301 
29302     if(!acdAttrTestDefined(thys, "default") &&
29303        acdAttrTestDefined(thys, "nullok"))
29304 	acdPromptStandardAppend(thys, " (optional)");
29305 
29306     return thys->StdPrompt;
29307 }
29308 
29309 
29310 
29311 
29312 /* @funcstatic acdPromptDiscretestates ****************************************
29313 **
29314 ** Sets the default prompt for this ACD object to be an input discrete states
29315 ** file with "first", "second" etc. added.
29316 **
29317 ** @param [u] thys [AcdPAcd] Current ACD object.
29318 ** @return [const AjPStr] Generated standard prompt
29319 **
29320 ** @release 4.0.0
29321 ** @@
29322 ******************************************************************************/
29323 
acdPromptDiscretestates(AcdPAcd thys)29324 static const AjPStr acdPromptDiscretestates(AcdPAcd thys)
29325 {
29326     static ajint count = 0;
29327 
29328     const AjPStr knowntype;
29329 
29330     knowntype = acdKnowntypeDesc(thys);
29331 
29332     if(ajStrGetLen(knowntype))
29333     {
29334 	count++;
29335 	acdPromptStandardS(thys, knowntype);
29336 	if(!ajStrSuffixC(knowntype, " file"))
29337 	   acdPromptStandardAppend(thys, " file");
29338     }
29339     else
29340 	acdPromptStandard(thys, "discrete states file", &count);
29341 
29342     if(!acdAttrTestDefined(thys, "default") &&
29343        acdAttrTestDefined(thys, "nullok"))
29344 	acdPromptStandardAppend(thys, " (optional)");
29345 
29346     return thys->StdPrompt;
29347 }
29348 
29349 
29350 
29351 
29352 /* @funcstatic acdPromptDistances *********************************************
29353 **
29354 ** Sets the default prompt for this ACD object to be an input distances
29355 ** file with "first", "second" etc. added.
29356 **
29357 ** @param [u] thys [AcdPAcd] Current ACD object.
29358 ** @return [const AjPStr] Generated standard prompt
29359 **
29360 ** @release 4.0.0
29361 ** @@
29362 ******************************************************************************/
29363 
acdPromptDistances(AcdPAcd thys)29364 static const AjPStr acdPromptDistances(AcdPAcd thys)
29365 {
29366     static ajint count = 0;
29367 
29368     const AjPStr knowntype;
29369 
29370     knowntype = acdKnowntypeDesc(thys);
29371 
29372     if(ajStrGetLen(knowntype))
29373     {
29374 	count++;
29375 	acdPromptStandardS(thys, knowntype);
29376 
29377 	if(!ajStrSuffixC(knowntype, " file"))
29378 	   acdPromptStandardAppend(thys, " file");
29379     }
29380     else
29381 	acdPromptStandard(thys, "distances file", &count);
29382 
29383     if(!acdAttrTestDefined(thys, "default") &&
29384        acdAttrTestDefined(thys, "nullok"))
29385 	acdPromptStandardAppend(thys, " (optional)");
29386 
29387     return thys->StdPrompt;
29388 }
29389 
29390 
29391 
29392 
29393 /* @funcstatic acdPromptFrequencies *******************************************
29394 **
29395 ** Sets the default prompt for this ACD object to be an input frequencies
29396 ** file with "first", "second" etc. added.
29397 **
29398 ** @param [u] thys [AcdPAcd] Current ACD object.
29399 ** @return [const AjPStr] Generated standard prompt
29400 **
29401 ** @release 4.0.0
29402 ** @@
29403 ******************************************************************************/
29404 
acdPromptFrequencies(AcdPAcd thys)29405 static const AjPStr acdPromptFrequencies(AcdPAcd thys)
29406 {
29407     static ajint count = 0;
29408 
29409     const AjPStr knowntype;
29410 
29411     knowntype = acdKnowntypeDesc(thys);
29412 
29413     if(ajStrGetLen(knowntype))
29414     {
29415 	count++;
29416 	acdPromptStandardS(thys, knowntype);
29417 
29418 	if(!ajStrSuffixC(knowntype, " file"))
29419 	   acdPromptStandardAppend(thys, " file");
29420     }
29421     else
29422 	acdPromptStandard(thys, "frequencies file", &count);
29423 
29424     if(!acdAttrTestDefined(thys, "default") &&
29425        acdAttrTestDefined(thys, "nullok"))
29426 	acdPromptStandardAppend(thys, " (optional)");
29427 
29428     return thys->StdPrompt;
29429 }
29430 
29431 
29432 
29433 
29434 /* @funcstatic acdPromptProperties ********************************************
29435 **
29436 ** Sets the default prompt for this ACD object to be an input properties
29437 ** file with "first", "second" etc. added.
29438 **
29439 ** @param [u] thys [AcdPAcd] Current ACD object.
29440 ** @return [const AjPStr] Generated standard prompt
29441 **
29442 ** @release 4.0.0
29443 ** @@
29444 ******************************************************************************/
29445 
acdPromptProperties(AcdPAcd thys)29446 static const AjPStr acdPromptProperties(AcdPAcd thys)
29447 {
29448     static ajint count = 0;
29449 
29450     const AjPStr knowntype;
29451 
29452     knowntype = acdKnowntypeDesc(thys);
29453 
29454     if(ajStrGetLen(knowntype))
29455     {
29456 	count++;
29457 	acdPromptStandardS(thys, knowntype);
29458 
29459 	if(!ajStrSuffixC(knowntype, " file"))
29460 	   acdPromptStandardAppend(thys, " file");
29461     }
29462     else
29463 	acdPromptStandard(thys, "properties file", &count);
29464 
29465     if(!acdAttrTestDefined(thys, "default") &&
29466        acdAttrTestDefined(thys, "nullok"))
29467 	acdPromptStandardAppend(thys, " (optional)");
29468 
29469     return thys->StdPrompt;
29470 }
29471 
29472 
29473 
29474 
29475 /* @funcstatic acdPromptPattern ***********************************************
29476 **
29477 ** Sets the default prompt for this ACD object to be a pattern string or
29478 ** file with "first", "second" etc. added.
29479 **
29480 ** @param [u] thys [AcdPAcd] Current ACD object.
29481 ** @return [const AjPStr] Generated standard prompt
29482 **
29483 ** @release 4.0.0
29484 ** @@
29485 ******************************************************************************/
29486 
acdPromptPattern(AcdPAcd thys)29487 static const AjPStr acdPromptPattern(AcdPAcd thys)
29488 {
29489     static ajint count = 0;
29490     AjPStr type = NULL;
29491 
29492     const AjPStr knowntype;
29493 
29494     acdAttrToStr(thys, "type", "", &type);
29495 
29496     knowntype = acdKnowntypeDesc(thys);
29497 
29498     if(ajStrGetLen(knowntype))
29499     {
29500 	count++;
29501 	acdPromptStandardS(thys, knowntype);
29502 
29503 	if(!ajStrSuffixC(knowntype, " pattern"))
29504 	   acdPromptStandardAppend(thys, " pattern");
29505     }
29506     else
29507     {
29508 	if(ajStrPrefixCaseC(type, "p"))
29509 	    acdPromptStandard(thys,
29510 			      "protein pattern string or @file", &count);
29511 	else if(ajStrPrefixCaseC(type, "n"))
29512 	    acdPromptStandard(thys,
29513 			      "nucleotide pattern string or @file", &count);
29514 	else
29515 	    acdPromptStandard(thys,
29516 			      "pattern string or @file", &count);
29517     }
29518 
29519     if(!acdAttrTestDefined(thys, "default") &&
29520        acdAttrTestDefined(thys, "nullok"))
29521 	acdPromptStandardAppend(thys, " (optional)");
29522 
29523     return thys->StdPrompt;
29524 }
29525 
29526 
29527 
29528 
29529 /* @funcstatic acdPromptRegexp ************************************************
29530 **
29531 ** Sets the default prompt for this ACD object to be a regular expression
29532 ** string or file with "first", "second" etc. added.
29533 **
29534 ** @param [u] thys [AcdPAcd] Current ACD object.
29535 ** @return [const AjPStr] Generated standard prompt
29536 **
29537 ** @release 4.0.0
29538 ** @@
29539 ******************************************************************************/
29540 
acdPromptRegexp(AcdPAcd thys)29541 static const AjPStr acdPromptRegexp(AcdPAcd thys)
29542 {
29543     static ajint count = 0;
29544     AjPStr type = NULL;
29545 
29546     const AjPStr knowntype;
29547 
29548     acdAttrToStr(thys, "type", "", &type);
29549 
29550     knowntype = acdKnowntypeDesc(thys);
29551 
29552     if(ajStrGetLen(knowntype))
29553     {
29554 	count++;
29555 	acdPromptStandardS(thys, knowntype);
29556 
29557 	if(!ajStrSuffixC(knowntype, " regular expression"))
29558 	   acdPromptStandardAppend(thys, " regular expression");
29559     }
29560     else
29561     {
29562 	if(ajStrPrefixCaseC(type, "p"))
29563 	    acdPromptStandard(thys,
29564 			      "protein regular expression string or @file",
29565 			      &count);
29566 	else if(ajStrPrefixCaseC(type, "n"))
29567 	    acdPromptStandard(thys,
29568 			      "nucleotide regular expression string or @file",
29569 			      &count);
29570 	else
29571 	    acdPromptStandard(thys,
29572 			      "regular expression string or @file",
29573 			      &count);
29574     }
29575 
29576     if(!acdAttrTestDefined(thys, "default") &&
29577        acdAttrTestDefined(thys, "nullok"))
29578 	acdPromptStandardAppend(thys, " (optional)");
29579 
29580     return thys->StdPrompt;
29581 }
29582 
29583 
29584 
29585 
29586 /* @funcstatic acdHelpTextResource ********************************************
29587 **
29588 ** Sets the help text for this ACD object to be a data resource description
29589 **
29590 ** @param [r] thys [const AcdPAcd] Current ACD object.
29591 ** @param [w] Pstr [AjPStr*] Help text
29592 ** @return [void]
29593 **
29594 ** @release 6.4.0
29595 ** @@
29596 ******************************************************************************/
29597 
acdHelpTextResource(const AcdPAcd thys,AjPStr * Pstr)29598 static void acdHelpTextResource(const AcdPAcd thys, AjPStr* Pstr)
29599 {
29600     ajint maxreads = 0;
29601 
29602     ajStrAssignClear(Pstr);
29603 
29604     acdAttrToInt(thys, "maxreads", 1, &maxreads);
29605 
29606     if(maxreads <= 1)
29607         ajStrAssignC(Pstr, "data resource");
29608     else
29609         ajStrAssignC(Pstr, "data resource(s)");
29610 
29611     ajStrFmtTitle(Pstr);
29612 
29613     ajStrAppendC(Pstr,
29614 		 " filename and optional format, or reference (input query)");
29615 
29616     return;
29617 }
29618 
29619 
29620 
29621 
29622 /* @funcstatic acdPromptResource **********************************************
29623 **
29624 ** Sets the default prompt for this ACD object to be a data resource
29625 ** prompt with "first", "second" etc. added.
29626 **
29627 ** @param [u] thys [AcdPAcd] Current ACD object.
29628 ** @return [const AjPStr] Generated standard prompt
29629 **
29630 ** @release 6.4.0
29631 ** @@
29632 ******************************************************************************/
29633 
acdPromptResource(AcdPAcd thys)29634 static const AjPStr acdPromptResource(AcdPAcd thys)
29635 {
29636     static ajint count=0;
29637     AjPStr resourcePrompt = NULL;
29638     AjPStr resourcePromptAlt = NULL;
29639     const AjPStr knowntype;
29640     ajint maxreads = 0;
29641 
29642     acdAttrToInt(thys, "maxreads", 1, &maxreads);
29643 
29644     knowntype = acdKnowntypeDesc(thys);
29645 
29646     resourcePrompt = ajStrNewRes(32);
29647     resourcePromptAlt = ajStrNewRes(32);
29648 
29649     if(ajStrGetLen(knowntype))
29650 	ajFmtPrintAppS(&resourcePromptAlt, "%S ", knowntype);
29651 
29652     ajFmtPrintAppS(&resourcePromptAlt, "data resource");
29653 
29654     if(maxreads > 1)
29655 	ajStrAppendC(&resourcePromptAlt, "(s)");
29656 
29657     ajFmtPrintS(&resourcePrompt, "Input %S", resourcePromptAlt);
29658 
29659     if(knowntype)
29660     {
29661 	count++;
29662 	acdPromptStandardS(thys, resourcePromptAlt);
29663     }
29664     else
29665 	acdPromptStandardAlt(thys, ajStrGetPtr(resourcePrompt),
29666 			     ajStrGetPtr(resourcePromptAlt), &count);
29667 
29668     if(!acdAttrTestDefined(thys, "default") &&
29669        acdAttrTestDefined(thys, "nullok"))
29670 	acdPromptStandardAppend(thys, " (optional)");
29671 
29672     ajStrDel(&resourcePrompt);
29673     ajStrDel(&resourcePromptAlt);
29674 
29675     return thys->StdPrompt;
29676 }
29677 
29678 
29679 
29680 
29681 /* @funcstatic acdCodeGet *****************************************************
29682 **
29683 ** Translates a code into a message text using the code table
29684 ** for the current language.
29685 **
29686 ** @param [r] code [const AjPStr] Code name
29687 ** @param [w] msg [AjPStr*] Message text for this code in current language
29688 ** @return [AjBool] ajTrue on success
29689 **
29690 ** @release 1.0.0
29691 ** @@
29692 ******************************************************************************/
29693 
acdCodeGet(const AjPStr code,AjPStr * msg)29694 static AjBool acdCodeGet(const AjPStr code, AjPStr *msg)
29695 {
29696     const AjPStr value;	       /* not static - copy of a table text */
29697 
29698     AjBool ret = ajFalse;
29699 
29700     acdLog("acdCodeGet ('%S')\n", code);
29701 
29702     if(!acdCodeSet)
29703 	acdCodeInit();
29704 
29705     value = ajTableFetchS(acdCodeTable, code);
29706 
29707     if(value)
29708     {
29709 	ajStrAssignS(msg, value);
29710 	acdLog("%S value '%S'\n", code, *msg);
29711 	ret = ajTrue;
29712     }
29713 
29714     return ret;
29715 }
29716 
29717 
29718 
29719 
29720 /* @funcstatic acdCodeDef *****************************************************
29721 **
29722 ** Generates a default code name of 'def' + qualifier type.
29723 ** Translates into a message text using the code table
29724 ** for the current language.
29725 **
29726 ** @param [r] thys [const AcdPAcd] Current ACD object
29727 ** @param [w] msg [AjPStr*] Message text for default message
29728 **                          in current language
29729 ** @return [AjBool] ajTrue on success
29730 **
29731 ** @release 1.0.0
29732 ** @@
29733 ******************************************************************************/
29734 
acdCodeDef(const AcdPAcd thys,AjPStr * msg)29735 static AjBool acdCodeDef(const AcdPAcd thys, AjPStr *msg)
29736 {
29737     AjPStr code  = NULL;
29738     AjPStr value = NULL;
29739 
29740     AjBool ret = ajFalse;
29741 
29742     acdLog("acdCodeDef '%s'\n", acdType[thys->Type].Name);
29743 
29744     if(!acdCodeSet)
29745 	acdCodeInit();
29746 
29747     code = ajStrNewC("def");
29748     ajStrAppendC(&code, acdType[thys->Type].Name);
29749     ajStrFmtLower(&code);
29750     acdLog("look for defcode '%S'\n", code);
29751 
29752     if(acdCodeGet(code, &value))
29753     {
29754 	ajFmtPrintS(msg, "-%S : %S",
29755 		    thys->Name, value);
29756 	ajStrDel(&value);
29757 	ret = ajTrue;
29758     }
29759     else
29760 	acdLog("defcode not found '%S'\n", code);
29761 
29762     ajStrDel(&code);
29763 
29764     return ret;
29765 }
29766 
29767 
29768 
29769 
29770 /* @funcstatic acdHelpCodeDef *************************************************
29771 **
29772 ** Generates a default code name of 'help' + qualifier type.
29773 ** Translates into a message text using the code table
29774 ** for the current language.
29775 **
29776 ** @param [r] thys [const AcdPAcd] Current ACD object
29777 ** @param [w] msg [AjPStr*] Help text in current language
29778 ** @return [AjBool] ajTrue on success
29779 **
29780 ** @release 1.0.0
29781 ** @@
29782 ******************************************************************************/
29783 
acdHelpCodeDef(const AcdPAcd thys,AjPStr * msg)29784 static AjBool acdHelpCodeDef(const AcdPAcd thys, AjPStr *msg)
29785 {
29786     AjPStr code         = NULL;
29787     AjPStr value = NULL;
29788 
29789     AjBool ret = ajFalse;
29790 
29791     acdLog("acdHelpCodeDef '%s'\n", acdType[thys->Type].Name);
29792 
29793     if(!acdCodeSet)
29794 	acdCodeInit();
29795 
29796     code = ajStrNewC("help");
29797     ajStrAppendC(&code, acdType[thys->Type].Name);
29798     ajStrFmtLower(&code);
29799     acdLog("look for helpcode '%S'\n", code);
29800 
29801     if(acdCodeGet(code, &value))
29802     {
29803 	ajFmtPrintS(msg, "%S", value);
29804 	ajStrDel(&value);
29805 	ret = ajTrue;
29806     }
29807     else
29808 	acdLog("helpcode not found '%S'\n", code);
29809 
29810     ajStrDel(&code);
29811 
29812     return ret;
29813 }
29814 
29815 
29816 
29817 
29818 /* @funcstatic acdCodeInit ****************************************************
29819 **
29820 ** Sets up the code file data for the current language when needed
29821 **
29822 ** @return [void]
29823 **
29824 ** @release 1.0.0
29825 ** @@
29826 ******************************************************************************/
29827 
acdCodeInit(void)29828 static void acdCodeInit(void)
29829 {
29830     AjPFile codeFile           = NULL;
29831     AjPStr codeFName    = NULL;
29832     AjPStr codeRoot     = NULL;
29833     AjPStr codeRootInst = NULL;
29834     AjPStr codePack     = NULL;
29835     AjPStr codeCode     = NULL;
29836     AjPStr codeValue    = NULL;
29837     AjPStr codeLine     = NULL;
29838     AjPStr codeText     = NULL;
29839     AjPStr codeLanguage = NULL;
29840     AjPStr tmpstr = NULL;
29841     AjPRegexp codexp = NULL;
29842 
29843     if(acdCodeSet)
29844 	return;
29845 
29846     ajStrAssignS(&codePack, ajNamValuePackage());
29847     ajStrAssignS(&codeRootInst,ajNamValueInstalldir());
29848     ajDirnameFix(&codeRootInst);
29849 
29850     if(!ajNamGetValueC("language", &codeLanguage))
29851 	ajStrAssignC(&codeLanguage, "english");
29852 
29853     if(ajNamGetValueC("acdroot", &codeRoot))
29854     {
29855 	ajDirnameFix(&codeRoot);
29856 	ajFmtPrintS(&codeFName, "%Scodes.%S", codeRoot, codeLanguage);
29857 	codeFile = ajFileNewInNameS(codeFName);
29858 	acdLog("Code file in acdroot: '%S'\n", codeFName);
29859     }
29860     else
29861     {
29862 	ajFmtPrintS(&codeFName, "%Sshare/%S/acd/codes.%S",
29863 		    codeRootInst, codePack, codeLanguage);
29864 	acdLog("Code file installed: '%S'\n", codeFName);
29865 	codeFile = ajFileNewInNameS(codeFName);
29866 
29867 	if(!codeFile)
29868 	{
29869 	    acdLog("Code file '%S' not opened\n", codeFName);
29870 	    ajStrAssignS(&codeRoot, ajNamValueRootdir());
29871 	    ajDirnameFix(&codeRoot);
29872 	    ajFmtPrintS(&codeFName, "%Sacd/codes.%S", codeRoot, codeLanguage);
29873 	    acdLog("Code file from source dir: '%S'\n", codeFName);
29874 	    codeFile = ajFileNewInNameS(codeFName);
29875 	}
29876     }
29877 
29878     if(!codeFile)			/* test acdc-codemissing */
29879 	ajWarn("Code file %S not found", codeFName);
29880     else
29881 	acdLog("Code file %F used\n", codeFile);
29882 
29883     codeText = ajStrNew();
29884 
29885     /* fix by Nicolas Joly <njoly@pasteur.fr> */
29886 
29887     while(codeFile && ajReadlineTrim(codeFile, &codeLine))
29888 	if(ajStrCutComments(&codeLine))
29889 	{
29890 	    ajStrAppendS(&codeText, codeLine);
29891 	    ajStrAppendC(&codeText, " ");
29892 	}
29893 
29894     ajFileClose(&codeFile);
29895 
29896     ajStrDel(&codeLine);
29897 
29898     acdCodeTable = ajTablestrNewCase(100);
29899 
29900     codexp = ajRegCompC("^ *([^ ]+) +\"([^\"]*)\"");
29901 
29902     while(ajRegExec(codexp, codeText))
29903     {
29904 	codeCode = codeValue = NULL; /* need to save in table each time */
29905 	ajRegSubI(codexp, 1, &codeCode);
29906 	ajRegSubI(codexp, 2, &codeValue);
29907 	ajStrFmtLower(&codeCode);
29908 	ajTablePut(acdCodeTable, codeCode, codeValue);
29909 	acdLog("add to table %S '%S'\n", codeCode, codeValue);
29910 	ajRegPost(codexp, &tmpstr);
29911         ajStrAssignS(&codeText, tmpstr);
29912     }
29913 
29914     if(!ajStrIsWhite(codeText))		/* test acdc-codebad */
29915 	ajDie("Bad format in codes file %S after '%S \"%S\"'",
29916 	      codeFName, codeCode, codeValue);
29917 
29918     codeCode = codeValue = NULL; /* saved in the table */
29919 
29920     ajRegFree(&codexp);
29921     ajStrDel(&codeText);
29922     ajStrDel(&codeFName);
29923     ajStrDel(&codeRoot);
29924     ajStrDel(&codeRootInst);
29925     ajStrDel(&codePack);
29926     ajStrDel(&codeLanguage);
29927     ajStrDel(&tmpstr);
29928 
29929     acdCodeSet = ajTrue;
29930 
29931     return;
29932 }
29933 
29934 
29935 
29936 
29937 /* @funcstatic acdKnowntypeInit ***********************************************
29938 **
29939 ** Sets up the known type data
29940 **
29941 ** @return [void]
29942 **
29943 ** @release 4.0.0
29944 ** @@
29945 ******************************************************************************/
29946 
acdKnowntypeInit(void)29947 static void acdKnowntypeInit(void)
29948 {
29949     if(acdKnowntypeSet)
29950         return;
29951 
29952     acdReadKnowntype(&acdKnowntypeDescTable, &acdKnowntypeTypeTable);
29953     acdKnowntypeSet = ajTrue;
29954 
29955     return;
29956 }
29957 
29958 
29959 
29960 
29961 /* @funcstatic acdSetQualAppl *************************************************
29962 **
29963 ** Sets internal variables for the application booleans -debug etc.
29964 **
29965 ** @param [r] thys [const AcdPAcd] ACD object
29966 ** @param [r] val [AjBool] Value
29967 ** @return [AjBool] ajTrue if this was an application-wide variable.
29968 **
29969 ** @release 1.0.0
29970 ** @@
29971 ******************************************************************************/
29972 
acdSetQualAppl(const AcdPAcd thys,AjBool val)29973 static AjBool acdSetQualAppl(const AcdPAcd thys, AjBool val)
29974 {
29975     ajint i = 0;
29976     AjBool setval;
29977     AjPStr setstr = NULL;
29978     static AjPStr valstr = NULL;
29979     static AjPStr bufstr = NULL;
29980 
29981     acdLog("acdSetQualAppl '%S'\n", thys->Name);
29982 
29983     for(i=0; acdQualAppl[i].Name; i++)
29984     {
29985 	if(ajStrMatchC(thys->Name, acdQualAppl[i].Name))
29986 	{
29987 	    if(thys->Defined)	 /* User put it on the command line */
29988 	    {
29989 		setval = val;
29990 		acdLog("Appl qualifier defined %S = %b\n",
29991 		       thys->Name, setval);
29992 	    }
29993 	    else			/* look for a variable */
29994 	    {
29995 		ajFmtPrintS(&setstr, "%S", thys->Name);
29996 
29997 		if(ajNamGetValueS(setstr, &valstr))
29998 		{
29999 		    ajStrToBool(valstr, &setval);
30000 		    acdLog("Appl qualifier variable %S = %b\n",
30001 			   setstr, setval);
30002 		}
30003 		else	    /* nothing found, use the default value */
30004 		    setval = val;
30005 		ajStrDel(&setstr);
30006 	    }
30007 
30008 	    switch(i)	   /* see acdQualAppl for the correct order */
30009 	    {
30010                 case 0:
30011                     acdAuto = setval;
30012                     break;
30013                 case 1:
30014                     acdStdout = setval;
30015                     break;
30016                 case 2:
30017                     acdFilter = setval;
30018 
30019                     if(acdFilter)
30020                     {
30021                         acdAuto   = ajTrue;
30022                         acdStdout = ajTrue;
30023                     }
30024 
30025                     break;
30026                 case 3:
30027                     acdOptions = setval;
30028                     break;
30029                 case 4:
30030                     acdDebug = setval;
30031                     /* acdLog("acdSetQualAppl acdDebug %B\n", acdDebug); */
30032                     acdDebugSet = ajTrue;
30033                     if(ajNamGetValueC("debugbuffer", &bufstr))
30034                     {
30035                         ajStrToBool(bufstr, &acdDebugBuffer);
30036                     }
30037                     break;
30038 
30039                 case 5:
30040                     acdVerbose = setval;
30041                     break;
30042                 case 6:
30043                     acdDoHelp = setval;
30044                     break;
30045                 case 7:
30046                     AjErrorLevel.warning = setval;
30047                     break;
30048                 case 8:
30049                     AjErrorLevel.error = setval;
30050                     break;
30051                 case 9:
30052                     AjErrorLevel.fatal = setval;
30053                     break;
30054                 case 10:
30055                     AjErrorLevel.die = setval;
30056                     break;
30057 	    }
30058 
30059 	    return ajTrue;
30060 	}
30061     }
30062 
30063     return ajFalse;
30064 }
30065 
30066 
30067 
30068 
30069 /* @funcstatic acdSelectPrompt ************************************************
30070 **
30071 ** Present the options as a simple numbered list
30072 **
30073 ** @param [r] thys [const AcdPAcd] ACD object
30074 ** @return [void]
30075 **
30076 ** @release 1.0.0
30077 ** @@
30078 ******************************************************************************/
30079 
acdSelectPrompt(const AcdPAcd thys)30080 static void acdSelectPrompt(const AcdPAcd thys)
30081 {
30082     const AjPStr hdrstr;
30083     AjPStr delim = NULL;
30084     AjPStr value = NULL;
30085     AjPStrTok handle;
30086     AjPStr line = NULL;
30087     static const char* white = " \t\n\r";
30088     ajint i = 0;
30089 
30090     if(acdAuto)
30091         return;
30092 
30093     hdrstr = acdAttrValue(thys, "header");
30094 
30095     if(ajStrGetLen(hdrstr))
30096 	ajUserDumpS(hdrstr);
30097 
30098     ajStrAssignS(&delim,acdAttrValue(thys, "delimiter"));
30099 
30100     if(!ajStrGetLen(delim))
30101 	ajStrAssignC(&delim, ";");
30102 
30103     ajStrAssignS(&value, acdAttrValue(thys, "values"));
30104     acdVarResolve(&value);
30105 
30106     if(!ajStrGetLen(value))
30107 	if(!acdKnownValueSelect(thys, &value))
30108 	    acdError("No value defined for selection");
30109 
30110     handle = ajStrTokenNewS(value, delim);
30111 
30112     while(ajStrTokenNextFind(handle, &line))
30113     {
30114 	ajStrTrimC(&line, white);
30115 	ajUser("  %5d : %S", ++i, line);
30116     }
30117 
30118     ajStrTokenDel(&handle);
30119     ajStrDel(&line);
30120     ajStrDel(&value);
30121     ajStrDel(&delim);
30122 
30123     return;
30124 }
30125 
30126 
30127 
30128 
30129 /* @funcstatic acdListPrompt **************************************************
30130 **
30131 ** Present the options as a list with option codes selectable by the user
30132 **
30133 ** @param [r] thys [const AcdPAcd] ACD object
30134 ** @return [void]
30135 **
30136 ** @release 1.0.0
30137 ** @@
30138 ******************************************************************************/
30139 
acdListPrompt(const AcdPAcd thys)30140 static void acdListPrompt(const AcdPAcd thys)
30141 {
30142     const AjPStr hdrstr;
30143     AjPStr codedelim = NULL;
30144     AjPStr delim     = NULL;
30145 
30146     AjPStr value     = NULL;
30147     AjPStrTok handle;
30148     AjPStrTok codehandle;
30149 
30150     AjPStr line = NULL;
30151     AjPStr code = NULL;
30152     AjPStr desc = NULL;
30153     ajuint margin = 8;
30154 
30155     static const char* white = " \t\n\r";
30156 
30157     if(acdAuto)
30158 	return;
30159 
30160     hdrstr = acdAttrValue(thys, "header");
30161 
30162     if(ajStrGetLen(hdrstr))
30163 	ajUserDumpS(hdrstr);
30164 
30165     ajStrAssignS(&delim,acdAttrValue(thys, "delimiter"));
30166 
30167     if(!ajStrGetLen(delim))
30168     {
30169 	ajStrAssignC(&delim, ";");
30170     }
30171 
30172     ajStrAssignS(&codedelim,acdAttrValue(thys, "codedelimiter"));
30173 
30174     if(!ajStrGetLen(codedelim))
30175     {
30176 	ajStrAssignC(&codedelim, ":");
30177     }
30178 
30179     ajStrAssignS(&value, acdAttrValue(thys, "values"));
30180     acdVarResolve(&value);
30181 
30182     if(!ajStrGetLen(value))
30183 	if(!acdKnownValueList(thys, &value))
30184 	    acdError("No value defined for list");
30185 
30186     handle = ajStrTokenNewS(value, delim);
30187 
30188     while(ajStrTokenNextFind(handle, &line))
30189     {
30190 	codehandle = ajStrTokenNewS(line, codedelim);
30191 	ajStrTokenNextParse(codehandle, &code);
30192 	ajStrTrimC(&code, white);
30193 
30194         if(ajStrGetLen(code) > margin)
30195             margin = ajStrGetLen(code);
30196 
30197 	ajStrTokenDel(&codehandle);
30198     }
30199 
30200     ajStrTokenAssignS(&handle, value, delim);
30201 
30202     while(ajStrTokenNextFind(handle, &line))
30203     {
30204 	codehandle = ajStrTokenNewS(line, codedelim);
30205 	ajStrTokenNextParse(codehandle, &code);
30206 	ajStrTokenNextParseS(codehandle, delim, &desc);
30207 	ajStrTrimC(&code, white);
30208 	ajStrTrimC(&desc, white);
30209 	ajUser("  %*S : %S", margin, code, desc);
30210 	ajStrTokenDel(&codehandle);
30211     }
30212 
30213     ajStrTokenDel(&handle);
30214     ajStrDel(&line);
30215     ajStrDel(&code);
30216     ajStrDel(&desc);
30217 
30218     ajStrDel(&delim);
30219 
30220     ajStrDel(&codedelim);
30221 
30222     ajStrDel(&value);
30223     return;
30224 }
30225 
30226 
30227 
30228 
30229 /* @funcstatic acdListValue ***************************************************
30230 **
30231 ** Checks the user setting against the menu list of codes and descriptions.
30232 **
30233 ** An unambiguous match to the codes counts as valid.
30234 ** If this fails, an unambiguous match to the descriptions counts.
30235 **
30236 ** @param [r] thys [const AcdPAcd] ACD Object
30237 ** @param [r] min [ajint] Minimum number of values required
30238 ** @param [r] max [ajint] Maximum number of values required
30239 ** @param [r] reply [const AjPStr] Default value
30240 ** @return [AjPStr*] Array of accepted matches, ending with a NULL.
30241 **
30242 ** @release 1.0.0
30243 ** @@
30244 ******************************************************************************/
30245 
acdListValue(const AcdPAcd thys,ajint min,ajint max,const AjPStr reply)30246 static AjPStr* acdListValue(const AcdPAcd thys, ajint min, ajint max,
30247 			    const AjPStr reply)
30248 {
30249     AjPStr* val = NULL;
30250 
30251     AjPStr codedelim = NULL;
30252     AjPStr delim     = NULL;
30253     AjPStr value  = NULL;
30254     AjBool exactcase;
30255     AjPStrTok handle = NULL;
30256     AjPStrTok rephandle = NULL;
30257     AjPStrTok codehandle = NULL;
30258 
30259     AjPStr line      = NULL;
30260     AjPStr code      = NULL;
30261     AjPStr desc      = NULL;
30262     AjPList list            = NULL;
30263     AjPStr repstr    = NULL;
30264     AjPStr hitstr    = NULL;
30265     AjPStr validstr  = NULL;
30266     AjPStr hitstr1          = NULL;
30267     AjPStr hitstr2          = NULL;
30268     AjPStr ambigList = NULL;
30269     AjPStr repdelim  = NULL;
30270     static const char* white = " \t\n\r";
30271     ajint k = 0;
30272 
30273     ajint ifound = 0;
30274     ajint jfound = 0;
30275     ajint ilen;
30276     ajint itoken = 0;
30277 
30278     AjBool ok = ajTrue;
30279 
30280     list = ajListstrNew();
30281 
30282     acdAttrToBool(thys, "casesensitive", ajFalse, &exactcase);
30283 
30284     acdAttrValueStr(thys, "delimiter", ";", &delim);
30285     acdAttrValueStr(thys, "codedelimiter", ":", &codedelim);
30286 
30287     if(!repdelim)
30288     {
30289 	repdelim = ajStrNewRes(10);
30290 	ajStrAssignC(&repdelim, ",");
30291     }
30292 
30293     ajStrAssignS(&value,acdAttrValue(thys, "values"));
30294     acdVarResolve(&value);
30295 
30296     if(!ajStrGetLen(value))
30297 	if(!acdKnownValueList(thys, &value))
30298 	    acdError("No value defined for list");
30299 
30300     ambigList = ajStrNew();
30301     ajStrAssignClear(&validstr);
30302     rephandle = ajStrTokenNewS(reply, repdelim);
30303     while(ajStrTokenNextParse(rephandle, &repstr))
30304     {
30305 	itoken++;
30306 	acdLog("testing '%S'\n", repstr);
30307 	ajStrTokenAssignS(&handle,value, delim);
30308 	ifound = jfound = 0;
30309 	ajStrAssignClear(&validstr);
30310 
30311         if(ajStrMatchC(repstr, "*"))
30312         {
30313             while(ajStrTokenNextFind(handle, &line))
30314             {
30315                 ajStrTokenAssignS(&codehandle, line, codedelim);
30316                 ajStrTokenNextParse(codehandle, &code);
30317                 ajStrTrimC(&code, white);
30318 
30319                 ajStrAssignS(&hitstr, code);
30320                 ajListstrPushAppend(list, hitstr);
30321                 hitstr = NULL;
30322                 ajStrTokenReset(codehandle);
30323             }
30324         }
30325         else
30326         {
30327             while(ajStrTokenNextFind(handle, &line))
30328             {
30329                 ajStrTokenAssignS(&codehandle, line, codedelim);
30330                 ajStrTokenNextParse(codehandle, &code);
30331                 ajStrTokenNextParseS(codehandle, delim, &desc);
30332                 ajStrTrimC(&code, white);
30333                 ajStrTrimC(&desc, white);
30334 
30335                 if(ajStrGetLen(validstr))
30336                     ajStrAppendK(&validstr, ',');
30337 
30338                 ajStrAppendS(&validstr, code);
30339 
30340                 if(ajStrMatchS(code, repstr) ||
30341                    (!exactcase && ajStrMatchCaseS(code, repstr)))
30342                 {
30343                     ifound = 1;
30344                     ajStrAssignS(&hitstr1, code);
30345                     break;
30346                 }
30347 
30348                 if(ajStrMatchS(desc, repstr) ||
30349                    (!exactcase && ajStrMatchCaseS(desc, repstr)))
30350                 {
30351                     jfound = 1;
30352                     ajStrAssignS(&hitstr2, code);
30353                     break;
30354                 }
30355 
30356                 if(ajStrPrefixS(code, repstr) ||
30357                    (!exactcase && ajStrPrefixCaseS(code, repstr)))
30358                 {
30359                     ifound++;
30360                     ajStrAssignS(&hitstr1, code);
30361                     acdAmbigApp(&ambigList, code);
30362                 }
30363 
30364                 if(ajStrPrefixS(desc, repstr) ||
30365                    (!exactcase && ajStrPrefixCaseS(desc, repstr)))
30366                 {
30367                     jfound++;
30368                     ajStrAssignS(&hitstr2, code);
30369                     acdAmbigApp(&ambigList, desc);
30370                 }
30371 
30372                 ajStrTokenReset(codehandle);
30373             } /* end of while */
30374 
30375             if(ifound == 1)
30376             {
30377                 ajStrAssignS(&hitstr,hitstr1);
30378                 ajListstrPushAppend(list, hitstr);
30379                 hitstr = NULL;
30380             }
30381             else if(jfound == 1)
30382             {
30383                 ajStrAssignS(&hitstr, hitstr2);
30384                 ajListstrPushAppend(list, hitstr);
30385                 hitstr = NULL;
30386             }
30387             else
30388             {
30389                 if(ifound || jfound) /* test acdc-listambig1 acdc-listambig2 */
30390                     ajErr("'%S' is ambiguous (%S)", repstr, ambigList);
30391                 else			/* test acdc-listbad */
30392                     ajErr("'%S' is not a valid menu option\n"
30393                           "Accepted short codes are: %S",
30394                           repstr, validstr);
30395 
30396                 ok = ajFalse;
30397                 break;
30398             }
30399         }
30400     }
30401 
30402     ajStrTokenDel(&handle);
30403     ajStrTokenDel(&rephandle);
30404     ajStrTokenDel(&codehandle);
30405     ajStrDel(&repstr);
30406 
30407     ilen = (ajuint) ajListstrGetLength(list);
30408     acdLog("Found %d matches OK: %b min: %d max: %d\n",
30409 	   ilen, ok, min, max);
30410     if(ok)
30411     {
30412 	if(ilen < min)
30413 	{				/* test acdc-listmin */
30414 	    if(min <= 1)
30415 		ajErr("Menu needs %d value", min);
30416 	    else
30417 		ajErr("Menu needs %d values", min);
30418 	    ok = ajFalse;
30419 	}
30420 
30421 	if(ilen > max)			/* test acdc-listmax */
30422 	{
30423 	    if(max <= 1)
30424 		ajErr("Menu allows no more than %d value", max);
30425 	    else
30426 		ajErr("Menu allows no more than %d values", max);
30427 	    ok = ajFalse;
30428 	}
30429     }
30430 
30431     if(ok)
30432     {
30433 	AJCNEW0(val, ilen+1);
30434 	for(k = 0; k < ilen; k++)
30435 	{
30436 	    ajListstrPop(list, &val[k]);
30437 	    acdLog("Accept[%d]: '%S'\n", k,val[k]);
30438 	}
30439     }
30440 
30441     acdLog("Found %d matches\n", ilen);
30442     acdLog("Menu length now %d\n", ajListstrGetLength(list));
30443 
30444     if(ok)
30445 	acdLog("Before return val[0] '%S'\n", val[0]);
30446 
30447     ajListstrFreeData(&list);
30448     ajStrDel(&delim);
30449     ajStrDel(&codedelim);
30450     ajStrDel(&repdelim);
30451     ajStrDel(&line);
30452     ajStrDel(&code);
30453     ajStrDel(&desc);
30454 
30455     ajStrDel(&ambigList);
30456     ajStrDel(&hitstr1);
30457     ajStrDel(&hitstr2);
30458 
30459     ajStrDel(&repstr);
30460 
30461     ajStrDel(&validstr);
30462     ajStrDel(&value);
30463 
30464     if(!ok)
30465 	return NULL;
30466 
30467     return val;
30468 }
30469 
30470 
30471 
30472 
30473 /* @funcstatic acdSelectValue *************************************************
30474 **
30475 ** Checks the user setting against the selection list set of codes
30476 **
30477 ** An unambiguous match to the codes counts as valid.
30478 ** If this fails, an unambiguous match to the descriptions counts.
30479 **
30480 ** @param [r] thys [const AcdPAcd] ACD Object
30481 ** @param [r] min [ajint] Minimum number of values required
30482 ** @param [r] max [ajint] Maximum number of values required
30483 ** @param [r] reply [const AjPStr] Default value
30484 ** @return [AjPStr*] Array of accepted matches, ending with a NULL.
30485 **
30486 ** @release 1.0.0
30487 ** @@
30488 ******************************************************************************/
30489 
acdSelectValue(const AcdPAcd thys,ajint min,ajint max,const AjPStr reply)30490 static AjPStr* acdSelectValue(const AcdPAcd thys, ajint min, ajint max,
30491 			      const AjPStr reply)
30492 {
30493     AjPStr *val = NULL;
30494 
30495     AjPStr delim=NULL;
30496     const AjPStr tmpstr = NULL;
30497     AjPStr value = NULL;
30498     AjBool exactcase;
30499     AjPStrTok handle = NULL;
30500     AjPStrTok rephandle = NULL;
30501     AjPStr line      = NULL;
30502     AjPStr code      = NULL;
30503     AjPStr desc      = NULL;
30504     AjPList list            = NULL;
30505     AjPStr repstr    = NULL;
30506     AjPStr hitstr    = NULL;
30507     AjPStr validstr  = NULL;
30508     AjPStr hitstr2 = NULL;
30509     AjPStr ambigList = NULL;
30510     AjPStr repdelim  = NULL;
30511     static const char* white = " \t\n\r";
30512     ajint i = 0;
30513     ajint k = 0;
30514 
30515     ajint jfound = 0;
30516     ajint icnt   = 0;
30517     ajint ilen;
30518     ajint itoken = 0;
30519 
30520     AjBool ok = ajTrue;
30521 
30522     list = ajListstrNew();
30523 
30524     acdAttrToBool(thys, "casesensitive", ajFalse, &exactcase);
30525 
30526     tmpstr = acdAttrValue(thys, "delimiter");
30527 
30528     if(ajStrGetLen(tmpstr))
30529 	ajStrAssignS(&delim, tmpstr);
30530     else
30531 	ajStrAssignC(&delim, ";");
30532 
30533     if(!repdelim)
30534     {
30535 	repdelim = ajStrNewRes(10);
30536 	ajStrAssignC(&repdelim, ",");
30537     }
30538 
30539     ajStrAssignS(&value, acdAttrValue(thys, "values"));
30540     acdVarResolve(&value);
30541 
30542     if(!ajStrGetLen(value))
30543 	if(!acdKnownValueSelect(thys, &value))
30544 	    acdError("No value defined for selection");
30545 
30546     ajStrAssignClear(&ambigList);
30547     ajStrAssignClear(&validstr);
30548     rephandle = ajStrTokenNewS(reply, repdelim);
30549     while(ajStrTokenNextParse(rephandle, &repstr))
30550     {
30551 	itoken++;
30552 
30553 	acdLog("testing '%S'\n", repstr);
30554 	ajStrTokenAssignS(&handle, value, delim);
30555 	i = jfound = 0;
30556 
30557         if(ajStrMatchC(repstr, "*"))
30558         {
30559             for(icnt = 1; ajStrTokenNextFind(handle, &desc); icnt++)
30560             {
30561                 ajStrAssignS(&hitstr, desc);
30562                 ajListstrPushAppend(list, hitstr);
30563                 hitstr = NULL;
30564             }
30565         }
30566         else
30567         {
30568             for(icnt = 1; ajStrTokenNextFind(handle, &desc); icnt++)
30569             {
30570                 ajStrTrimC(&desc, white);
30571 
30572                 if(itoken == 1)
30573                 {
30574                     if(ajStrGetLen(validstr))
30575                         ajStrAppendK(&validstr, ',');
30576                     ajStrAppendS(&validstr, desc);
30577                 }
30578 
30579                 if(ajStrMatchS(desc, repstr) ||
30580                    (!exactcase && ajStrMatchCaseS(desc, repstr)))
30581                 {
30582                     jfound = 1;
30583                     ajStrAssignS(&hitstr2, desc);
30584                     break;
30585                 }
30586 
30587                 if(ajStrPrefixS(desc, repstr) ||
30588                    (!exactcase && ajStrPrefixCaseS(desc,repstr)))
30589                 {
30590                     jfound++;
30591                     ajStrAssignS(&hitstr2, desc);
30592                     acdAmbigApp(&ambigList, desc);
30593                 }
30594 
30595                 if(ajStrToInt(repstr, &i) && i == icnt)
30596                 {
30597                     jfound++;
30598                     ajStrAssignS(&hitstr2, desc);
30599                     acdAmbigApp(&ambigList, repstr);
30600                 }
30601             } /* end of while */
30602 
30603             if(jfound == 1)
30604             {
30605                 ajStrAssignS(&hitstr, hitstr2);
30606                 ajListstrPushAppend(list, hitstr);
30607                 hitstr = NULL;
30608             }
30609             else
30610             {
30611                 if(jfound)			/* test acdc-selectambig */
30612                     ajErr("'%S' is ambiguous (%S)", repstr, ambigList);
30613                 else			/* test acdc-selectbad */
30614                     ajErr("'%S' is not a valid selection list option\n"
30615                           "Accepted values are: %S",
30616                           repstr, validstr);
30617                 ok = ajFalse;
30618                 break;
30619             }
30620         }
30621     }
30622 
30623     ajStrTokenDel(&handle);
30624     ajStrTokenDel(&rephandle);
30625     ajStrDel(&repstr);
30626 
30627     ilen = (ajuint) ajListstrGetLength(list);
30628 
30629     if(ok)
30630     {
30631 	if(ilen < min)			/* test acdc-selectmin */
30632 	{
30633 	    if(min <= 1)
30634 		ajErr("Selection list needs %d value", min);
30635 	    else
30636 		ajErr("Selection list needs %d values", min);
30637 	    ok = ajFalse;
30638 	}
30639 	if(ilen > max)			/* test acdc-selectmax */
30640 	{
30641 	    if(max <= 1)
30642 		ajErr("Selection list allows no more than %d value", max);
30643 	    else
30644 		ajErr("Selection list allows no more than %d values", max);
30645 	    ok = ajFalse;
30646 	}
30647     }
30648 
30649     if(ok)
30650     {
30651 	AJCNEW0(val, ilen+1);
30652 
30653 	for(k = 0; k < ilen; k++)
30654 	    ajListstrPop(list, &val[k]);
30655     }
30656 
30657     acdLog("Found %d matches\n", ilen);
30658 
30659     ajListstrFreeData(&list);
30660     ajStrDel(&value);
30661     ajStrDel(&line);
30662     ajStrDel(&code);
30663     ajStrDel(&desc);
30664     ajStrDel(&ambigList);
30665     ajStrDel(&hitstr2);
30666     ajStrDel(&delim);
30667     ajStrDel(&repdelim);
30668     ajStrDel(&validstr);
30669 
30670     if(!ok)
30671 	return NULL;
30672 
30673     return val;
30674 }
30675 
30676 
30677 
30678 
30679 /* @funcstatic acdAmbigApp ****************************************************
30680 **
30681 ** Appends a token to a list, with commas as delimiters. Used to
30682 ** build a list of ambiguous matches for messages.
30683 **
30684 ** @param [w] pambigList [AjPStr*] List of tokens with ',' delimiter
30685 ** @param [r] str [const AjPStr] Latest token to add
30686 ** @return [void]
30687 **
30688 ** @release 1.0.0
30689 ** @@
30690 ******************************************************************************/
30691 
acdAmbigApp(AjPStr * pambigList,const AjPStr str)30692 static void acdAmbigApp(AjPStr* pambigList, const AjPStr str)
30693 {
30694     if(ajStrGetLen(*pambigList))
30695 	ajStrAppendC(pambigList, ",");
30696     ajStrAppendS(pambigList, str);
30697 
30698     return;
30699 }
30700 
30701 
30702 
30703 
30704 /* @funcstatic acdAmbigAppC ***************************************************
30705 **
30706 ** Appends a token to a list, with commas as delimiters. Used to
30707 ** build a list of ambiguous matches for messages.
30708 **
30709 ** @param [w] pambigList [AjPStr*] List of tokens with ',' delimiter
30710 ** @param [r] txt [const char*] Latest token to add
30711 ** @return [void]
30712 **
30713 ** @release 1.0.0
30714 ** @@
30715 ******************************************************************************/
30716 
acdAmbigAppC(AjPStr * pambigList,const char * txt)30717 static void acdAmbigAppC(AjPStr* pambigList, const char* txt)
30718 {
30719     if(ajStrGetLen(*pambigList))
30720 	ajStrAppendC(pambigList, ",");
30721 
30722     ajStrAppendC(pambigList, txt);
30723 
30724     return;
30725 }
30726 
30727 
30728 
30729 
30730 /* @funcstatic acdDataFilename ************************************************
30731 **
30732 ** Sets a default data file name. If no values are provided, it will be
30733 ** programname.dat
30734 **
30735 ** @param [w] infname [AjPStr*] Resulting file name
30736 ** @param [r] name [const AjPStr] File name
30737 ** @param [r] ext [const AjPStr] File extension
30738 ** @param [r] nullok [AjBool] Can set as an empty string if true
30739 ** @return [AjBool] ajTrue if a name was successfully set
30740 **
30741 ** @release 1.0.0
30742 ** @@
30743 ******************************************************************************/
30744 
acdDataFilename(AjPStr * infname,const AjPStr name,const AjPStr ext,AjBool nullok)30745 static AjBool acdDataFilename(AjPStr* infname,
30746 			      const AjPStr name, const AjPStr ext,
30747 			      AjBool nullok)
30748 {
30749     AjBool ret = ajTrue;
30750 
30751     if(ajStrGetLen(name))
30752 	ajStrAssignS(infname, name);
30753     else if(!nullok)
30754 	ajStrAssignS(infname, acdProgram);
30755     else
30756 	ajStrAssignClear(infname);
30757 
30758     if(ajStrGetLen(ext))
30759 	ajFilenameReplaceExtS(infname, ext);
30760     else
30761 	if (!nullok)
30762 	    ajFilenameReplaceExtC(infname, "dat");
30763 
30764     return ret;
30765 }
30766 
30767 
30768 
30769 
30770 /* @funcstatic acdInFilename **************************************************
30771 **
30772 ** Sets a default input file name. If filtering is on, this will be stdin.
30773 ** Otherwise it is blank.
30774 **
30775 ** @param [w] infname [AjPStr*] Input file name
30776 ** @return [AjBool] ajTrue if a name was successfully set
30777 **
30778 ** @release 1.0.0
30779 ** @@
30780 ******************************************************************************/
30781 
acdInFilename(AjPStr * infname)30782 static AjBool acdInFilename(AjPStr* infname)
30783 {
30784     AjBool ret = ajFalse;
30785 
30786     if(!acdInFile && acdFilter)
30787     {
30788 	ajStrAssignC(infname, "stdin");
30789 	ret = ajTrue;
30790     }
30791     else
30792 	ajStrAssignClear(infname);
30793 
30794     acdInFile++;
30795 
30796     return ret;
30797 }
30798 
30799 
30800 
30801 
30802 /* @funcstatic acdOutDirectory ************************************************
30803 **
30804 ** Sets a default output file directory. Uses the _OUTDIRECTORY variable
30805 ** as a default value, but any input string overrides it.
30806 **
30807 ** The recommendation is that the directory should always be provided
30808 ** in the emboss.defaults file or by an environment variable.
30809 **
30810 ** As for all associated qualifiers, it is also possible to set a value
30811 ** in the ACD file.
30812 **
30813 ** @param [w] dir [AjPStr*] Specified directory
30814 ** @return [AjBool] ajTrue if a directory was successfully set
30815 **
30816 ** @release 2.7.0
30817 ** @@
30818 ******************************************************************************/
30819 
acdOutDirectory(AjPStr * dir)30820 static AjBool acdOutDirectory(AjPStr* dir)
30821 {
30822     AjBool ret = ajFalse;
30823 
30824     AjPStr mydir  = NULL;
30825 
30826     acdLog("acdOutDirectory ('%S')\n",
30827 	   *dir);
30828 
30829     if(!acdDirectoryDef)
30830 	if(!ajNamGetValueC("outdirectory", &acdDirectoryDef))
30831 	    ajStrAssignClear(&acdDirectoryDef);
30832 
30833     if(dir && ajStrGetLen(*dir))
30834 	ajStrAssignS(&mydir, *dir);
30835     else
30836 	ajStrAssignS(&mydir, acdDirectoryDef);
30837 
30838     if(ajStrGetLen(mydir))
30839     {
30840 	ajDirnameFix(&mydir);
30841 	ajStrAssignS(dir, mydir);
30842 	ret = ajTrue;
30843     }
30844     else
30845     {
30846 	ajStrAssignClear(dir);
30847 	ret = ajFalse;
30848     }
30849 
30850     acdLog(". . . dir '%S' ret: %B\n",
30851 	   *dir, ret);
30852 
30853     ajStrDel(&mydir);
30854 
30855     return ret;
30856 }
30857 
30858 
30859 
30860 
30861 /* @funcstatic acdOutFilename *************************************************
30862 **
30863 ** Sets a default output file name. If stdout or filtering are on,
30864 ** this will be stdout for the first output file.
30865 ** Otherwise it is built from the defaults provided.
30866 **
30867 ** The base file name is usually specified in the ACD file as name:
30868 ** and passed in by the calling acdSet function. The default will
30869 ** be the base file name saved from the first input file, or "outfile"
30870 **
30871 ** The extension is usually specified in the ACD file as extension:
30872 ** and passed in by the calling acdSet function. The default will
30873 ** be the program name for the first file, and "out2", "out3" and so
30874 ** on for later files.
30875 **
30876 ** The recommendation is that the extension should always be provided
30877 ** in the ACD file, but that the base file name should be taken from
30878 ** the input file in most cases.
30879 **
30880 ** @param [w] outfname [AjPStr*] Input file name
30881 ** @param [r] name [const AjPStr] Specified base file name
30882 ** @param [r] ext [const AjPStr] Specified extension
30883 ** @return [AjBool] ajTrue if a name was successfully set
30884 **
30885 ** @release 1.0.0
30886 ** @@
30887 ******************************************************************************/
30888 
acdOutFilename(AjPStr * outfname,const AjPStr name,const AjPStr ext)30889 static AjBool acdOutFilename(AjPStr* outfname,
30890 			     const AjPStr name, const AjPStr ext)
30891 {
30892     AjBool ret = ajFalse;
30893 
30894     acdLog("acdOutFilename ('%S', '%S', '%S') acdStdout: %B\n",
30895 	   *outfname, name, ext, acdStdout);
30896 
30897     if(!acdOutFile && acdStdout) /* first outfile, running as a filter */
30898     {
30899 	ajStrAssignC(outfname, "stdout");
30900 	acdLog("outfile <first> '%S'\n", *outfname);
30901 	acdOutFile++;
30902 	return ajTrue;
30903     }
30904 
30905     ajStrAssignEmptyS(&acdOutFName, name);		/* use name if given */
30906     ajStrFmtWord(&acdOutFName);
30907     ajStrAssignEmptyS(&acdOutFName, acdInFName); /* else use saved name */
30908     ajStrAssignEmptyC(&acdOutFName, "outfile"); /* else, use "outfile" */
30909 
30910     ajStrAssignEmptyS(&acdOutFExt, ext); /* use extension if given */
30911 
30912     if(!acdOutFile)
30913 	ajStrAssignEmptyS(&acdOutFExt, acdProgram);
30914 
30915     /* else try program name for first file */
30916     if(!ajStrGetLen(acdOutFExt))	/* if all else fails, use out2 etc. */
30917 	ajFmtPrintS(&acdOutFExt, "out%d", acdOutFile+1);
30918 
30919     acdLog(". . . acdOutFName '%S', acdOutFExt '%S'\n",
30920 	   acdOutFName, acdOutFExt);
30921 
30922     if(ext && ajStrGetLen(acdOutFExt))	 /* NULL ext means add no extension */
30923 	ajFmtPrintS(outfname, "%S.%S", acdOutFName, acdOutFExt);
30924     else
30925 	ajStrAppendS(outfname, acdOutFName);
30926 
30927     acdOutFile++;
30928 
30929     acdLog("outfile %d %S.%S\n", acdOutFile, acdOutFName, acdOutFExt);
30930 
30931     ajStrDelStatic(&acdOutFName);
30932     ajStrDelStatic(&acdOutFExt);
30933 
30934     return ret;
30935 }
30936 
30937 
30938 
30939 
30940 /* @funcstatic acdInFileSave **************************************************
30941 **
30942 ** For the first call, saves the input filename for use in building output
30943 ** file name(s).
30944 **
30945 ** @param [r] infname [const AjPStr] Input file name
30946 ** @param [r] objname [const AjPStr] Input object name (or NULL)
30947 ** @param [r] reset [AjBool] Reset the saved name if this is the first time
30948 **                           a true value has been passed.
30949 ** @return [AjBool] ajTrue if a name was successfully set
30950 **
30951 ** @release 1.0.0
30952 ** @@
30953 ******************************************************************************/
30954 
acdInFileSave(const AjPStr infname,const AjPStr objname,AjBool reset)30955 static AjBool acdInFileSave(const AjPStr infname, const AjPStr objname,
30956                             AjBool reset)
30957 {
30958     static AjBool usefile = AJFALSE;
30959     static ajint called = 0;
30960 
30961     AjBool useobj = ajTrue;
30962 
30963     if(!called)
30964     {
30965         if(ajNamGetValueC("acdfilename", &acdTmpStr))
30966             ajStrToBool(acdTmpStr, &usefile);
30967         called = 1;
30968     }
30969 
30970     if(acdInFileSet)			/* already have a name */
30971 	return ajFalse;
30972 
30973     if(!reset && ajStrGetLen(acdInFName)) /* have a name, no reset forced */
30974 	return ajFalse;
30975 
30976     if(usefile)
30977     {
30978         useobj = ajFalse;
30979         if(ajStrMatchC(infname, "stdin"))
30980             useobj = ajTrue;
30981     }
30982 
30983     acdLog("acdInFileSave (%S,%S) reset: %B usefile: %B, saved name '%S'\n",
30984 	   infname, objname, reset, usefile, acdInFName);
30985 
30986     if(useobj && ajStrGetLen(objname))
30987     {
30988         if(!ajStrGetLen(objname))
30989             return ajFalse;
30990 
30991         ajStrAssignS(&acdInFName, objname);
30992         ajFilenameTrimAll(&acdInFName);
30993         ajStrFmtLower(&acdInFName);
30994     }
30995     else
30996     {
30997         if(!ajStrGetLen(infname))
30998             return ajFalse;
30999 
31000         ajStrAssignS(&acdInFName, infname);
31001         ajFilenameTrimAll(&acdInFName);
31002 
31003         if(useobj)
31004             ajStrFmtLower(&acdInFName);
31005     }
31006 
31007     if(reset)
31008 	acdInFileSet = ajTrue;
31009 
31010     acdLog("acdInFileSave (%S, %S) input file set to '%S'\n",
31011 	   infname, objname, acdInFName);
31012 
31013     return ajTrue;
31014 }
31015 
31016 
31017 
31018 
31019 /* @funcstatic acdInTypeSeqSave ***********************************************
31020 **
31021 ** For the first call, saves the input filename for use in building output
31022 ** file name(s).
31023 **
31024 ** @param [r] intype [const AjPStr] Input sequence type
31025 ** @return [AjBool] ajTrue if a type was successfully set
31026 **
31027 ** @release 2.7.0
31028 ** @@
31029 ******************************************************************************/
31030 
acdInTypeSeqSave(const AjPStr intype)31031 static AjBool acdInTypeSeqSave(const AjPStr intype)
31032 {
31033     if(acdInTypeSeqName)
31034 	return ajFalse;
31035 
31036     acdLog("acdInTypeSeqSave (%S)\n",
31037 	   intype);
31038 
31039     if(!ajStrGetLen(intype))
31040     {
31041 	ajStrAssignClear(&acdInTypeSeqName);
31042 	acdLog("Input sequence type defaults to ''\n", acdInTypeSeqName);
31043 	acdInTypeFeatSave(NULL);
31044     }
31045     else
31046     {
31047 	ajStrAssignS(&acdInTypeSeqName, intype);
31048 	ajStrFmtLower(&acdInTypeSeqName);
31049 
31050 	if(ajSeqTypeIsAny(intype))
31051 	    acdInTypeFeatSaveC("");
31052 	else if(ajSeqTypeIsProt(intype))
31053 	    acdInTypeFeatSaveC("protein");
31054 	else if(ajSeqTypeIsNuc(intype))
31055 	    acdInTypeFeatSaveC("nucleotide");
31056 	else
31057 	    acdInTypeFeatSaveC("");
31058     }
31059 
31060     acdLog("acdInTypeSeqSave (%S) input type set to '%S'\n",
31061 	   intype, acdInTypeSeqName);
31062 
31063     return ajTrue;
31064 }
31065 
31066 
31067 
31068 
31069 /* @funcstatic acdInTypeSeq ***************************************************
31070 **
31071 ** Returns the input sequence type (if known)
31072 **
31073 ** @param [w] typename [AjPStr*] Input sequence type
31074 ** @return [AjBool] ajTrue if a type was successfully set
31075 **
31076 ** @release 2.7.0
31077 ** @@
31078 ******************************************************************************/
31079 
acdInTypeSeq(AjPStr * typename)31080 static AjBool acdInTypeSeq(AjPStr* typename)
31081 {
31082     AjBool ret = ajFalse;
31083 
31084     acdLog("acdInTypeSeq saved acdInTypeSeqName '%S'\n", acdInTypeSeqName);
31085 
31086     if(acdInTypeSeqName)		/* could be an empty string */
31087     {
31088 	ajStrAssignS(typename, acdInTypeSeqName);
31089 	ret = ajTrue;
31090     }
31091     else
31092     {
31093 	ajStrAssignClear(typename);  /* allow anything, return ajFalse */
31094 	ret = ajFalse;
31095     }
31096 
31097     return ret;
31098 }
31099 
31100 
31101 
31102 
31103 /* @funcstatic acdInTypeFeatSave **********************************************
31104 **
31105 ** Saves the input feature type for use in setting the default output type
31106 **
31107 ** @param [r] intype [const AjPStr] Input feature type
31108 ** @return [AjBool] ajTrue if a type was successfully set
31109 **
31110 ** @release 2.7.0
31111 ** @@
31112 ******************************************************************************/
31113 
acdInTypeFeatSave(const AjPStr intype)31114 static AjBool acdInTypeFeatSave(const AjPStr intype)
31115 {
31116     if(acdInTypeFeatName)
31117 	return ajFalse;
31118 
31119     acdLog("acdInTypeFeatSave (%S)\n",
31120 	   intype);
31121 
31122     if(!ajStrGetLen(intype))
31123     {
31124 	ajStrAssignClear(&acdInTypeFeatName);
31125 	acdLog("Input feature type defaults to '%S'\n", acdInTypeFeatName);
31126     }
31127     else
31128 	ajStrAssignS(&acdInTypeFeatName, intype);
31129 
31130     ajStrFmtLower(&acdInTypeFeatName);
31131 
31132     acdLog("acdInTypeFeatSave (%S) input feature type set to '%S'\n",
31133 	   intype, acdInTypeFeatName);
31134 
31135     return ajTrue;
31136 }
31137 
31138 
31139 
31140 
31141 /* @funcstatic acdInTypeFeatSaveC *********************************************
31142 **
31143 ** Saves the input feature type for use in setting the default output type
31144 **
31145 ** @param [r] intype [const char*] Input feature type
31146 ** @return [AjBool] ajTrue if a type was successfully set
31147 **
31148 ** @release 2.7.0
31149 ** @@
31150 ******************************************************************************/
31151 
acdInTypeFeatSaveC(const char * intype)31152 static AjBool acdInTypeFeatSaveC(const char* intype)
31153 {
31154     AjBool ret;
31155     AjPStr tmpstr = NULL;
31156 
31157     tmpstr = ajStrNewC(intype);
31158     ret = acdInTypeFeatSave(tmpstr);
31159     ajStrDel(&tmpstr);
31160 
31161     return ret;
31162 }
31163 
31164 
31165 
31166 
31167 /* @funcstatic acdInTypeFeat **************************************************
31168 **
31169 ** Returns the input feature type (if known)
31170 **
31171 ** @param [w] typename [AjPStr*] Input feature type
31172 ** @return [AjBool] ajTrue if a type was successfully set
31173 **
31174 ** @release 2.7.0
31175 ** @@
31176 ******************************************************************************/
31177 
acdInTypeFeat(AjPStr * typename)31178 static AjBool acdInTypeFeat(AjPStr* typename)
31179 {
31180     AjBool ret = ajFalse;
31181 
31182     acdLog("acdInTypeFeat saved acdInTypeFeatName '%S'\n", acdInTypeFeatName);
31183 
31184     if(acdInTypeFeatName)		/* could be an empty string */
31185     {
31186 	ajStrAssignS(typename, acdInTypeFeatName);
31187 	ret = ajTrue;
31188     }
31189     else
31190     {
31191 	ajStrAssignClear(typename);  /* allow anything, return ajFalse */
31192 	ret = ajFalse;
31193     }
31194 
31195     return ret;
31196 }
31197 
31198 
31199 
31200 
31201 /* @funcstatic acdLog *********************************************************
31202 **
31203 ** Writes a message to the .acdlog file
31204 **
31205 ** @param [r] fmt [const char*] Format with ajFmt extensions
31206 ** @param [v] [...] Optional arguments
31207 ** @return [void]
31208 **
31209 ** @release 1.0.0
31210 ** @@
31211 ******************************************************************************/
31212 
acdLog(const char * fmt,...)31213 static void acdLog(const char *fmt, ...)
31214 {
31215     va_list args;
31216 
31217     if(!acdDoLog)
31218 	return;
31219 
31220     if(!acdLogFName)
31221     {
31222 	ajFmtPrintS(&acdLogFName, "%S.acdlog", acdProgram);
31223 	acdLogFile = ajFileNewOutNameS(acdLogFName);
31224 	ajFileSetUnbuffer(acdLogFile);
31225     }
31226 
31227     va_start(args, fmt) ;
31228     ajFmtVPrintF(acdLogFile, fmt, args);
31229     va_end(args) ;
31230 
31231     return;
31232 }
31233 
31234 
31235 
31236 
31237 /* @funcstatic acdPretty ******************************************************
31238 **
31239 ** Writes a pretty formatted version of the .acd syntax
31240 ** message to the .acdpretty file
31241 **
31242 ** @param [r] fmt [const char*] Format with ajFmt extensions
31243 ** @param [v] [...] Optional arguments
31244 ** @return [void]
31245 **
31246 ** @release 1.0.0
31247 ** @@
31248 ******************************************************************************/
31249 
acdPretty(const char * fmt,...)31250 static void acdPretty(const char *fmt, ...)
31251 {
31252     va_list args ;
31253     static AjPStr tmpstr = NULL;
31254     ajint *icword    = NULL;
31255     ajint *icpos    = NULL;
31256     AjPStr cmtstr = NULL;
31257     ajint lastword;
31258     ajint wordcount;
31259     ajuint ipos;
31260     ajint i = 0;
31261     ajint j = 0;
31262     ajint ccnt=0;
31263 
31264     if(!acdDoPretty)
31265 	return;
31266 
31267     if(!acdPrettyFName)
31268     {
31269 	if(acdStdout)
31270 	    acdPrettyFile = ajFileNewFromCfile(stdout);
31271 	else
31272 	{
31273 	    ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram);
31274 	    acdPrettyFile = ajFileNewOutNameS(acdPrettyFName);
31275 	    ajFileSetUnbuffer(acdPrettyFile);
31276 	    ajFmtPrint("Created %S\n", acdPrettyFName);
31277 	}
31278     }
31279 
31280     va_start(args, fmt);
31281     ajFmtVPrintS(&tmpstr, fmt, args);
31282     va_end(args);
31283 
31284     /*
31285     ** test for comment block before this line
31286     */
31287 
31288     while(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= acdWordSave))
31289     {
31290 	ajListPeek(acdListCommentsCount, (void**) &icword);
31291 	ajListPeek(acdListCommentsColumn, (void**) &icpos);
31292 	acdCmtWord = *icword;
31293 
31294 	if((acdCmtWord == acdWordSave && !*icpos) ||
31295 	    (acdCmtWord<=acdWordSave))
31296 	{
31297 	    if(!ajStrGetLen(cmtstr))
31298 		ajFmtPrintF(acdPrettyFile, "\n");
31299 
31300 	    ajListPop(acdListCommentsCount, (void**) &icword);
31301 	    ajListPop(acdListCommentsColumn, (void**) &icpos);
31302 	    ajListstrPop(acdListComments, &cmtstr);
31303 	    acdPrettyComment(cmtstr);
31304 	    ajStrDel(&cmtstr);
31305 	    AJFREE(icword);
31306 	    AJFREE(icpos);
31307 	    ccnt++;
31308 	}
31309     }
31310 
31311     if(ccnt && ajStrGetCharFirst(tmpstr) != '\n')
31312 	ajFmtPrintF(acdPrettyFile, "\n");
31313 
31314     while(ajStrGetCharFirst(tmpstr) == '\n')
31315     {
31316 	ajFmtPrintF(acdPrettyFile, "\n");
31317 	ajStrCutStart(&tmpstr, 1);
31318     }
31319 
31320     wordcount = ajStrParseCount(tmpstr);
31321     lastword = acdWordSave + wordcount;
31322 
31323     /*
31324     ** now check for inline comment on this line of text
31325     */
31326 
31327     if(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= lastword))
31328     {
31329 	ajListPeek(acdListCommentsCount, (void**) &icword);
31330 	ajListPeek(acdListCommentsColumn, (void**) &icpos);
31331 	acdCmtWord = *icword;
31332 	if((acdCmtWord == lastword && *icpos) |
31333 	   (acdCmtWord < lastword))
31334 	{
31335 	    ajListPop(acdListCommentsCount, (void**) &icword);
31336 	    ajListPop(acdListCommentsColumn, (void**) &icpos);
31337 	    ajListstrPop(acdListComments, &cmtstr);
31338 
31339 	    ajStrRemoveWhiteExcess(&cmtstr);
31340 
31341 	    if(!ajStrPrefixC(cmtstr, "#"))
31342 		ajStrInsertC(&cmtstr, 0, "#");
31343 
31344 	    if((ajStrGetLen(cmtstr) > 1) && !ajStrPrefixC(cmtstr, "# "))
31345 		ajStrInsertC(&cmtstr, 1, " ");
31346 
31347 	    i=0;
31348 	    while(ajStrGetCharLast(tmpstr) == '\n')
31349 	    {
31350 		ajStrCutEnd(&tmpstr, 1);
31351 		i++;
31352 	    }
31353 	    ipos = 75;
31354 
31355 	    if(ajStrGetLen(cmtstr) > (79 - ipos))
31356 		ipos = 79 - ajStrGetLen(cmtstr);
31357 
31358 	    if(ipos <= (ajStrGetLen(tmpstr)+acdPrettyMargin))
31359 		ipos = ajStrGetLen(tmpstr)+acdPrettyMargin+1;
31360 
31361 	    j = ipos-ajStrGetLen(tmpstr)-acdPrettyMargin;
31362 	    ajStrAppendCountK(&tmpstr, ' ', j);
31363 	    ajStrAppendS(&tmpstr, cmtstr);
31364 	    if(i)
31365 		ajStrAppendCountK(&tmpstr, '\n', i);
31366 	    ajStrDel(&cmtstr);
31367 	    AJFREE(icword);
31368 	    AJFREE(icpos);
31369 	}
31370     }
31371 
31372     if(acdPrettyMargin)
31373 	ajFmtPrintF(acdPrettyFile, "%.*s", acdPrettyMargin,
31374 		    "                                                       ");
31375     ajFmtPrintF(acdPrettyFile, "%S", tmpstr);
31376 
31377     acdWordSave += wordcount;
31378 
31379     return;
31380 }
31381 
31382 
31383 
31384 
31385 /* @funcstatic acdPrettyClose *************************************************
31386 **
31387 ** Writes any remaining comments and closes the pretty output file
31388 **
31389 ** @return [void]
31390 **
31391 ** @release 6.0.0
31392 ** @@
31393 ******************************************************************************/
31394 
acdPrettyClose(void)31395 static void acdPrettyClose(void)
31396 {
31397     ajint *icword    = NULL;
31398     ajint *icpos    = NULL;
31399     AjPStr cmtstr = NULL;
31400 
31401     if(!acdDoPretty)
31402 	return;
31403 
31404     if(!acdPrettyFName)
31405     {
31406 	if(acdStdout)
31407 	    acdPrettyFile = ajFileNewFromCfile(stdout);
31408 	else
31409 	{
31410 	    ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram);
31411 	    acdPrettyFile = ajFileNewOutNameS(acdPrettyFName);
31412 	    ajFileSetUnbuffer(acdPrettyFile);
31413 	    ajFmtPrint("Created %S\n", acdPrettyFName);
31414 	}
31415     }
31416 
31417     while(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= acdWordSave))
31418     {
31419 	ajListPeek(acdListCommentsCount, (void**) &icword);
31420 	acdCmtWord = *icword;
31421 
31422 	if(acdCmtWord <= acdWordSave)
31423 	{
31424 	    if(!ajStrGetLen(cmtstr))
31425 		ajFmtPrintF(acdPrettyFile, "\n");
31426 
31427 	    ajStrDel(&cmtstr);
31428 	    ajListPop(acdListCommentsCount, (void**) &icword);
31429 	    ajListPop(acdListCommentsColumn, (void**) &icpos);
31430 	    ajListstrPop(acdListComments, &cmtstr);
31431 	    acdPrettyComment(cmtstr);
31432 	    AJFREE(icword);
31433 	    AJFREE(icpos);
31434 	}
31435     }
31436 
31437     ajStrDel(&cmtstr);
31438 
31439     ajFileClose(&acdPrettyFile);
31440 
31441     return;
31442 }
31443 
31444 
31445 
31446 
31447 /* @funcstatic acdPrettyComment ***********************************************
31448 **
31449 ** Writes an indented one-line comment
31450 **
31451 ** @param [r] comment [const AjPStr] OComment to be printer
31452 ** @return [void]
31453 **
31454 ** @release 6.0.0
31455 ** @@
31456 ******************************************************************************/
31457 
acdPrettyComment(const AjPStr comment)31458 static void acdPrettyComment(const AjPStr comment)
31459 {
31460     AjPStr tmpstr = NULL;
31461 
31462     if(!acdDoPretty)
31463 	return;
31464 
31465     if(!acdPrettyFName)
31466     {
31467 	if(acdStdout)
31468 	    acdPrettyFile = ajFileNewFromCfile(stdout);
31469 	else
31470 	{
31471 	    ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram);
31472 	    acdPrettyFile = ajFileNewOutNameS(acdPrettyFName);
31473 	    ajFileSetUnbuffer(acdPrettyFile);
31474 	    ajFmtPrint("Created %S\n", acdPrettyFName);
31475 	}
31476     }
31477 
31478     ajStrAssignS(&tmpstr, comment);
31479     ajStrRemoveWhiteExcess(&tmpstr);
31480 
31481     if(!ajStrPrefixC(tmpstr, "#"))
31482 	ajStrInsertC(&tmpstr, 0, "#");
31483 
31484     if((ajStrGetLen(tmpstr) > 1) && !ajStrPrefixC(tmpstr, "# "))
31485 	ajStrInsertC(&tmpstr, 1, " ");
31486 
31487 
31488     /*
31489     ** margin is set for attributes
31490     ** reduce by 2 to align with definitions
31491     */
31492 
31493     if(acdPrettyMargin)
31494 	ajFmtPrintF(acdPrettyFile, "%.*s", acdPrettyMargin,
31495 		    "                                                       ");
31496     ajFmtPrintF(acdPrettyFile, "%S\n", tmpstr);
31497 
31498     ajStrDel(&tmpstr);
31499 
31500     return;
31501 }
31502 
31503 
31504 
31505 
31506 /* @funcstatic acdPrettyWrap **************************************************
31507 **
31508 ** Writes a pretty formatted version of the .acd syntax
31509 ** line to the .acdpretty file
31510 **
31511 ** @param [r] left [ajint] Extra left margin for follow-on lines
31512 ** @param [r] fmt [const char*] Format with ajFmt extensions
31513 ** @param [v] [...] Optional arguments
31514 ** @return [void]
31515 **
31516 ** @release 2.7.0
31517 ** @@
31518 ******************************************************************************/
31519 
acdPrettyWrap(ajint left,const char * fmt,...)31520 static void acdPrettyWrap(ajint left, const char *fmt, ...)
31521 {
31522     va_list args;
31523     static AjPStr tmpstr = NULL;
31524     ajint leftmargin     = left + acdPrettyMargin;
31525     ajint width          = 78 - leftmargin;
31526     ajint *icword    = NULL;
31527     ajint *icpos    = NULL;
31528     AjPStr cmtstr = NULL;
31529     ajint lastword;
31530     ajint wordcount;
31531     ajuint ipos;
31532     ajint ccnt = 0;
31533     ajlong jpos;
31534     ajlong kpos;
31535     ajlong ilen;
31536     AjIList itercmt;
31537     AjIList iterpos;
31538     AjIList iterword;
31539 
31540     if(!acdDoPretty)
31541 	return;
31542 
31543     if(!acdPrettyFName)
31544     {
31545 	if(acdStdout)
31546 	    acdPrettyFile = ajFileNewFromCfile(stdout);
31547 	else
31548 	{
31549 	    ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram);
31550 	    acdPrettyFile = ajFileNewOutNameS(acdPrettyFName);
31551 	    ajFileSetUnbuffer(acdPrettyFile);
31552 	}
31553     }
31554 
31555     /*
31556     ** whole line comments before wrapped text
31557     */
31558 
31559     while(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= acdWordSave))
31560     {
31561 	ajListPeek(acdListCommentsCount, (void**) &icword);
31562 	acdCmtWord = *icword;
31563 
31564 	if(acdCmtWord <= acdWordSave)
31565 	{
31566 	    if(!ajStrGetLen(cmtstr))
31567 		ajFmtPrintF(acdPrettyFile, "\n");
31568 
31569 	    ajListPop(acdListCommentsCount, (void**) &icword);
31570 	    ajListPop(acdListCommentsColumn, (void**) &icpos);
31571 	    ajListstrPop(acdListComments, &cmtstr);
31572 	    acdPrettyComment(cmtstr);
31573 	    ajStrDel(&cmtstr);
31574 	    AJFREE(icword);
31575 	    AJFREE(icpos);
31576 	}
31577     }
31578 
31579     va_start(args, fmt);
31580     ajFmtVPrintS(&tmpstr, fmt, args);
31581     va_end(args);
31582 
31583     ajStrExchangeCC(&tmpstr, " \\ ", " \\\n"); /* force newlines at '\' */
31584 
31585     wordcount = ajStrParseCount(tmpstr);
31586     lastword = acdWordSave + wordcount;
31587 
31588     /*
31589     ** Now check for inline comments in these lines of text
31590     */
31591 
31592     /*
31593     ** First iterate to get comment max length
31594     */
31595 
31596     ipos = 75;
31597 
31598     if(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= lastword))
31599     {
31600         ajListPeek(acdListCommentsCount, (void**) &icword);
31601         acdCmtWord = *icword;
31602 	itercmt  = ajListIterNewread(acdListComments);
31603 	iterpos  = ajListIterNewread(acdListCommentsColumn);
31604 	iterword = ajListIterNewread(acdListCommentsCount);
31605 
31606 	while(!ajListIterDone(iterword) && (*icword <= lastword))
31607 	{
31608 	    icword = ajListIterGet(iterword);
31609 	    icpos = ajListIterGet(iterpos);
31610 	    cmtstr = ajListIterGet(itercmt);
31611 
31612 	    if(*icword <= lastword && *icpos > (acdPrettyMargin+3))
31613 	    {
31614 		ccnt++;
31615 		if(ajStrGetLen(cmtstr) > (79 - ipos))
31616 		    ipos = 79 - ajStrGetLen(cmtstr);
31617 		/*if(*icpos < (ajint) ipos)
31618 		    ipos = *icpos;*/
31619 	    }
31620 
31621             cmtstr = NULL;
31622 	}
31623 
31624 	ajListIterDel(&itercmt);
31625 	ajListIterDel(&iterpos);
31626 	ajListIterDel(&iterword);
31627     }
31628 
31629     if((ajint) ipos <= (leftmargin + 20))
31630        ipos = leftmargin + 20;
31631 
31632     width = ipos - leftmargin - 1;
31633 
31634     ajStrFmtWrapLeft(&tmpstr, width, acdPrettyMargin, left);
31635 
31636     /*
31637     ** Insert any comments at ends of lines
31638     */
31639 
31640     jpos=-1;
31641 
31642     while(ccnt--)
31643     {
31644 	ajListPop(acdListCommentsCount, (void**) &icword);
31645 	ajListPop(acdListCommentsColumn, (void**) &icpos);
31646 	ajListstrPop(acdListComments, &cmtstr);
31647         ajStrRemoveWhiteExcess(&cmtstr);
31648 
31649 	if(!ajStrPrefixC(cmtstr, "#"))
31650 	    ajStrInsertC(&cmtstr, 0, "#");
31651 
31652 	if((ajStrGetLen(cmtstr) > 1) && !ajStrPrefixC(cmtstr, "# "))
31653 	    ajStrInsertC(&cmtstr, 1, " ");
31654 
31655 	kpos = ajStrFindNextK(tmpstr, jpos+1, '\n');
31656 
31657 	if(kpos < 0)
31658 	{
31659 	    if(jpos == (ajint) ajStrGetLen(tmpstr))
31660 	    {
31661 		ajStrAppendK(&tmpstr, '\n');
31662 		ilen = 0;
31663 	    }
31664 	    else
31665 		ilen = ajStrGetLen(tmpstr) - jpos - 1;
31666 
31667 	    while(ilen < (ajlong) ipos)
31668 	    {
31669 		ajStrAppendK(&tmpstr, ' ');
31670 		ilen++;
31671 	    }
31672 
31673 	    ajStrAppendS(&tmpstr, cmtstr);
31674 	    jpos = ajStrGetLen(tmpstr);
31675 	}
31676 	else
31677 	{
31678 	    ilen = kpos - jpos - 1;
31679 	    jpos = kpos;
31680 
31681 	    while(ilen < (ajlong) ipos)
31682 	    {
31683 		ajStrInsertK(&tmpstr, jpos, ' ');
31684 		ilen++;
31685 		jpos++;
31686 	    }
31687 	    ajStrInsertS(&tmpstr, jpos, cmtstr);
31688 	    jpos += ajStrGetLen(cmtstr);
31689 	}
31690 
31691 	ajStrDel(&cmtstr);
31692 	AJFREE(icword);
31693 	AJFREE(icpos);
31694     }
31695 
31696 
31697     ajFmtPrintF(acdPrettyFile, "%S\n", tmpstr);
31698 
31699     acdWordSave += wordcount;
31700 
31701     return;
31702 }
31703 
31704 
31705 
31706 
31707 /* @funcstatic acdPrettyShift *************************************************
31708 **
31709 ** Right shifts (indents) acdpretty printing
31710 **
31711 ** @return [void]
31712 **
31713 ** @release 2.7.0
31714 ** @@
31715 ******************************************************************************/
31716 
acdPrettyShift(void)31717 static void acdPrettyShift(void)
31718 {
31719     acdPrettyMargin += acdPrettyIndent;
31720 
31721     return;
31722 }
31723 
31724 
31725 
31726 
31727 /* @funcstatic acdPrettyUnShift ***********************************************
31728 **
31729 ** Left shifts acdpretty printing
31730 **
31731 ** @return [void]
31732 **
31733 ** @release 2.7.0
31734 ** @@
31735 ******************************************************************************/
31736 
acdPrettyUnShift(void)31737 static void acdPrettyUnShift(void)
31738 {
31739     acdPrettyMargin -= acdPrettyIndent;
31740 
31741     if(acdPrettyMargin < 0)
31742     {
31743 	ajWarn("acdpretty printing indent error - too many left shifts");
31744 	acdPrettyMargin = 0;
31745     }
31746 
31747     return;
31748 }
31749 
31750 
31751 
31752 
31753 /* @funcstatic acdIsQtype *****************************************************
31754 **
31755 ** Tests whether an ACD object is a qualifier or parameter type. If not we
31756 ** assume it is a keyword type.
31757 **
31758 ** @param [r] thys [const AcdPAcd] ACD object
31759 ** @return [AjBool] ajTrue if the object is a qualifier or parameter
31760 **
31761 ** @release 1.0.0
31762 ** @@
31763 ******************************************************************************/
31764 
acdIsQtype(const AcdPAcd thys)31765 static AjBool acdIsQtype(const AcdPAcd thys)
31766 {
31767     if((thys->Level == ACD_QUAL) || (thys->Level == ACD_PARAM))
31768 	return ajTrue;
31769 
31770     return ajFalse;
31771 }
31772 
31773 
31774 
31775 
31776 /* @funcstatic acdIsStype *****************************************************
31777 **
31778 ** Tests whether an ACD object is a section or endsection type.
31779 **
31780 ** @param [r] thys [const AcdPAcd] ACD object
31781 ** @return [AjBool] ajTrue if the object is a section or endsection
31782 **                  type definition
31783 **
31784 ** @release 2.3.0
31785 ** @@
31786 ******************************************************************************/
31787 
acdIsStype(const AcdPAcd thys)31788 static AjBool acdIsStype(const AcdPAcd thys)
31789 {
31790     if((thys->Level == ACD_SEC) || (thys->Level == ACD_ENDSEC))
31791 	return ajTrue;
31792 
31793     return ajFalse;
31794 }
31795 
31796 
31797 
31798 
31799 /* @funcstatic acdIsAtype *****************************************************
31800 **
31801 ** Tests whether an ACD object is an application type.
31802 **
31803 ** @param [r] thys [const AcdPAcd] ACD object
31804 ** @return [AjBool] ajTrue if the object is an application type definition
31805 **
31806 ** @release 6.1.0
31807 ** @@
31808 ******************************************************************************/
31809 
acdIsAtype(const AcdPAcd thys)31810 static AjBool acdIsAtype(const AcdPAcd thys)
31811 {
31812     if(thys->Level == ACD_APPL)
31813 	return ajTrue;
31814 
31815     return ajFalse;
31816 }
31817 
31818 
31819 
31820 
31821 /* @funcstatic acdIsVtype *****************************************************
31822 **
31823 ** Tests whether an ACD object is a variable type.
31824 **
31825 ** @param [r] thys [const AcdPAcd] ACD object
31826 ** @return [AjBool] ajTrue if the object is a variable type definition
31827 **
31828 ** @release 6.1.0
31829 ** @@
31830 ******************************************************************************/
31831 
acdIsVtype(const AcdPAcd thys)31832 static AjBool acdIsVtype(const AcdPAcd thys)
31833 {
31834     if(thys->Level == ACD_VAR)
31835 	return ajTrue;
31836 
31837     return ajFalse;
31838 }
31839 
31840 
31841 
31842 
31843 /* @funcstatic acdTextFormat **************************************************
31844 **
31845 ** Converts backslash codes in a string into special characters
31846 **
31847 ** @param [u] text [AjPStr*] Text with backslash codes
31848 ** @return [AjBool] ajTrue if successful
31849 **
31850 ** @release 1.0.0
31851 ** @@
31852 ******************************************************************************/
31853 
acdTextFormat(AjPStr * text)31854 static AjBool acdTextFormat(AjPStr* text)
31855 {
31856     ajStrExchangeCC(text, " \\ ", "\n");
31857 
31858     return ajTrue;
31859 }
31860 
31861 
31862 
31863 
31864 /* @funcstatic acdTextTrim*****************************************************
31865 **
31866 ** Trims white space. For HTML output, replaces angled brackets
31867 **
31868 ** @param [u] text [AjPStr*] Text to be processed
31869 ** @return [void]
31870 **
31871 ** @release 4.1.0
31872 ** @@
31873 ******************************************************************************/
31874 
acdTextTrim(AjPStr * text)31875 static void acdTextTrim(AjPStr* text)
31876 {
31877     ajStrTrimC(text, " \t\n\r");
31878 
31879     if(acdDoTable)
31880     {
31881 	ajStrExchangeCC(text, "<", "&lt;");
31882 	ajStrExchangeCC(text, ">", "&gt;");
31883     }
31884 
31885     return;
31886 }
31887 
31888 
31889 
31890 
31891 /* @section print *************************************************************
31892 **
31893 ** @fdata [none]
31894 **
31895 ** Print internal details for use by entrails
31896 **
31897 ** @nam3rule Print Print internal details
31898 ** @nam4rule PrintAppl Print details of ACD application attributes
31899 ** @nam4rule PrintQual Print details of ACD datatype known qualifiers
31900 ** @nam4rule PrintType Print details of ACD datatypes
31901 **
31902 ** @argrule Print outf [AjPFile] Output file
31903 ** @argrule Print full [AjBool] Print full details
31904 **
31905 ** @valrule * [void]
31906 ** @fcategory misc
31907 **
31908 ******************************************************************************/
31909 
31910 
31911 
31912 
31913 /* @func ajAcdPrintAppl *******************************************************
31914 **
31915 ** Report details of all known ACD attributes for all applications.
31916 ** For use by EMBOSS entrails.
31917 **
31918 ** @param [u] outf [AjPFile] Output file
31919 ** @param [r] full [AjBool] Full report - currently no extra details printed
31920 ** @return [void]
31921 **
31922 **
31923 ** @release 4.0.0
31924 ******************************************************************************/
31925 
ajAcdPrintAppl(AjPFile outf,AjBool full)31926 void ajAcdPrintAppl(AjPFile outf, AjBool full)
31927 {
31928     ajint i;
31929     AcdPAttr attr;
31930     AjPStr tmpstr = NULL;
31931     ajuint maxtmp = 0;
31932 
31933     if(full)
31934 	ajFmtPrintF(outf, "\n");
31935     else
31936 	ajFmtPrintF(outf, "\n");
31937 
31938     ajFmtPrintF(outf, "# ACD Application Attributes\n");
31939     ajFmtPrintF(outf, "# Attribute       Type       Default      Helptext\n");
31940 
31941     ajFmtPrintF(outf, "AttrAppl {\n");
31942 
31943     for(i=0; acdAttrAppl[i].Name; i++)
31944     {
31945 	attr = &acdAttrAppl[i];
31946 	ajFmtPrintF(outf, "  %-15s", attr->Name);
31947 	ajFmtPrintF(outf, " %-10s", acdValNames[attr->Type]);
31948 	ajFmtPrintS(&tmpstr, "\"%s\"", attr->Default);
31949 
31950 	if(ajStrGetLen(tmpstr) > maxtmp)
31951 	    maxtmp = ajStrGetLen(tmpstr);
31952 
31953 	ajFmtPrintF(outf, " %-12S", tmpstr);
31954 	ajFmtPrintF(outf, " \"%s\"", attr->Help);
31955 	ajFmtPrintF(outf, "\n");
31956     }
31957 
31958     ajFmtPrintF(outf, "}\n\n");
31959 
31960     if(maxtmp > 12) ajWarn("ajAcdPrintAppl max tmpstr len %d",
31961 			maxtmp);
31962     ajStrDel(&tmpstr);
31963 
31964     return;
31965 }
31966 
31967 
31968 
31969 
31970 /* @func ajAcdPrintQual *******************************************************
31971 **
31972 ** Report details of all known ACD qualifiers for all applications.
31973 ** For use by EMBOSS entrails.
31974 **
31975 ** @param [u] outf [AjPFile] Output file
31976 ** @param [r] full [AjBool] Full report - currently no extra details printed
31977 ** @return [void]
31978 **
31979 **
31980 ** @release 2.8.0
31981 ******************************************************************************/
31982 
ajAcdPrintQual(AjPFile outf,AjBool full)31983 void ajAcdPrintQual(AjPFile outf, AjBool full)
31984 {
31985     ajint i;
31986     AcdPQual qual;
31987     AjPStr tmpstr = NULL;
31988     ajuint maxtmp = 0;
31989 
31990     if(full)
31991 	ajFmtPrintF(outf, "\n");
31992     else
31993 	ajFmtPrintF(outf, "\n");
31994 
31995     ajFmtPrintF(outf, "# ACD Application Qualifiers\n");
31996     ajFmtPrintF(outf, "# Qualifier       Type        Default     Helptext\n");
31997     ajFmtPrintF(outf, "QualAppl {\n");
31998 
31999     for(i=0; acdQualAppl[i].Name; i++)
32000     {
32001 	qual = &acdQualAppl[i];
32002 	ajFmtPrintF(outf, "  %-15s", qual->Name);
32003 	ajFmtPrintF(outf, " %-10s", qual->Type);
32004 	ajFmtPrintS(&tmpstr, " \"%s\"", qual->Default);
32005 
32006 	if(ajStrGetLen(tmpstr) > maxtmp)
32007 	    maxtmp = ajStrGetLen(tmpstr);
32008 	ajFmtPrintF(outf, " %-12S", tmpstr);
32009 	ajFmtPrintF(outf, " \"%s\"", qual->Help);
32010 	ajFmtPrintF(outf, "\n");
32011     }
32012 
32013     ajFmtPrintF(outf, "}\n\n");
32014     if(maxtmp > 12) ajWarn("ajAcdPrintQual max tmpstr len %d",
32015 			maxtmp);
32016     ajStrDel(&tmpstr);
32017 
32018     return;
32019 }
32020 
32021 
32022 
32023 
32024 /* @func ajAcdPrintType *******************************************************
32025 **
32026 ** Report details of all known ACD types.
32027 ** For use by EMBOSS entrails.
32028 **
32029 ** @param [u] outf [AjPFile] Output file
32030 ** @param [r] full [AjBool] Full report
32031 ** @return [void]
32032 **
32033 **
32034 ** @release 1.0.0
32035 ******************************************************************************/
32036 
ajAcdPrintType(AjPFile outf,AjBool full)32037 void ajAcdPrintType(AjPFile outf, AjBool full)
32038 {
32039     AcdPType pat;
32040     AcdPAttr attr;
32041     AcdPQual qual;
32042     ajint i;
32043     AjPStr tmpstr = NULL;
32044     ajuint maxtmp = 0;
32045 
32046     ajFmtPrintF(outf, "\n");
32047     ajFmtPrintF(outf, "# ACD Types\n");
32048     ajFmtPrintF(outf, "# Name           Group      Description\n");
32049     ajFmtPrintF(outf, "#     Attribute       Type       "
32050 		"Default      Comment\n");
32051     ajFmtPrintF(outf, "#     Qualifier       Type       "
32052 		"Default      Helptext\n");
32053     ajFmtPrintF(outf, "AcdType {\n");
32054 
32055     for(i=0; acdType[i].Name; i++)
32056     {
32057 	pat = &acdType[i];
32058 	ajFmtPrintF(outf, "  %-14s", pat->Name);
32059 	ajFmtPrintF(outf, " %-10s", pat->Group);
32060 	ajFmtPrintF(outf, " \"%s\"", pat->Valid);
32061 	ajFmtPrintF(outf, "\n");
32062 
32063 	if(full && pat->Attr)
32064 	{
32065 	    ajFmtPrintF(outf, "    attributes {\n");
32066 
32067 	    for(attr=pat->Attr; attr->Name; attr++)
32068 	    {
32069 		ajFmtPrintF(outf, "      %-15s", attr->Name);
32070 		ajFmtPrintF(outf, " %-10s", acdValNames[attr->Type]);
32071 		ajFmtPrintS(&tmpstr, "\"%s\"", attr->Default);
32072 
32073 		if(ajStrGetLen(tmpstr) > maxtmp)
32074 		    maxtmp = ajStrGetLen(tmpstr);
32075 
32076 		ajFmtPrintF(outf, " %-12S", tmpstr);
32077 		ajFmtPrintF(outf, " \"%s\"", attr->Help);
32078 		ajFmtPrintF(outf, "\n");
32079 	    }
32080 
32081 	    ajFmtPrintF(outf, "    }\n");
32082 	}
32083 
32084 	if(pat->Quals)
32085 	{
32086 	    ajFmtPrintF(outf, "    qualifiers {\n");
32087 
32088 	    for(qual=pat->Quals; qual->Name; qual++)
32089 	    {
32090 		ajFmtPrintF(outf, "      %-15s", qual->Name);
32091 		ajFmtPrintF(outf, " %-10s", qual->Type);
32092 		ajFmtPrintS(&tmpstr, "\"%s\"", qual->Default);
32093 
32094 		if(ajStrGetLen(tmpstr) > maxtmp)
32095 		    maxtmp = ajStrGetLen(tmpstr);
32096 
32097 		ajFmtPrintF(outf, " %-12S", tmpstr);
32098 		ajFmtPrintF(outf, " \"%s\"", qual->Help);
32099 		ajFmtPrintF(outf, "\n");
32100 	    }
32101 	    ajFmtPrintF(outf, "    }\n");
32102 	}
32103     }
32104     ajFmtPrintF(outf, "}\n");
32105 
32106     ajFmtPrintF(outf, "# ACD Default attributes\n");
32107     ajFmtPrintF(outf, "# Name             Type     Default        Comment\n");
32108 
32109     for(i=0; acdAttrDef[i].Name; i++)
32110     {
32111 	ajFmtPrintF(outf, "  %-15s", acdAttrDef[i].Name);
32112 	ajFmtPrintF(outf, "  %-10s", acdValNames[acdAttrDef[i].Type]);
32113 	ajFmtPrintS(&tmpstr, "\"%s\"", acdAttrDef[i].Default);
32114 
32115 	if(ajStrGetLen(tmpstr) > maxtmp)
32116 	    maxtmp = ajStrGetLen(tmpstr);
32117 
32118 	ajFmtPrintF(outf, " %-12S", tmpstr);
32119 	ajFmtPrintF(outf, " \"%s\"", acdAttrDef[i].Help);
32120 	ajFmtPrintF(outf, "\n");
32121     }
32122 
32123     ajFmtPrintF(outf, "\n");
32124 
32125     ajFmtPrintF(outf, "# ACD Calculated attributes\n");
32126     ajFmtPrintF(outf, "# Name\n");
32127     ajFmtPrintF(outf, "#     Attribute      Type       "
32128 		"Default              Comment\n");
32129 
32130     acdPrintCalcattr(outf, "distances", acdCalcDistances);
32131     acdPrintCalcattr(outf, "features", acdCalcFeat);
32132     acdPrintCalcattr(outf, "frequencies", acdCalcFrequencies);
32133     acdPrintCalcattr(outf, "properties", acdCalcProperties);
32134     acdPrintCalcattr(outf, "regexp", acdCalcRegexp);
32135     acdPrintCalcattr(outf, "sequence", acdCalcSeq);
32136     acdPrintCalcattr(outf, "seqall", acdCalcSeqall);
32137     acdPrintCalcattr(outf, "seqset", acdCalcSeqset);
32138     acdPrintCalcattr(outf, "seqsetall", acdCalcSeqsetall);
32139     acdPrintCalcattr(outf, "string", acdCalcString);
32140     acdPrintCalcattr(outf, "tree", acdCalcTree);
32141     ajFmtPrintF(outf, "\n");
32142 
32143     if(maxtmp > 12)
32144         ajWarn("ajAcdPrintType max tmpstr len %d",
32145                maxtmp);
32146 
32147     ajStrDel(&tmpstr);
32148 
32149     return;
32150 }
32151 
32152 
32153 
32154 
32155 /* @funcstatic acdPrintCalcattr ***********************************************
32156 **
32157 ** Report calculated attributes set
32158 ** For use by EMBOSS entrails.
32159 **
32160 ** @param [u] outf [AjPFile] Output file
32161 ** @param [r] acdtype [const char*] ACD type name
32162 ** @param [r] calcattr [const AcdOAttr[]] Acd calculated attributes
32163 ** @return [void]
32164 **
32165 **
32166 ** @release 4.0.0
32167 ******************************************************************************/
32168 
acdPrintCalcattr(AjPFile outf,const char * acdtype,const AcdOAttr calcattr[])32169 static void acdPrintCalcattr(AjPFile outf, const char* acdtype,
32170 			     const AcdOAttr calcattr[])
32171 {
32172     ajint i;
32173 
32174     AjPStr tmpstr = NULL;
32175     ajuint maxtmp = 0;
32176 
32177     ajFmtPrintF(outf, "  %s",acdtype);
32178     ajFmtPrintF(outf, "\n");
32179     ajFmtPrintF(outf, "    attributes {\n");
32180 
32181     for(i=0; calcattr[i].Name; i++)
32182     {
32183 	ajFmtPrintF(outf, "      %-14s", calcattr[i].Name);
32184 	ajFmtPrintF(outf, " %-10s", acdValNames[calcattr[i].Type]);
32185 	ajFmtPrintS(&tmpstr, "\"%s\"", calcattr[i].Default);
32186 
32187 	if(ajStrGetLen(tmpstr) > maxtmp)
32188 	    maxtmp = ajStrGetLen(tmpstr);
32189 
32190 	ajFmtPrintF(outf, " %-20S", tmpstr);
32191 	ajFmtPrintF(outf, " \"%s\"", calcattr[i].Help);
32192 	ajFmtPrintF(outf, "\n");
32193     }
32194 
32195     ajFmtPrintF(outf, "    }\n");
32196 
32197     if(maxtmp > 20)
32198         ajWarn("acdPrintCalcAttr max tmpstr len %d",
32199                maxtmp);
32200 
32201     ajStrDel(&tmpstr);
32202 
32203     return;
32204 }
32205 
32206 
32207 
32208 
32209 /* @funcstatic acdVocabCheck **************************************************
32210 **
32211 ** Checks for a string in a controlled vocabulary of character strings,
32212 ** ended with a NULL.
32213 **
32214 ** @param [r] str [const AjPStr] Test string
32215 ** @param [r] vocab [const char**] Controlled vocabulary
32216 ** @return [AjBool] ajTrue if the string matched on of the words
32217 **
32218 ** @release 2.0.0
32219 ******************************************************************************/
32220 
acdVocabCheck(const AjPStr str,const char ** vocab)32221 static AjBool acdVocabCheck(const AjPStr str, const char** vocab)
32222 {
32223     ajint i = 0;
32224 
32225     while(vocab[i])
32226     {
32227 	if(ajStrMatchCaseC(str, vocab[i]))
32228 	    return ajTrue;
32229 
32230 	i++;
32231     }
32232 
32233     return ajFalse;
32234 }
32235 
32236 
32237 
32238 
32239 /* @funcstatic acdError *******************************************************
32240 **
32241 ** Formatted write as an error message, then exits with ajExitBad
32242 **
32243 ** @param [r] fmt [const char*] Format string
32244 ** @param [v] [...] Format arguments.
32245 ** @return [void]
32246 **
32247 ** @release 2.7.0
32248 ** @@
32249 ******************************************************************************/
32250 
acdError(const char * fmt,...)32251 __noreturn static void acdError(const char* fmt, ...)
32252 {
32253     va_list args ;
32254     AjPStr errstr = NULL;
32255     ajint linenum;
32256 
32257     acdErrorCount++;
32258 
32259     va_start(args, fmt) ;
32260     ajFmtVPrintS(&errstr, fmt, args);
32261     va_end(args) ;
32262 
32263     if(acdLineNum > 0)
32264 	linenum = acdLineNum;
32265     else if(acdSetCurr)
32266 	linenum = acdSetCurr->LineNum;
32267     else if(acdProcCurr)
32268 	linenum = acdProcCurr->LineNum;
32269     else if(acdListCurr)
32270 	linenum = acdListCurr->LineNum;
32271     else
32272 	linenum = 0;
32273 
32274     ajErr("File %S line %d: %S", acdFName, linenum, errstr);
32275     ajStrDel(&errstr);
32276     ajExitBad();
32277 }
32278 
32279 
32280 
32281 
32282 /* @funcstatic acdErrorValid **************************************************
32283 **
32284 ** Formatted write as an error message, then continues (acdError exits)
32285 **
32286 ** @param [r] fmt [const char*] Format string
32287 ** @param [v] [...] Format arguments.
32288 ** @return [void]
32289 **
32290 ** @release 2.7.0
32291 ** @@
32292 ******************************************************************************/
32293 
acdErrorValid(const char * fmt,...)32294 static void acdErrorValid(const char* fmt, ...)
32295 {
32296     va_list args;
32297     AjPStr errstr=NULL;
32298     ajint linenum;
32299     acdErrorCount++;
32300 
32301     va_start(args, fmt) ;
32302     ajFmtVPrintS(&errstr, fmt, args);
32303     va_end(args) ;
32304 
32305     if(acdLineNum > 0)
32306 	linenum = acdLineNum;
32307     else if(acdSetCurr)
32308 	linenum = acdSetCurr->LineNum;
32309     else if(acdProcCurr)
32310 	linenum = acdProcCurr->LineNum;
32311     else if(acdListCurr)
32312 	linenum = acdListCurr->LineNum;
32313     else
32314 	linenum = 0;
32315 
32316     ajErr("File %S line %d: %S", acdFName, linenum, errstr);
32317     ajStrDel(&errstr);
32318 
32319     return;
32320 }
32321 
32322 
32323 
32324 
32325 /* @funcstatic acdWarnObsolete ************************************************
32326 **
32327 ** Warning about obsolete status of an application
32328 **
32329 ** @param [r] str [const AjPStr] Format string
32330 ** @return [void]
32331 **
32332 ** @release 6.0.0
32333 ** @@
32334 ******************************************************************************/
32335 
acdWarnObsolete(const AjPStr str)32336 static void acdWarnObsolete(const AjPStr str)
32337 {
32338     AjPStr outstr = NULL;
32339     AjPStr tmpstr = NULL;
32340     AjBool warnobsolete = ajTrue;
32341 
32342     if(ajNamGetValueC("warnobsolete", &tmpstr))
32343 	ajStrToBool(tmpstr, &warnobsolete);
32344 
32345     ajStrDel(&tmpstr);
32346 
32347     if(!warnobsolete)
32348         return;
32349 
32350     ajFmtPrintS(&outstr, "Application %S is marked as obsolete.\n%S",
32351                 acdProgram, str);
32352     ajStrFmtWrap(&outstr, 75);
32353     ajWarn("%S", outstr);
32354 
32355     ajStrDel(&outstr);
32356 
32357     return;
32358 }
32359 
32360 
32361 
32362 
32363 /* @funcstatic acdWarn ********************************************************
32364 **
32365 ** Formatted write as an error message.
32366 **
32367 ** @param [r] fmt [const char*] Format string
32368 ** @param [v] [...] Format arguments.
32369 ** @return [void]
32370 **
32371 ** @release 2.7.0
32372 ** @@
32373 ******************************************************************************/
32374 
acdWarn(const char * fmt,...)32375 static void acdWarn(const char* fmt, ...)
32376 {
32377     va_list args;
32378     AjPStr errstr = NULL;
32379     ajint linenum;
32380 
32381     acdErrorCount++;
32382 
32383     va_start(args, fmt) ;
32384     ajFmtVPrintS(&errstr, fmt, args);
32385     va_end(args) ;
32386 
32387     if(acdLineNum > 0)
32388 	linenum = acdLineNum;
32389     else if(acdSetCurr)
32390 	linenum = acdSetCurr->LineNum;
32391     else if(acdProcCurr)
32392 	linenum = acdProcCurr->LineNum;
32393     else if(acdListCurr)
32394 	linenum = acdListCurr->LineNum;
32395     else
32396 	linenum = 0;
32397 
32398     ajWarn("File %S line %d: %S", acdFName, linenum, errstr);
32399     ajStrDel(&errstr);
32400 
32401     return;
32402 }
32403 
32404 
32405 
32406 
32407 /* @funcstatic acdErrorAcd ****************************************************
32408 **
32409 ** Formatted write as an error message, for a specified ACD object
32410 **
32411 ** @param [r] thys [const AcdPAcd] ACD object
32412 ** @param [r] fmt [const char*] Format string
32413 ** @param [v] [...] Format arguments.
32414 ** @return [void]
32415 **
32416 ** @release 2.7.0
32417 ** @@
32418 ******************************************************************************/
32419 
acdErrorAcd(const AcdPAcd thys,const char * fmt,...)32420 __noreturn static void acdErrorAcd(const AcdPAcd thys, const char* fmt, ...)
32421 {
32422     va_list args;
32423     AjPStr errstr = NULL;
32424 
32425     acdErrorCount++;
32426     ajUtilCatch();
32427     va_start(args, fmt) ;
32428     ajFmtVPrintS(&errstr, fmt, args);
32429     va_end(args) ;
32430 
32431     ajErr("File %S line %d: (%S) %S",
32432 	  acdFName, thys->LineNum, thys->Name, errstr);
32433     ajStrDel(&errstr);
32434     ajExitBad();
32435 }
32436 
32437 
32438 
32439 
32440 /* @section exit **************************************************************
32441 **
32442 ** Functions called on exit
32443 **
32444 ** @fdata [none]
32445 **
32446 ** @nam3rule Exit Cleanup of internals when program exits
32447 **
32448 ** @argrule Exit silent [AjBool] If false, produce warnings for unused
32449 **                               ACD datatype definitions
32450 **
32451 ** @valrule * [void]
32452 ** @fcategory misc
32453 **
32454 ******************************************************************************/
32455 
32456 
32457 
32458 
32459 /* @func ajAcdExit ************************************************************
32460 **
32461 ** Reports any unused ACD values
32462 **
32463 ** Cleans up ACD processing  internal memory
32464 **
32465 ** @param [r] silent [AjBool] Turn off messages (used when some messages
32466 **                            are expected but can be ignored).
32467 ** @return [void]
32468 **
32469 ** @release 2.4.0
32470 ** @@
32471 ******************************************************************************/
32472 
ajAcdExit(AjBool silent)32473 void ajAcdExit(AjBool silent)
32474 {
32475     AcdPAcd pa;
32476     static AjBool staySilent = AJFALSE;
32477     AjPFile cmdlogfile = NULL;
32478     AjPStr  cmdlog     = NULL;
32479     AjPStr  cmdstr     = NULL;
32480 
32481     if(silent)
32482 	staySilent = ajTrue;
32483 
32484     if(acdDoHelp)
32485 	staySilent = ajTrue;
32486 
32487     if(acdDoPretty)
32488 	staySilent = ajTrue;
32489 
32490     if(!staySilent)
32491     {
32492 	/* turn off the warnings for now ... comment out this line to
32493 	 ** enable them.
32494 	 ** the problem is that some programs have conditionals around the
32495 	 ** ajAcdGet calls so they can sometimes fail to use values, even where
32496 	 ** the test cases say they are fine.
32497 	 ** also some ACD files (showdb for example) use values,
32498 	 ** but in some cases (showdb with all booleans on the command line)
32499 	 ** the value is not needed
32500 	 */
32501 
32502 /*	ajDebug("ajAcdExit Name................ Assoc Level  Used\n");*/
32503 	for(pa=acdList; pa; pa=pa->Next)
32504 	{
32505 	    /*ajDebug("ajAcdExit %20S   %3B   %3d   %3B\n",
32506 		    pa->Name, pa->Assoc, pa->Level, pa->Used); */
32507 	    if(pa->Assoc)
32508 		continue;
32509 	    if(pa->Level != ACD_PARAM && pa->Level != ACD_QUAL)
32510 		continue;
32511 	    if(!pa->Used)
32512 		acdLog("ACD qualifier never used: %S = '%S' (assoc %B)",
32513 		       pa->Name, pa->ValStr, pa->Assoc);
32514 	}
32515     }
32516 
32517 
32518     /* report the command line to a log if requested.
32519      ** added mainly to log command lines for the QA tests
32520      ** so they can also be used in memory leak tests
32521      **
32522      ** Need to test acdProgram is still set - acdc calls this twice
32523      */
32524 
32525     if(acdCommandLine &&
32526        ajStrGetLen(acdProgram) &&
32527        ajNamGetValueC("acdcommandlinelog", &cmdlog))
32528     {
32529 	cmdlogfile = ajFileNewOutappendNameS(cmdlog);
32530 	ajStrAssignS(&cmdstr, acdArgSave);
32531 	if(ajStrGetLen(acdInputSave))
32532 	{
32533 	    ajStrAppendK(&cmdstr, ' ');
32534 	    ajStrAppendS(&cmdstr, acdInputSave);
32535 	}
32536 	ajStrRemoveWhiteExcess(&cmdstr);
32537 	ajFmtPrintF(cmdlogfile, "%S %S\n", acdProgram, cmdstr);
32538 	ajFileClose(&cmdlogfile);
32539 	ajStrDel(&cmdlog);
32540 	ajStrDel(&cmdstr);
32541     }
32542 
32543 
32544     /*
32545     ** clean up memory:
32546     **
32547     */
32548 
32549     acdReset();
32550 
32551     return;
32552 }
32553 
32554 
32555 
32556 
32557 /* @funcstatic acdPrintUsed ***************************************************
32558 **
32559 ** Quick printoout of all qualifiers believed to have been used
32560 **
32561 ** @return [void]
32562 **
32563 ** @release 6.0.0
32564 ******************************************************************************/
32565 
acdPrintUsed(void)32566 static void acdPrintUsed(void)
32567 {
32568     AcdPAcd pa;
32569 
32570     ajUserDumpS(acdArgSave);
32571 
32572     for(pa=acdList; pa; pa=pa->Next)
32573         if(pa->UserDefined)
32574             ajUser("ACD qual defined: '%S'", pa->Name);
32575 
32576     return;
32577 }
32578 
32579 
32580 
32581 
32582 /* @funcstatic acdReset *******************************************************
32583 **
32584 ** Cleans up all memory allocated to ACD internals.
32585 **
32586 ** All ACD objects are assumed to have been passed to the calling program
32587 ** and are no longer "owned" by ACD.
32588 **
32589 ** In future, we could consider removing them once they have been fetched.
32590 **
32591 ** @return [void]
32592 **
32593 ** @release 4.0.0
32594 ******************************************************************************/
32595 
acdReset(void)32596 static void acdReset(void)
32597 {
32598     AcdPAcd pa;
32599     AcdPAcd qa = NULL;
32600 
32601     /* acdPrintUsed(); */
32602 
32603     for(pa=acdList; pa; pa=qa)
32604     {
32605 	qa = pa->Next;
32606 	acdDel(&pa);
32607     }
32608 
32609     ajStrDel(&acdPackName);
32610     ajStrDel(&acdPackVersion);
32611 
32612     ajTablestrFree(&acdKnowntypeTypeTable);
32613     ajTablestrFree(&acdKnowntypeDescTable);
32614     ajTablestrFree(&acdCodeTable);
32615     ajTablestrFree(&acdGrpTable);
32616 
32617     ajStrDel(&acdTmpStr);
32618     ajStrDel(&acdTmpStr2);
32619 
32620     ajStrDel(&acdPrefName);
32621     ajStrDel(&acdPrefToken);
32622 
32623     ajStrDel(&acdArgSave);
32624     ajStrDel(&acdInputSave);
32625     ajStrDel(&acdInputName);
32626     ajStrDel(&acdInFName);
32627     ajStrDel(&acdOutFName);
32628     ajStrDel(&acdOutFExt);
32629     ajStrDel(&acdInTypeFeatName);
32630     ajStrDel(&acdInTypeSeqName);
32631     ajStrDel(&acdTmpOutFName);
32632 
32633     ajStrDel(&acdLogFName);
32634     ajFileClose(&acdLogFile);
32635 
32636     ajListstrFreeData(&acdSecList);
32637     ajTablestrFree(&acdSecTable);
32638     ajTablestrFree(&acdExternalTable);
32639 
32640     ajStrDel(&acdPrettyFName);
32641     ajFileClose(&acdPrettyFile);
32642     ajStrDel(&acdFName);
32643     ajStrDel(&acdOutFullFName);
32644     ajStrDel(&acdVarAcdProtein);
32645 
32646     acdParseQuotes = ajFalse;
32647     ajStrDel(&acdParseReturn);
32648     ajStrDel(&acdReply);
32649     ajStrDel(&acdReplyDef);
32650     ajStrDel(&acdReplyPrompt);
32651     ajStrDel(&acdUserMsg);
32652     ajStrDel(&acdUserReplyDef);
32653     ajStrDel(&acdDirectoryDef);
32654     ajStrDel(&acdQNameTmp);
32655     ajStrDel(&acdQTypeTmp);
32656     ajStrDel(&acdAttrValTmp);
32657     ajStrDel(&acdQualNameTmp);
32658     ajStrDel(&acdQualNumTmp);
32659 
32660     ajRegFree(&acdRegQualParse);
32661     ajRegFree(&acdRegVarname);
32662     ajRegFree(&acdRegFunction);
32663     ajRegFree(&acdRegToggle);
32664     ajRegFree(&acdRegResolveVar);
32665     ajRegFree(&acdRegResolveFun);
32666 
32667     ajRegFree(&acdRegExpPlusI);
32668     ajRegFree(&acdRegExpPlusD);
32669     ajRegFree(&acdRegExpMinusI);
32670     ajRegFree(&acdRegExpMinusD);
32671     ajRegFree(&acdRegExpStarI);
32672     ajRegFree(&acdRegExpStarD);
32673     ajRegFree(&acdRegExpDivI);
32674     ajRegFree(&acdRegExpDivD);
32675     ajRegFree(&acdRegExpEqualI);
32676     ajRegFree(&acdRegExpEqualD);
32677     ajRegFree(&acdRegExpEqualT);
32678     ajRegFree(&acdRegExpNeI);
32679     ajRegFree(&acdRegExpNeD);
32680     ajRegFree(&acdRegExpNeT);
32681     ajRegFree(&acdRegExpGtI);
32682     ajRegFree(&acdRegExpGtD);
32683     ajRegFree(&acdRegExpGtT);
32684     ajRegFree(&acdRegExpLtI);
32685     ajRegFree(&acdRegExpLtD);
32686     ajRegFree(&acdRegExpLtT);
32687     ajRegFree(&acdRegExpOrI);
32688     ajRegFree(&acdRegExpOrD);
32689     ajRegFree(&acdRegExpOrT);
32690     ajRegFree(&acdRegExpAndI);
32691     ajRegFree(&acdRegExpAndD);
32692     ajRegFree(&acdRegExpAndT);
32693     ajRegFree(&acdRegExpCond);
32694     ajRegFree(&acdRegExpNot);
32695     ajRegFree(&acdRegExpOneofCase);
32696     ajRegFree(&acdRegExpOneofList);
32697     ajRegFree(&acdRegExpCaseCase);
32698     ajRegFree(&acdRegExpCaseList);
32699     ajRegFree(&acdRegExpFilename);
32700     ajRegFree(&acdRegExpFileExists);
32701     ajRegFree(&acdRegExpValue);
32702 
32703     ajListFreeData(&acdListCommentsCount);
32704     ajListFreeData(&acdListCommentsColumn);
32705     ajListstrFreeData(&acdListComments);
32706 
32707     ajStrDel(&acdProgram);
32708     ajStrDel(&acdAppldoc);
32709     AJFREE(acdParamSet);
32710 
32711     acdDoHelp = AJFALSE;
32712     acdDoLog = AJFALSE;
32713     acdDoWarnRange =AJTRUE;
32714     acdDoPretty = AJFALSE;
32715     acdDoTable = AJFALSE;
32716     acdDoValid = AJFALSE;
32717     acdVerbose = AJFALSE;
32718     acdAuto = AJFALSE;
32719     acdFilter = AJFALSE;
32720     acdOptions = AJFALSE;
32721     acdStdout = AJFALSE;
32722     acdCodeSet = AJFALSE;
32723     acdKnowntypeSet = AJFALSE;
32724     acdWrapper = AJFALSE;
32725 /*    acdQualTestSkip = AJFALSE; */
32726     acdInFile = 0;
32727     acdInFileSet = AJFALSE;
32728     acdOutFile = 0;
32729     acdPromptTry = 2;
32730     acdPrettyMargin = 0;
32731     acdPrettyIndent = 2;
32732     acdLineNum = 0;
32733     acdWordNum = 0;
32734     acdErrorCount = 0;
32735     acdUseData = 0;
32736     acdUseFeatures = 0;
32737     acdUseInfile = 0;
32738     acdUseSeq = 0;
32739     acdUseAlign = 0;
32740     acdUseFeatout = 0;
32741     acdUseOutfile = 0;
32742     acdUseReport = 0;
32743     acdUseSeqout = 0;
32744     acdUseGraph = 0;
32745     acdUseMisc = 0;
32746     acdCurrentStage = NO_STAGE;
32747     acdNParam=0;
32748 
32749     acdNewCurr = NULL;
32750     acdMasterQual = NULL;
32751     acdList = NULL;
32752     acdListLast = NULL;
32753     acdListCurr = NULL;
32754     acdProcCurr = NULL;
32755     acdSetCurr = NULL;
32756 
32757     return;
32758 }
32759 
32760 
32761 
32762 
32763 /* @funcstatic acdValidAppl ***************************************************
32764 **
32765 ** Validation for an application definition
32766 **
32767 ** @param [r] thys [const AcdPAcd] ACD object
32768 ** @return [void]
32769 **
32770 ** @release 2.7.0
32771 ** @@
32772 ******************************************************************************/
32773 
acdValidAppl(const AcdPAcd thys)32774 static void acdValidAppl(const AcdPAcd thys)
32775 {
32776     ajint i;
32777     ajuint idocmax = 70;			/* maximum length of
32778 					   documentation string */
32779 
32780     AjPStrTok tokenhandle = NULL;
32781     AjPStr relation = NULL;
32782     const AjPStr namespace;
32783     ajuint ireloper = 0;
32784     ajuint ireltopic = 0;
32785 
32786     if(!acdDoValid)
32787 	return;
32788 
32789     /* must have a documentation attribute */
32790 
32791     i = acdFindAttrC(acdAttrAppl, "documentation");
32792     if(!ajStrGetLen(thys->AttrStr[i]))
32793 	acdErrorValid("Application has no documentation defined");
32794 
32795     else
32796     {
32797 	if(!isupper((int)ajStrGetCharFirst(thys->AttrStr[i])))
32798 	{
32799 	    if (islower((int)ajStrGetCharFirst(thys->AttrStr[i])))
32800 		acdWarn("Documentation string starts in lower case");
32801 	    else
32802 		acdWarn("Documentation string starts non-alphabetic");
32803 	}
32804 	if (ajStrGetLen(thys->AttrStr[i]) > idocmax)
32805 		acdWarn("Documentation string %d exceeds %d characters",
32806 			ajStrGetLen(thys->AttrStr[i]), idocmax);
32807     }
32808 
32809     /* must have a group attribute */
32810 
32811     i = acdFindAttrC(acdAttrAppl, "groups");
32812 
32813     if(!ajStrGetLen(thys->AttrStr[i]))
32814 	acdErrorValid("Application has no groups defined");
32815 
32816     /* group must be a known group (and subgroup) */
32817 
32818     acdValidApplGroup(thys->AttrStr[i]);
32819 
32820     i = acdFindAttrC(acdAttrAppl, "keywords");
32821     acdValidApplKeywords(thys->AttrStr[i]);
32822 
32823         /* for now, skip EMBASSY applications */
32824 /*
32825     if(acdEdam)
32826     {
32827         i = acdFindAttrC(acdAttrAppl, "embassy");
32828         if(ajStrGetLen(thys->AttrStr[i]))
32829             acdEdam = NULL;
32830     }
32831 */
32832     if(acdEdam)
32833     {
32834         i = acdFindAttrC(acdAttrAppl, "relations");
32835         tokenhandle = ajStrTokenNewC(thys->AttrStr[i], "|");
32836 
32837         while(ajStrTokenNextParse(tokenhandle, &relation))
32838         {
32839             namespace = acdEdamTest(relation);
32840             if(!namespace)
32841                 acdErrorValid("Application relation '%S' not found",
32842                               relation);
32843             else if(ajStrMatchC(namespace, "operation"))
32844                 ireloper++;
32845             else if(ajStrMatchC(namespace, "topic"))
32846                 ireltopic++;
32847             else
32848                 acdErrorValid("Application has relation with namespace '%S'",
32849                               namespace);
32850         }
32851 
32852         if(!ireltopic)
32853             acdErrorValid("Application has no 'topic' relation");
32854         if(!ireloper)
32855             acdErrorValid("Application has no 'operation' relation");
32856 
32857         ajStrDel(&relation);
32858         ajStrTokenDel(&tokenhandle);
32859     }
32860 
32861     /*
32862     ** test for wrapper attribute
32863     ** if true, we use the original command line
32864     ** so we turn off EMBOSS validation of qualifier names
32865     */
32866 
32867     return;
32868 }
32869 
32870 
32871 
32872 
32873 /* @funcstatic acdValidRelation ***********************************************
32874 **
32875 ** Validation for a relation definition
32876 **
32877 ** @param [r] thys [const AcdPAcd] ACD object
32878 ** @return [void]
32879 **
32880 ** @release 2.9.0
32881 ** @@
32882 ******************************************************************************/
32883 
acdValidRelation(const AcdPAcd thys)32884 static void acdValidRelation(const AcdPAcd thys)
32885 {
32886     const AjPStr tmpstr   = NULL;
32887 
32888     if(!acdDoValid)
32889 	return;
32890 
32891     tmpstr = acdAttrValue(thys, "relations");
32892 
32893     if(!ajStrGetLen(tmpstr))
32894 	return;
32895 
32896     return;
32897 }
32898 
32899 
32900 
32901 
32902 /* @funcstatic acdValidSection ************************************************
32903 **
32904 ** Validation for a section definition
32905 **
32906 ** @param [r] thys [const AcdPAcd] ACD object
32907 ** @return [void]
32908 **
32909 ** @release 2.7.0
32910 ** @@
32911 ******************************************************************************/
32912 
acdValidSection(const AcdPAcd thys)32913 static void acdValidSection(const AcdPAcd thys)
32914 {
32915     static AjPTable typeTable = NULL;
32916     static AjPTable infoTable = NULL;
32917 
32918     static ajint sectLevel = 0;
32919     static ajint sectNumber= -1;
32920 
32921     const AjPStr sectType = NULL; /* string from table - no delete */
32922     const AjPStr sectInfo = NULL; /* string from table - no delete */
32923     const AjPStr tmpstr   = NULL;
32924     static AjPStr sectNameTop;
32925     ajint i;
32926 
32927 
32928     if(!acdDoValid)
32929 	return;
32930 
32931     if(!typeTable)
32932 	acdReadSections(&typeTable, &infoTable);
32933 
32934     if(ajCharMatchC(acdKeywords[thys->Type].Name, "endsection"))
32935     {
32936 	--sectLevel;
32937 	if(sectLevel < 0)
32938 	    acdErrorValid("Too many endsections");
32939 	return;
32940     }
32941 
32942     ++sectLevel;
32943 
32944     if(sectLevel == 1)
32945     {
32946 	ajStrAssignS(&sectNameTop, thys->Name);
32947 	for(i=0; acdSections[i]; i++)
32948 	{
32949 	    if(ajStrMatchC(thys->Name, acdSections[i]->Name))
32950 	    {
32951 		if(i < sectNumber)
32952 		    acdWarn("Section '%S' follows section '%s'",
32953 				 thys->Name, acdSections[sectNumber]->Name);
32954 		else
32955 		    sectNumber = i;
32956 		break;
32957 	    }
32958 	}
32959 
32960 	if(!acdSections[i])
32961 	    acdWarn("No defined order for primary section '%S'",
32962 		    thys->Name);
32963     }
32964     /* should have a known name */
32965 
32966     sectType = ajTableFetchS(typeTable, thys->Name);
32967     tmpstr = acdAttrValue(thys, "type");
32968 
32969     if(!sectType)
32970     {
32971 	if(sectLevel == 1)
32972 	    acdErrorValid("Section '%S' not defined in sections.standard file",
32973 			  thys->Name);
32974 	else
32975 	    acdWarn("Sub level section '%S' not defined in "
32976 		    "sections.standard file",
32977 		    thys->Name);
32978 	/* if unknown, must be distinctive - check for common words? */
32979 
32980 	return;
32981     }
32982     else
32983     {			     /* if known, must have a standard type */
32984 	if(sectLevel == 1)
32985 	{
32986 	    if(!ajStrMatchC(tmpstr, "page"))
32987 		acdErrorValid("Top level section '%S' not of type 'page'",
32988 			      thys->Name);
32989 
32990 	    else if(!ajStrMatchC(sectType, "page"))
32991 		acdErrorValid("Top level section '%S' defined as "
32992 			      "sub type of '%S' in sections.standard",
32993 			      thys->Name, sectType);
32994 	}
32995 	else
32996 	{
32997 	    if(ajStrMatchC(tmpstr, "page"))
32998 		acdErrorValid("Sub level section '%S' not of type 'frame'",
32999 			      thys->Name);
33000 	    else if(ajStrPrefixC(sectType, "page"))
33001 		acdErrorValid("Sub level section '%S' not defined "
33002 			      "as type 'frame' in sections.standard",
33003 			      thys->Name);
33004 	    else if(!ajStrMatchS(sectType, sectNameTop))
33005 		acdErrorValid("Sub level section '%S' should be under '%S'",
33006 			      thys->Name, sectType);
33007 	}
33008     }
33009 
33010     sectInfo = ajTableFetchS(infoTable, thys->Name);
33011     tmpstr = acdAttrValue(thys, "information");
33012 
33013     /* must have an information attribute */
33014 
33015     if(!ajStrGetLen(tmpstr))
33016 	acdWarn("Section has no information string");
33017 
33018     /* if known, must have a standard info string */
33019 
33020     else
33021     {
33022 	if(!ajStrMatchS(sectInfo, tmpstr))
33023 	{
33024 	    if(ajStrMatchCaseS(sectInfo, tmpstr))
33025 		acdWarn("Section info '%S' expected, case mismatch",
33026 			sectInfo);
33027 	    else
33028 		acdErrorValid("Section info '%S' expected, found '%S'",
33029 			      sectInfo, tmpstr);
33030 	}
33031     }
33032 
33033     return;
33034 }
33035 
33036 
33037 
33038 
33039 /* @funcstatic acdValidQual ***************************************************
33040 **
33041 ** Validation for a qualifier definition
33042 **
33043 ** @param [u] thys [AcdPAcd] ACD object
33044 ** @return [void]
33045 **
33046 ** @release 2.7.0
33047 ** @@
33048 ******************************************************************************/
33049 
acdValidQual(AcdPAcd thys)33050 static void acdValidQual(AcdPAcd thys)
33051 {
33052     ajint itype;
33053     AjBool isparam = ajFalse;
33054     AjBool boolval;
33055     AjBool toggle;
33056 
33057     AjBool isParameter = ajFalse;
33058     AjBool isStandard = ajFalse;
33059     AjBool isAdditional = ajFalse;
33060     AjBool isToggle = ajFalse;
33061 
33062     static AjPStr secname   = NULL;
33063     const AjPStr relstr    = NULL;
33064     const AjPStr tmpstr    = NULL;
33065     const AjPStr tmpinfo   = NULL;
33066     const AjPStr tmpprompt = NULL;
33067     const AjPStr tmphelp   = NULL;
33068     const AjPStr tmpstandard = NULL;
33069 
33070     static ajint qualCountSeq     = 0;
33071     static ajint qualCountSeqout  = 0;
33072     static ajint qualCountInfile  = 0;
33073     static ajint qualCountOutfile = 0;
33074     static ajint qualCountIn      = 0;
33075     static ajint qualCountOut     = 0;
33076     static ajint qualCountFeat    = 0;
33077     static ajint qualCountFeatout = 0;
33078 
33079     static AjPStr qualName         = NULL;
33080     static AjPStr qualSeqFirst     = NULL;
33081     static AjPStr qualSeqoutFirst  = NULL;
33082     static AjPStr seqTypeIn        = NULL;
33083     static AjPStr qualFeatFirst    = NULL;
33084     static AjPStr qualFeatoutFirst = NULL;
33085 
33086     static AjBool seqMulti     = AJFALSE;
33087     static AjBool seqoutMulti  = AJFALSE;
33088     static AjBool featMulti    = AJFALSE;
33089     static AjBool featoutMulti = AJFALSE;
33090     const AjPStr namespace = NULL;
33091     AjPStr relation = NULL;
33092     AjPStrTok tokenhandle = NULL;
33093     ajuint ireldata = 0;
33094 
33095     if(!acdDoValid)
33096 	return;
33097 
33098     if(acdEdam)
33099     {
33100         relstr = acdAttrValue(thys, "relations");
33101         tokenhandle = ajStrTokenNewC(relstr, "|");
33102         while(ajStrTokenNextParse(tokenhandle, &relation))
33103         {
33104             namespace = acdEdamTest(relation);
33105             if(!namespace)
33106                 acdErrorValid("Qualifier relation '%S' not found",
33107                               relation);
33108             else if(ajStrMatchC(namespace, "data"))
33109                 ireldata++;
33110             else if(ajStrMatchC(namespace, "format"))
33111                 ireldata++;
33112             else if(ajStrMatchC(namespace, "identifier"))
33113                 ireldata++;
33114             else
33115                 acdErrorValid("Qualifier has relation '%S' with namespace '%S'",
33116                               relation, namespace);
33117         }
33118 
33119         ajStrDel(&relation);
33120         ajStrTokenDel(&tokenhandle);
33121     }
33122 
33123     if(ajListGetLength(acdSecList))
33124     {
33125 	acdValidSectionFull(&secname);
33126     }
33127     else
33128     {
33129 	acdErrorValid("No section defined for qualifier '%S'", thys->Name);
33130 	ajStrAssignC(&secname, "<none>");
33131     }
33132 
33133     if (acdType[thys->Type].Section)
33134     {
33135 	if (!acdValidSectionMatch(acdType[thys->Type].Section->Name))
33136 	    acdErrorValid("Qualifier '%S' type '%s' not in section '%s'",
33137 			  thys->Name, acdType[thys->Type].Name,
33138 			  acdType[thys->Type].Section->Name);
33139     }
33140 
33141     if(ajCharMatchC(acdType[thys->Type].Name, "toggle"))
33142 	isToggle = ajTrue;
33143 
33144     /* parameter, standard, additional only once, with 'Y' */
33145 
33146     itype = 0;
33147 
33148     tmpstr = acdAttrValue(thys, "parameter");
33149 
33150     if(ajStrGetLen(tmpstr))
33151     {
33152 	itype++;
33153 
33154 	if(acdVarTestValid(tmpstr, &toggle))
33155 	{
33156 	    isParameter = ajTrue;
33157 	    acdErrorValid("Calculated parameter value for '%S'",
33158 			  thys->Name);
33159 	}
33160 	else
33161 	{
33162 	    if(ajStrToBool(tmpstr,&isparam))
33163 	    {
33164 		if(isparam)
33165 		{
33166 		    isParameter = ajTrue;
33167 		}
33168 		else
33169 		{
33170 		    acdErrorValid("Parameter defined as false '%S'", tmpstr);
33171 		    itype--;
33172 		}
33173 	    }
33174 	}
33175     }
33176 
33177     tmpstr = acdAttrValue(thys, "standard");
33178 
33179     if(ajStrGetLen(tmpstr))
33180     {
33181 	itype++;
33182 
33183 	if(acdVarTestValid(tmpstr, &toggle))
33184 	{
33185 	    isStandard = ajTrue;
33186 
33187 	    if (!toggle)
33188 		acdWarn("Calculated standard value for '%S'",
33189 			thys->Name);
33190 
33191 	    if (acdValidSectionMatch("advanced"))
33192 		acdWarn("Calculated standard value for qualifier '%S' "
33193 			"in section '%S'",
33194 			thys->Name, secname);
33195 	}
33196 	else
33197 	{
33198 	    if(ajStrToBool(tmpstr,&boolval))
33199 	    {
33200 		if(boolval)
33201 		{
33202 		    isStandard = ajTrue;
33203 		}
33204 		else
33205 		{
33206 		    acdErrorValid("Standard defined as false '%S'",
33207 				  tmpstr);
33208 		    itype--;
33209 		}
33210 	    }
33211 	}
33212     }
33213 
33214     tmpstr = acdAttrValue(thys, "additional");
33215 
33216     if(ajStrGetLen(tmpstr))
33217     {
33218 	itype++;
33219 	if(acdVarTestValid(tmpstr, &toggle))
33220 	{
33221 	    isAdditional = ajTrue;
33222 
33223 	    if (!toggle)
33224 		acdWarn("Calculated additional value for '%S'",
33225 			thys->Name);
33226 	    if (acdValidSectionMatch("advanced"))
33227 		acdWarn("Calculated additional value for qualifier '%S' "
33228 			"in section '%S'",
33229 			thys->Name, secname);
33230 	}
33231 	else
33232 	{
33233 	    if(ajStrToBool(tmpstr,&boolval))
33234 	    {
33235 		if(boolval)
33236 		    isAdditional = ajTrue;
33237 		else
33238 		{
33239 		    acdErrorValid("Additional defined as false '%S'",
33240 				  tmpstr);
33241 		    itype--;
33242 		}
33243 	    }
33244 	}
33245     }
33246 
33247     if(itype > 1)
33248 	acdErrorValid("Multiple definition of parameter/standard/additional");
33249 
33250     if (isParameter)
33251     {
33252 		    if (acdValidSectionMatch("advanced") ||
33253 			acdValidSectionMatch("additional"))
33254 			acdErrorValid("Parameter '%S' in section '%S'",
33255 				      thys->Name, secname);
33256     }
33257 
33258     else if (isStandard)
33259     {
33260 	if (acdValidSectionMatch("advanced") ||
33261 	    acdValidSectionMatch("additional"))
33262 	    acdWarn("Standard qualifier '%S' "
33263 		    "in section '%S'",
33264 		    thys->Name, secname);
33265     }
33266 
33267     else if (isAdditional)
33268     {
33269 	if (acdValidSectionMatch("advanced") ||
33270 	    (!isToggle && acdValidSectionMatch("required")))
33271 	    acdWarn("Additional qualifier '%S' "
33272 		    "in section '%S'",
33273 		    thys->Name, secname);
33274     }
33275 
33276     else				/* must be advanced */
33277     {
33278 	if (!isToggle)
33279 	{
33280 	    if (acdValidSectionMatch("additional") ||
33281 		acdValidSectionMatch("required"))
33282 		acdWarn("Advanced qualifier '%S' "
33283 			"in section '%S'",
33284 			thys->Name, secname);
33285 	}
33286     }
33287 
33288     tmpinfo = acdAttrValue(thys, "information");
33289     tmpprompt = acdAttrValue(thys, "prompt");
33290     tmphelp = acdAttrValue(thys, "help");
33291 
33292     if(acdType[thys->Type].Prompt)
33293     {
33294 	tmpstandard = (*acdType[thys->Type].Prompt)(thys);
33295 
33296 	if(ajStrGetLen(tmpstandard) &&
33297 	   acdKnowntypeDesc(thys))
33298 	{
33299 	    if(ajStrGetLen(tmpinfo))
33300 	    {
33301 		if(!ajStrMatchS(tmpinfo, tmpstandard))
33302 		    acdWarn("Information string for '%S' '%S' not standard '%S'",
33303 			    thys->Name, tmpinfo, tmpstandard);
33304 	    }
33305 	    else
33306 	    {
33307 		    acdWarn("Missing standard information '%S' expected '%S'",
33308 			    thys->Name, tmpstandard);
33309 	    }
33310 	}
33311 /*
33312 	else if(ajStrGetLen(tmpinfo))
33313 	{
33314 		acdWarn("Standard prompt for '%S' is '%S' information '%S'",
33315 			thys->Name, tmpstandard, tmpinfo);
33316 
33317 	}
33318 */
33319     }
33320 
33321     if(ajStrGetLen(tmpprompt) && !ajStrGetLen(tmpinfo))
33322 	acdErrorValid("Prompt specified but no information");
33323 
33324     if(ajStrGetLen(tmpinfo) && !isupper((int)ajStrGetCharFirst(tmpinfo)))
33325     {
33326 	if (islower((int)ajStrGetCharFirst(tmpinfo)))
33327 	    acdWarn("Information string for '%S' starts in lower case",
33328 		thys->Name);
33329 	else
33330 	    acdWarn("Information string for '%S' starts non-alphabetic",
33331 		    thys->Name);
33332     }
33333 
33334     if(ajStrGetLen(tmpprompt) && !isupper((int)ajStrGetCharFirst(tmpprompt)))
33335     {
33336 	if (islower((int)ajStrGetCharFirst(tmpprompt)))
33337 	    acdWarn("Prompt string for '%S' starts in lower case",
33338 		thys->Name);
33339 	else
33340 	    acdWarn("Prompt string for '%S' starts non-alphabetic",
33341 		    thys->Name);
33342     }
33343 
33344     if(ajStrGetLen(tmphelp) && !isupper((int)ajStrGetCharFirst(tmphelp)))
33345     {
33346 	if (islower((int)ajStrGetCharFirst(tmphelp)))
33347 	    acdWarn("Help string for '%S' starts in lower case",
33348 		thys->Name);
33349 	else
33350 	    acdWarn("Help string for '%S' starts non-alphabetic",
33351 		    thys->Name);
33352     }
33353 
33354     /*
33355      ** if known, must have a standard info string
33356      ** but we can make allowances for possibly confusing 2nd occurrence
33357      ** and beyond
33358      ** and also allow for those with a default value that are usually not
33359      ** prompted for
33360      */
33361 
33362     if(acdType[thys->Type].Stdprompt &&
33363        (ajStrGetLen(tmpinfo) || ajStrGetLen(tmpprompt)) &&
33364        !acdAttrTestDefined(thys, "default") &&
33365        !acdAttrTestDefined(thys, "knowntype") &&
33366        *acdType[thys->Type].UseClassCount == 1)
33367     {
33368 	acdWarn("Unexpected information value for type '%s'",
33369 		acdType[thys->Type].Name);
33370     }
33371 
33372     /* else it must have an info attribute or a knowntype */
33373 
33374     if(!acdType[thys->Type].Stdprompt &&
33375        !ajStrGetLen(tmpinfo) &&
33376        !ajStrGetLen(tmpprompt) &&
33377        !acdAttrTestDefined(thys, "knowntype"))
33378     {
33379 	acdErrorValid("Missing information value for type '%s'",
33380 		      acdType[thys->Type].Name);
33381     }
33382 
33383     /* if known, must have a standard type */
33384 
33385     /* expected types should have a known name */
33386     /* sequence seqset seqall see below - need to do seqout, infile, outfile */
33387 
33388     if(ajCharMatchC(acdType[thys->Type].Name, "sequence") ||
33389        ajCharMatchC(acdType[thys->Type].Name, "seqall") ||
33390        ajCharMatchC(acdType[thys->Type].Name, "seqsetall") ||
33391        ajCharMatchC(acdType[thys->Type].Name, "seqset"))
33392     {
33393 	if(!isparam &&
33394 	   !acdAttrTestDefined(thys, "default") &&
33395 	   !acdAttrTestDefined(thys, "nullok"))
33396 	{
33397 	    if(*acdType[thys->Type].UseClassCount == 1)
33398 		acdErrorValid("First sequence input '%S' is not a parameter",
33399 			      thys->Token);
33400 	    else
33401 		acdWarn("Subsequent sequence input '%S' is not a parameter",
33402 			thys->Token);
33403 	}
33404 
33405 	qualCountIn++;
33406 	qualCountSeq++;
33407 
33408 	if(qualCountSeq == 1)
33409 	    ajStrAssignS(&qualSeqFirst, thys->Token);
33410 	ajFmtPrintS(&qualName, "%csequence",
33411 		    (char) ('a' - 1 + qualCountSeq));
33412 
33413 	if(!(ajStrSuffixC(thys->Token, "sequence") ||
33414 	     (ajCharMatchC(acdType[thys->Type].Name, "seqall") &&
33415 	      ajStrSuffixC(thys->Token, "seqall")) ||
33416 	     (ajCharMatchC(acdType[thys->Type].Name, "seqset") &&
33417 	      ajStrSuffixC(thys->Token, "sequences")) ||
33418 	     (ajCharMatchC(acdType[thys->Type].Name, "seqsetall") &&
33419 	      ajStrSuffixC(thys->Token, "sequences")) ))
33420 	{
33421 	    if(ajCharMatchC(acdType[thys->Type].Name, "seqall"))
33422 		acdWarn("Sequence qualifier '%S' is not 'sequence' "
33423 			"or '*sequence' or 'seqall' "
33424 			"(should be '%Ssequence')",
33425 			thys->Token, thys->Token);
33426 	    else if(ajCharMatchC(acdType[thys->Type].Name, "seqset"))
33427 		acdWarn("Sequence qualifier '%S' is not 'sequence' "
33428 			"or '*sequence' or 'sequences' "
33429 			"(should be '%Ssequence')",
33430 			thys->Token, thys->Token);
33431 	    else if(ajCharMatchC(acdType[thys->Type].Name, "seqsetall"))
33432 		acdWarn("Sequence qualifier '%S' is not 'sequence' "
33433 			"or '*sequence' or 'sequences' "
33434 			"(should be '%Ssequence')",
33435 			thys->Token, thys->Token);
33436 	    else
33437 		acdWarn("Sequence qualifier '%S' is not 'sequence' "
33438 			"or '*sequence' "
33439 			"(should be '%Ssequence')",
33440 			thys->Token, thys->Token);
33441 	}
33442 	else
33443 	{
33444 	    if((qualCountSeq > 1) ||
33445 	       !(ajStrMatchC(thys->Token, "sequence") ||
33446 		 (ajCharMatchC(acdType[thys->Type].Name, "seqall") &&
33447 		  ajStrSuffixC(thys->Token, "seqall")) ||
33448 		 (ajCharMatchC(acdType[thys->Type].Name, "seqsetall") &&
33449 		  ajStrSuffixC(thys->Token, "sequences")) ||
33450 		 (ajCharMatchC(acdType[thys->Type].Name, "seqset") &&
33451 		  ajStrSuffixC(thys->Token, "sequences")) ))
33452 		seqMulti = ajTrue;
33453 
33454 	    if(seqMulti)
33455             {
33456                 if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) &&
33457 		    ajStrSuffixC(thys->Token, "sequence"))
33458 		{
33459 		    if(!ajStrMatchS(thys->Token, qualName))
33460 			acdWarn("Expected sequence qualifier is '%S' "
33461 				"found '%S'",
33462 				qualName, thys->Token);
33463 		}
33464             }
33465 	}
33466 
33467 	tmpstr = acdAttrValue(thys, "type");
33468 	if(!ajStrGetLen(tmpstr))
33469 	    acdErrorValid("No type specified for input sequence");
33470 	else
33471 	    if(qualCountSeq == 1)
33472 		ajStrAssignS(&seqTypeIn, tmpstr);
33473 
33474 	if(ajCharMatchC(acdType[thys->Type].Name, "seqset") ||
33475 	   ajCharMatchC(acdType[thys->Type].Name, "seqsetall"))
33476 	{
33477 	    if(!acdAttrTestDefined(thys, "aligned"))
33478 	       acdErrorValid("Sequence set '%S' has no 'aligned' attribute",
33479 			     thys->Token);
33480 	}
33481     }
33482 
33483     if(ajCharMatchC(acdType[thys->Type].Name, "feature"))
33484     {
33485 	if(!isparam &&
33486 	   !acdAttrTestDefined(thys, "default") &&
33487 	   !acdAttrTestDefined(thys, "nullok"))
33488 	{
33489 	    if(*acdType[thys->Type].UseClassCount == 1)
33490 		acdErrorValid("First feature input '%S' is not a parameter",
33491 			      thys->Token);
33492 	    else
33493 		acdWarn("Subsequent feature input '%S' is not a parameter",
33494 			thys->Token);
33495 	}
33496 
33497 	qualCountFeat++;
33498 	if(qualCountFeat == 1)
33499 	    ajStrAssignS(&qualFeatFirst, thys->Token);
33500 	ajFmtPrintS(&qualName, "%cfeature",
33501 		    (char) ('a' - 1 + qualCountFeat));
33502 
33503 	if(!(ajStrSuffixC(thys->Token, "feature")))
33504 	{
33505 	    acdWarn("Feature qualifier '%S' is not 'feature' "
33506 			"or '*feature' "
33507 			"(should be '%Sfeature')",
33508 			thys->Token, thys->Token);
33509 	}
33510 	else
33511 	{
33512 	    if((qualCountFeat > 1) ||
33513 	       !(ajStrMatchC(thys->Token, "feature")))
33514 		featMulti = ajTrue;
33515 
33516 	    if(featMulti)
33517 		if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) &&
33518 		    ajStrSuffixC(thys->Token, "feature"))
33519 		{
33520 		    if(!ajStrMatchS(thys->Token, qualName))
33521 			acdWarn("Expected feature qualifier is '%S' "
33522 				"found '%S'",
33523 				qualName, thys->Token);
33524 		}
33525 	}
33526 
33527 	/* still to do - check for type */
33528 
33529 	tmpstr = acdAttrValue(thys, "type");
33530 	if(!ajStrGetLen(tmpstr) && !ajStrGetLen(seqTypeIn))
33531 	    acdErrorValid("No type specified for input feature, "
33532 			  "and no input sequence type as a default");
33533     }
33534 
33535     /* infile - assume parameter  -infile */
33536     /* check for type */
33537 
33538     if(ajCharMatchC(acdType[thys->Type].Name, "infile") ||
33539        ajCharMatchC(acdType[thys->Type].Name, "filelist") ||
33540        ajCharMatchC(acdType[thys->Type].Name, "directory") ||
33541        ajCharMatchC(acdType[thys->Type].Name, "dirlist"))
33542     {
33543 	if(!isparam &&
33544 	   !acdAttrTestDefined(thys, "default") &&
33545 	   !acdAttrTestDefined(thys, "nullok"))
33546 	{
33547 	    if(ajCharMatchC(acdType[thys->Type].Name, "directory") ||
33548 	       ajCharMatchC(acdType[thys->Type].Name, "dirlist"))
33549 	    {
33550 		if(*acdType[thys->Type].UseClassCount == 1)
33551 		    acdErrorValid("First input directory '%S' is not a "
33552 				  "parameter",
33553 				  thys->Token);
33554 		else
33555 		    acdWarn("Subsequent input directory '%S' is not a "
33556 			    "parameter",
33557 			    thys->Token);
33558 	    }
33559 	    else
33560 	    {
33561 		if(*acdType[thys->Type].UseClassCount == 1)
33562 		    acdErrorValid("First input file '%S' is not a parameter",
33563 				  thys->Token);
33564 		else
33565 		    acdWarn("Subsequent input file '%S' is not a parameter",
33566 			    thys->Token);
33567 	    }
33568 	}
33569 
33570 	qualCountIn++;
33571 	qualCountInfile++;
33572 
33573 	if(ajCharMatchC(acdType[thys->Type].Name, "infile"))
33574 	{
33575 	    if(!ajStrSuffixC(thys->Token, "file"))
33576 		acdWarn("Infile qualifier '%S' is not 'infile' or '*file' "
33577 			"(should be '%Sfile')",
33578 			thys->Token, thys->Token);
33579 	    else
33580 	    {
33581 		if((qualCountIn == 1) &&
33582 		   !ajStrMatchC(thys->Token, "infile") &&
33583 		   !ajStrSuffixC(thys->Token, "file"))
33584 		    acdWarn("First input file qualifier '%S' is not "
33585 			    "'infile' or '*file' "
33586 			    "(should be '%Sfile')",
33587 			    thys->Token, thys->Token);
33588 	    }
33589 	}
33590 	else if(ajCharMatchC(acdType[thys->Type].Name, "filelist"))
33591 	{
33592 	    if(!ajStrSuffixC(thys->Token, "files"))
33593 		acdWarn("Filelist qualifier '%S' is not '*files'",
33594 			thys->Token);
33595 	    /* no fixed qualifier name for first input filelist */
33596 	}
33597 	else if(ajCharMatchC(acdType[thys->Type].Name, "directory") ||
33598 		ajCharMatchC(acdType[thys->Type].Name, "dirlist"))
33599 	{
33600 	    if(ajStrSuffixC(thys->Token, "outdir"))
33601 		acdWarn("Directory qualifier '%S' has outdir style name "
33602 			"'*outdir'",
33603 			thys->Token);
33604 	    else if(!ajStrSuffixC(thys->Token, "dir") &&
33605 		    !ajStrSuffixC(thys->Token, "path") &&
33606 		    !ajStrSuffixC(thys->Token, "directory"))
33607 		acdWarn("Directory qualifier '%S' is not '*directory or *dir'"
33608 			" or *path' "
33609 			"(should be '%Sdir')",
33610 			thys->Token, thys->Token);
33611 	    /* no fixed qualifier name for first input directory */
33612 	}
33613 
33614 	tmpstr = acdAttrValue(thys, "knowntype");
33615 
33616 	if(!ajStrGetLen(tmpstr))
33617 	    acdWarn("No knowntype specified for input file");
33618     }
33619 
33620     /* datafile - no standard qualifier name yet */
33621     /* check for knowntype */
33622 
33623     if(ajCharMatchC(acdType[thys->Type].Name, "datafile"))
33624     {
33625 	tmpstr = acdAttrValue(thys, "knowntype");
33626 
33627 	if(!ajStrGetLen(tmpstr))
33628 	    acdWarn("No knowntype specified for data file");
33629     }
33630 
33631     /* outfile - assume parameter unless default is stdout -outfile */
33632     /* check for type */
33633 
33634     if(ajCharMatchC(acdType[thys->Type].Name, "outfile"))
33635     {
33636 	/* Skip this test - there is a good default for output files */
33637 
33638 	/*
33639 	if(!isparam &&
33640 	   !acdAttrTestDefined(thys, "default") &&
33641 	   !acdAttrTestDefined(thys, "nullok"))
33642 	{
33643 	    if(*acdType[thys->Type].UseClassCount == 1)
33644 		acdErrorValid("First output file '%S' is not a parameter",
33645 			      thys->Token);
33646 	    else
33647 		acdWarn("Subsequent output file '%S' is not a parameter",
33648 			thys->Token);
33649 	}
33650 	*/
33651 
33652 	qualCountOut++;
33653 	qualCountOutfile++;
33654 
33655 	if(ajCharMatchC(acdType[thys->Type].Name, "outfile") &&
33656 	   !ajStrSuffixC(thys->Token, "file"))
33657 	    acdWarn("Outfile qualifier '%S' is not 'outfile' or '*file' "
33658 		    "(should be '%Sfile')",
33659 		    thys->Token, thys->Token);
33660 	else
33661 	{
33662 	    if((qualCountOut == 1) &&
33663 	       !ajStrMatchC(thys->Token, "outfile"))
33664 	    {
33665 		acdWarn("First output file qualifier '%S' is not 'outfile'",
33666 			thys->Token);
33667 	    }
33668 	}
33669 
33670 	/* still to do - check for type */
33671 
33672 	tmpstr = acdAttrValue(thys, "knowntype");
33673 
33674 	if(!ajStrGetLen(tmpstr))
33675 	    acdWarn("No knowntype specified for output file");
33676     }
33677 
33678     /* outdirectory - assume parameter unless default is stdout -outfile */
33679     /* check for type */
33680 
33681     if(ajCharMatchC(acdType[thys->Type].Name, "outdir"))
33682     {
33683 	if(!isparam &&
33684 	   !acdAttrTestDefined(thys, "default") &&
33685 	   !acdAttrTestDefined(thys, "nullok"))
33686 	{
33687 	    if(*acdType[thys->Type].UseClassCount == 1)
33688 		acdErrorValid("First output directory '%S' is not a parameter",
33689 			      thys->Token);
33690 	    else
33691 		acdWarn("Subsequent output directory '%S' is not a parameter",
33692 			thys->Token);
33693 	}
33694 
33695 	qualCountOut++;
33696 	qualCountOutfile++;
33697 
33698 	if(ajCharMatchC(acdType[thys->Type].Name, "outdir") &&
33699 	   !ajStrSuffixC(thys->Token, "outdir"))
33700 	    acdWarn("Outdir qualifier '%S' is not 'outdir' or '*outdir'",
33701 		    thys->Token);
33702 	else
33703 	{
33704 	    if((qualCountOut == 1) &&
33705 	       !ajStrMatchC(thys->Token, "outdir") &&
33706 	       !ajStrSuffixC(thys->Token, "outdir"))
33707 		acdWarn("First output directory qualifier '%S' "
33708 			"is not 'outdir' or '*outdir' "
33709 			"(should be '%Sfile')",
33710 			thys->Token, thys->Token);
33711 	}
33712 
33713 	/* still to do - check for type */
33714 
33715 	tmpstr = acdAttrValue(thys, "knowntype");
33716 	if(!ajStrGetLen(tmpstr))
33717 	    acdWarn("No knowntype specified for output directory");
33718     }
33719 
33720     /* align - as for outfile? */
33721 
33722     if(ajCharMatchC(acdType[thys->Type].Name, "align"))
33723     {
33724 	if(!isparam &&
33725 	   !acdAttrTestDefined(thys, "default") &&
33726 	   !acdAttrTestDefined(thys, "nullok"))
33727 	{
33728 	    if(*acdType[thys->Type].UseClassCount == 1)
33729 		acdErrorValid("First alignment file '%S' is not a parameter",
33730 			      thys->Token);
33731 	    else
33732 		acdWarn("Subsequent alignment file '%S' is not a parameter",
33733 			thys->Token);
33734 	}
33735 
33736 	qualCountOut++;
33737 	qualCountOutfile++;
33738 
33739 	if(!ajStrSuffixC(thys->Token, "file"))
33740 	    acdWarn("Align qualifier '%S' is not 'outfile' or '*file' "
33741 		    "(should be '%Sfile')",
33742 		    thys->Token, thys->Token);
33743 	else
33744 	{
33745 	    if((qualCountOut == 1) &&
33746 	       !ajStrMatchC(thys->Token, "outfile"))
33747 		acdWarn("First alignment file qualifier '%S' is not 'outfile'",
33748 			thys->Token);
33749 	}
33750     }
33751 
33752     /* report - as for outfile? */
33753 
33754     if(ajCharMatchC(acdType[thys->Type].Name, "report"))
33755     {
33756 	if(!isparam &&
33757 	   !acdAttrTestDefined(thys, "default") &&
33758 	   !acdAttrTestDefined(thys, "nullok"))
33759 	{
33760 	    if(*acdType[thys->Type].UseClassCount == 1)
33761 		acdErrorValid("First report file '%S' is not a parameter",
33762 			      thys->Token);
33763 	    else
33764 		acdWarn("Subsequent report file '%S' is not a parameter",
33765 			thys->Token);
33766 	}
33767 
33768 	qualCountOut++;
33769 	qualCountOutfile++;
33770 	if(!ajStrSuffixC(thys->Token, "file"))
33771 	    acdWarn("Report qualifier '%S' is not 'outfile' or '*file' "
33772 		    "(should be '%Sfile')",
33773 		    thys->Token, thys->Token);
33774 	else
33775 	{
33776 	    if((qualCountOut == 1) &&
33777 	       !ajStrMatchC(thys->Token, "outfile"))
33778 		acdWarn("First report file qualifier '%S' is not 'outfile'",
33779 			thys->Token);
33780 	}
33781     }
33782 
33783     /* seqout* - assume parameter - what names? -outseq? */
33784     /* type only if there is no sequence input */
33785 
33786     if(ajCharMatchC(acdType[thys->Type].Name, "seqout") ||
33787        ajCharMatchC(acdType[thys->Type].Name, "seqoutall") ||
33788        ajCharMatchC(acdType[thys->Type].Name, "seqoutset"))
33789     {
33790 	/* skip this test - there is a good default for sequence output */
33791 
33792 	/*
33793 	if(!isparam &&
33794 	   !acdAttrTestDefined(thys, "default") &&
33795 	   !acdAttrTestDefined(thys, "nullok"))
33796 	{
33797 	    if(*acdType[thys->Type].UseClassCount == 1)
33798 		acdErrorValid("First sequence output '%S' is not a parameter",
33799 			      thys->Token);
33800 	    else
33801 		acdWarn("Subsequent sequence output '%S' is not a parameter",
33802 			thys->Token);
33803 	}
33804 	*/
33805 
33806 	qualCountOut++;
33807 	qualCountSeqout++;
33808 
33809 	if(qualCountSeqout == 1)
33810 	    ajStrAssignS(&qualSeqoutFirst, thys->Token);
33811 	ajFmtPrintS(&qualName, "%coutseq",
33812 		    (char) ('a' - 1 + qualCountSeqout));
33813 
33814 	if(!ajStrSuffixC(thys->Token, "outseq") &&
33815 	   !ajStrSuffixC(thys->Token, "outfile"))
33816 	    acdWarn("Sequence output qualifier '%S' is not 'outseq' "
33817 		    "or '*outseq' or '*outfile'"
33818 		    "(should be '%Soutseq')",
33819 		    thys->Token, thys->Token);
33820 
33821 	else
33822 	{
33823 	    if((qualCountOut > 1) ||
33824 	       (!ajStrMatchC(thys->Token, "outseq") &&
33825 		!ajStrMatchC(thys->Token, "outfile")))
33826 		seqoutMulti = ajTrue;
33827 	    if(seqoutMulti)
33828 	    {
33829 		if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) &&
33830 		    ajStrSuffixC(thys->Token, "outseq"))
33831 		{
33832 		    if(!ajStrMatchS(thys->Token, qualName))
33833 			acdWarn("Expected sequence output qualifier is '%S' "
33834 				"found '%S'",
33835 				qualName, thys->Token);
33836 		}
33837 	    }
33838 	}
33839 
33840 	/* still to do - check for type */
33841 
33842 	tmpstr = acdAttrValue(thys, "type");
33843 
33844 	if(!ajStrGetLen(tmpstr) && !ajStrGetLen(seqTypeIn))
33845 	    acdErrorValid("No type specified for output sequence, "
33846 			  "and no input sequence type as a default");
33847     }
33848 
33849     /* featout - assume parameter - what names? -outfeat? */
33850     /* type only if there is no sequence input */
33851 
33852     if(ajCharMatchC(acdType[thys->Type].Name, "featout"))
33853     {
33854 	if(!isparam &&
33855 	   !acdAttrTestDefined(thys, "default") &&
33856 	   !acdAttrTestDefined(thys, "nullok"))
33857 	{
33858 	    if(*acdType[thys->Type].UseClassCount == 1)
33859 		acdErrorValid("First feature output '%S' is not a parameter",
33860 			      thys->Token);
33861 	    else
33862 		acdWarn("Subsequent feature output '%S' is not a parameter",
33863 			thys->Token);
33864 	}
33865 
33866 	qualCountFeatout++;
33867 
33868 	if(qualCountFeatout == 1)
33869 	    ajStrAssignS(&qualFeatoutFirst, thys->Token);
33870 	ajFmtPrintS(&qualName, "%coutfeat",
33871 		    (char) ('a' - 1 + qualCountFeatout));
33872 
33873 	if(!ajStrMatchC(thys->Token, "outfeat") &&
33874 	   !ajStrSuffixC(thys->Token, "outfeat"))
33875 	    acdWarn("Feature output qualifier '%S' is not 'outfeat' "
33876 		    "or '*outfeat'"
33877 		    "(should be '%Soutfeat')",
33878 		    thys->Token, thys->Token);
33879 
33880 	else
33881 	{
33882 	    if((qualCountFeatout > 1) ||
33883 	       (!ajStrMatchC(thys->Token, "outfeat")))
33884 		featoutMulti = ajTrue;
33885 
33886 	    if(featoutMulti)
33887 	    {
33888 		if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) &&
33889 		    ajStrSuffixC(thys->Token, "outfeat"))
33890 		{
33891 		    if(!ajStrMatchS(thys->Token, qualName))
33892 			acdWarn("Expected feature output qualifier is '%S' "
33893 				"found '%S'",
33894 				qualName, thys->Token);
33895 		}
33896 	    }
33897 	}
33898 
33899 	/* still to do - check for type */
33900 
33901 	tmpstr = acdAttrValue(thys, "type");
33902 
33903 	if(!ajStrGetLen(tmpstr) && !ajStrGetLen(seqTypeIn))
33904 	    acdErrorValid("No type specified for output feature, "
33905 			  "and no input sequence type as a default");
33906     }
33907 
33908     /* string - we don't ask much, but we do prefer strings to have a
33909        known type that does not suggest some other datatype can be
33910        used */
33911 
33912     if(ajCharMatchC(acdType[thys->Type].Name, "string"))
33913     {
33914 	tmpstr = acdAttrValue(thys, "knowntype");
33915 
33916 	if(!ajStrGetLen(tmpstr))
33917 	{
33918 	    tmpstr = acdAttrValue(thys, "pattern");
33919 
33920 	    if (!ajStrGetLen(tmpstr))
33921 		acdWarn("No knowntype specified for string");
33922 	    else
33923 		acdWarn("Pattern but no knowntype specified for string");
33924 	}
33925     }
33926 
33927     acdValidKnowntype(thys);
33928 
33929     return;
33930 }
33931 
33932 
33933 
33934 
33935 /* @funcstatic acdValidKnowntype **********************************************
33936 **
33937 ** Validation for Known type
33938 **
33939 ** @param [r] thys [const AcdPAcd] Current ACD object
33940 ** @return [void]
33941 **
33942 ** @release 2.9.0
33943 ** @@
33944 ******************************************************************************/
33945 
acdValidKnowntype(const AcdPAcd thys)33946 static void acdValidKnowntype(const AcdPAcd thys)
33947 {
33948     const AjPStr typestr         = NULL;
33949     const AjPStr acdKnownType    = NULL;
33950     static AjPStr defType = NULL;
33951     AjBool typeok = ajFalse;
33952 
33953     if(!acdDoValid)
33954 	return;
33955 
33956     typestr = acdAttrValue(thys, "knowntype");
33957 
33958     if (!ajStrGetLen(typestr))
33959 	return;
33960 
33961 
33962     if (!defType)
33963 	ajFmtPrintS(&defType, "%S output", acdProgram);
33964 
33965     acdKnownType = ajTableFetchS(acdKnowntypeTypeTable, typestr);
33966     if (!acdKnownType)
33967     {
33968 	if(ajStrFindAnyK(typestr, '_') >= 0)
33969 	{
33970 		acdWarn("Knowntype '%S' replace underscore(s) with spaces",
33971 			typestr);
33972 	}
33973 	else
33974 	{
33975 	    if (!ajStrMatchS(typestr, defType))
33976 		acdWarn("Knowntype '%S' not defined in knowntypes.standard",
33977 			typestr);
33978 	}
33979 
33980 	return;
33981     }
33982 
33983     if (ajStrMatchC(acdKnownType, "file"))
33984     {
33985 	if (!ajCharMatchC(acdType[thys->Type].Name, "infile") &&
33986 	    !ajCharMatchC(acdType[thys->Type].Name, "datafile") &&
33987 	    !ajCharMatchC(acdType[thys->Type].Name, "directory") &&
33988 	    !ajCharMatchC(acdType[thys->Type].Name, "dirlist") &&
33989 	    !ajCharMatchC(acdType[thys->Type].Name, "outfile") &&
33990 	    !ajCharMatchC(acdType[thys->Type].Name, "outdir") &&
33991 	    !ajCharMatchC(acdType[thys->Type].Name, "filelist"))
33992 	{
33993 	    acdWarn("Knowntype '%S' defined for type '%S', used for '%s'",
33994 		    typestr, acdKnownType, acdType[thys->Type].Name);
33995 	}
33996     }
33997     else if (ajStrMatchC(acdKnownType, "sequence"))
33998     {
33999 	if (!ajCharMatchC(acdType[thys->Type].Name, "sequence") &&
34000 	    !ajCharMatchC(acdType[thys->Type].Name, "seqall") &&
34001 	    !ajCharMatchC(acdType[thys->Type].Name, "seqset") &&
34002 	    !ajCharMatchC(acdType[thys->Type].Name, "seqsetall") &&
34003 	    !ajCharMatchC(acdType[thys->Type].Name, "seqout") &&
34004 	    !ajCharMatchC(acdType[thys->Type].Name, "seqoutall") &&
34005 	    !ajCharMatchC(acdType[thys->Type].Name, "seqoutset") &&
34006 	    !ajCharMatchC(acdType[thys->Type].Name, "seqoutsetall"))
34007 	{
34008 	    acdWarn("Knowntype '%S' defined for type '%S', used for '%s'",
34009 		    typestr, acdKnownType, acdType[thys->Type].Name);
34010 	}
34011     }
34012     else if (ajStrMatchC(acdKnownType, "codon") ||
34013 	     ajStrMatchC(acdKnownType, "cpdb") ||
34014 	     ajStrMatchC(acdKnownType, "matrix") ||
34015 	     ajStrMatchC(acdKnownType, "discretestates") ||
34016 	     ajStrMatchC(acdKnownType, "distances") ||
34017 	     ajStrMatchC(acdKnownType, "frequencies") ||
34018 	     ajStrMatchC(acdKnownType, "properties") ||
34019 	     ajStrMatchC(acdKnownType, "scop") ||
34020 	     ajStrMatchC(acdKnownType, "tree"))
34021     {
34022 	typeok = ajFalse;
34023 	if (ajStrMatchC(acdKnownType, "codon"))
34024 	    if(ajCharMatchC(acdType[thys->Type].Name, "codon") ||
34025 	       ajCharMatchC(acdType[thys->Type].Name, "outcodon"))
34026 	       typeok = ajTrue;
34027 
34028 	if (ajStrMatchC(acdKnownType, "cpdb"))
34029 	    if(ajCharMatchC(acdType[thys->Type].Name, "cpdb") ||
34030 	       ajCharMatchC(acdType[thys->Type].Name, "outcpdb"))
34031 	       typeok = ajTrue;
34032 
34033 	if (ajStrMatchC(acdKnownType, "discretestates"))
34034 	    if(ajCharMatchC(acdType[thys->Type].Name, "discretestates") ||
34035 	       ajCharMatchC(acdType[thys->Type].Name, "outdiscrete"))
34036 	       typeok = ajTrue;
34037 
34038 	if (ajStrMatchC(acdKnownType, "distances"))
34039 	    if(ajCharMatchC(acdType[thys->Type].Name, "distances") ||
34040 	       ajCharMatchC(acdType[thys->Type].Name, "outdistances"))
34041 	       typeok = ajTrue;
34042 
34043 	if (ajStrMatchC(acdKnownType, "frequencies"))
34044 	    if(ajCharMatchC(acdType[thys->Type].Name, "frequencies") ||
34045 	       ajCharMatchC(acdType[thys->Type].Name, "outfreq"))
34046 	       typeok = ajTrue;
34047 
34048 	if (ajStrMatchC(acdKnownType, "obo"))
34049 	    if(ajCharMatchC(acdType[thys->Type].Name, "obo") ||
34050 	       ajCharMatchC(acdType[thys->Type].Name, "outobo"))
34051 	       typeok = ajTrue;
34052 
34053 	if (ajStrMatchC(acdKnownType, "properties"))
34054 	    if(ajCharMatchC(acdType[thys->Type].Name, "properties") ||
34055 	       ajCharMatchC(acdType[thys->Type].Name, "outproperties"))
34056 	       typeok = ajTrue;
34057 
34058 	if (ajStrMatchC(acdKnownType, "resource"))
34059 	    if(ajCharMatchC(acdType[thys->Type].Name, "resource") ||
34060 	       ajCharMatchC(acdType[thys->Type].Name, "outresource"))
34061 	       typeok = ajTrue;
34062 
34063 	if (ajStrMatchC(acdKnownType, "scop"))
34064 	    if(ajCharMatchC(acdType[thys->Type].Name, "scop") ||
34065 	       ajCharMatchC(acdType[thys->Type].Name, "outscop"))
34066 	       typeok = ajTrue;
34067 
34068 	if (ajStrMatchC(acdKnownType, "tree"))
34069 	    if(ajCharMatchC(acdType[thys->Type].Name, "tree") ||
34070 	       ajCharMatchC(acdType[thys->Type].Name, "outtree"))
34071 	       typeok = ajTrue;
34072 
34073 	if (ajStrMatchC(acdKnownType, "matrix"))
34074 	    if(ajCharMatchC(acdType[thys->Type].Name, "matrix") ||
34075 	       ajCharMatchC(acdType[thys->Type].Name, "matrixf") ||
34076 	       ajCharMatchC(acdType[thys->Type].Name, "outmatrix") ||
34077 	       ajCharMatchC(acdType[thys->Type].Name, "outmatrixf"))
34078 	       typeok = ajTrue;
34079 
34080 	if (!ajCharMatchC(acdType[thys->Type].Name, "infile") &&
34081 	    !ajCharMatchC(acdType[thys->Type].Name, "datafile") &&
34082 	    !ajCharMatchC(acdType[thys->Type].Name, "directory") &&
34083 	    !ajCharMatchC(acdType[thys->Type].Name, "dirlist") &&
34084 	    !ajCharMatchC(acdType[thys->Type].Name, "outfile") &&
34085 	    !ajCharMatchC(acdType[thys->Type].Name, "outdir") &&
34086 	    !ajCharMatchC(acdType[thys->Type].Name, "filelist"))
34087 	{
34088 	    if(!typeok)
34089 		acdWarn("Knowntype '%S' defined for type '%S', used for '%s'",
34090 			typestr, acdKnownType, acdType[thys->Type].Name);
34091 	}
34092     }
34093     else if (!ajStrMatchC(acdKnownType, acdType[thys->Type].Name))
34094     {
34095 	acdWarn("Knowntype '%S' defined for type '%S', used for '%s'",
34096 		typestr, acdKnownType, acdType[thys->Type].Name);
34097     }
34098 
34099     return;
34100 }
34101 
34102 
34103 
34104 
34105 /* @funcstatic acdKnowntypeDesc ***********************************************
34106 **
34107 ** Return description of known type
34108 **
34109 ** @param [r] thys [const AcdPAcd] Acd object
34110 ** @return [const AjPStr] Known type description or NULL if not defined.
34111 **
34112 ** @release 4.0.0
34113 ** @@
34114 ******************************************************************************/
34115 
acdKnowntypeDesc(const AcdPAcd thys)34116 static const AjPStr acdKnowntypeDesc(const AcdPAcd thys)
34117 {
34118     const AjPStr knowntype = NULL;
34119     const AjPStr knowndesc;
34120 
34121     knowntype = acdAttrValue(thys, "knowntype");
34122 
34123     if(!ajStrGetLen(knowntype))
34124         return NULL;
34125 
34126     knowndesc = ajTableFetchS(acdKnowntypeDescTable, knowntype);
34127 
34128     return knowndesc;
34129 }
34130 
34131 
34132 
34133 
34134 /* @funcstatic acdReadKnowntype ***********************************************
34135 **
34136 ** Read standard file of ACD sections and store in new AjPTable objects
34137 **
34138 ** @param [wN] desctable [AjPTable*] String table of section names and types
34139 ** @param [wN] typetable [AjPTable*] String table of section names and
34140 **                                 descriptions
34141 ** @return [void]
34142 **
34143 ** @release 4.0.0
34144 ** @@
34145 ******************************************************************************/
34146 
acdReadKnowntype(AjPTable * desctable,AjPTable * typetable)34147 static void acdReadKnowntype(AjPTable* desctable, AjPTable* typetable)
34148 {
34149     AjPFile knownFile    = NULL;
34150     AjPStr knownFName    = NULL;
34151     AjPStr knownRoot     = NULL;
34152     AjPStr knownRootInst = NULL;
34153     AjPStr knownPack     = NULL;
34154     AjPStr knownLine     = NULL;
34155     AjBool ok            = ajFalse;
34156     AjPStrTok handle     = NULL;
34157     AjPStr knownName     = NULL;
34158     AjPStr knownName2     = NULL;
34159     AjPStr knownType     = NULL;
34160     AjPStr knownDesc     = NULL;
34161     AjPStr knownEdam     = NULL;
34162     AjPStr knownRest     = NULL;
34163     ajint iline = 0;
34164 
34165     ajStrAssignS(&knownPack, ajNamValuePackage());
34166     ajStrAssignS(&knownRootInst, ajNamValueInstalldir());
34167     ajDirnameFix(&knownRootInst);
34168 
34169     *desctable = ajTablestrNewCase(2048);
34170     *typetable = ajTablestrNewCase(2048);
34171 
34172     if(ajNamGetValueC("acdroot", &knownRoot))
34173     {
34174 	ajDirnameFix(&knownRoot);
34175 	ajFmtPrintS(&knownFName, "%Sknowntypes.standard", knownRoot);
34176 	knownFile = ajFileNewInNameS(knownFName);
34177 	acdLog("Knowntypes file in acdroot: '%S'\n", knownFName);
34178     }
34179     else
34180     {
34181 	ajFmtPrintS(&knownFName, "%Sshare/%S/acd/knowntypes.standard",
34182 		    knownRootInst, knownPack);
34183 	acdLog("Knowntypes file installed: '%S'\n", knownFName);
34184 	knownFile = ajFileNewInNameS(knownFName);
34185 	if(!knownFile)
34186 	{
34187 	    acdLog("Knowntypes file '%S' not opened\n", knownFName);
34188 	    ajStrAssignS(&knownRoot, ajNamValueRootdir());
34189 	    ajDirnameFix(&knownRoot);
34190 	    ajFmtPrintS(&knownFName, "%Sacd/knowntypes.standard", knownRoot);
34191 	    acdLog("Knowntypes file from source dir: '%S'\n", knownFName);
34192 	    knownFile = ajFileNewInNameS(knownFName);
34193 	}
34194     }
34195 
34196     if(!knownFile)			/* test acdc-knownmissing */
34197 	ajDie("Knowntypes file %S not found", knownFName);
34198     else
34199 	acdLog("Knowntypes file %F used\n", knownFile);
34200 
34201     while(knownFile && ajReadlineTrim(knownFile, &knownLine))
34202     {
34203 	iline++;
34204 
34205 	if(ajStrCutComments(&knownLine))
34206 	{
34207             handle = ajStrTokenNewC(knownLine, "|");
34208 
34209             ok = ajStrTokenNextParse(handle, &knownName);
34210 
34211 	    if(ok)
34212 	      ok = ajStrTokenNextParse(handle, &knownType);
34213 	    if(ok)
34214 	      ok = ajStrTokenNextParse(handle, &knownEdam);
34215 	    if(ok)
34216 	      ajStrTokenRestParse(handle, &knownDesc);
34217 
34218             ajStrTokenDel(&handle);
34219 
34220 	    if(ok)
34221 	    {
34222                 ajStrRemoveWhiteExcess(&knownName);
34223 		ajStrExchangeKK(&knownName, '_', ' ');
34224                 ajStrRemoveWhiteExcess(&knownType);
34225 		if(ajStrMatchCaseC(knownType, "infile") ||
34226 		   ajStrMatchCaseC(knownType, "filelist") ||
34227 		   ajStrMatchCaseC(knownType, "datafile") ||
34228 		   ajStrMatchCaseC(knownType, "outfile"))
34229 		{
34230 		    ajWarn("Knowntype '%S' in file %S line %d - use 'file'",
34231 			   knownType, knownFName, iline);
34232 		}
34233 		if(ajTablePut(*typetable, knownName, knownType))
34234 		    ajWarn("Duplicate knowntype name '%S' in file %S line %d",
34235 			   knownName, knownFName, iline);
34236 		ajStrAssignS(&knownName2, knownName);
34237                 ajStrRemoveWhiteExcess(&knownEdam);
34238                 ajStrQuoteStrip(&knownEdam);
34239                 if(ajStrPrefixC(knownEdam, "EDAM_data: "))
34240 		{
34241                     ajStrCutStart(&knownEdam, 11);
34242 		}
34243                 else if(ajStrPrefixC(knownEdam, "EDAM_data:"))
34244 		{
34245                     ajStrCutStart(&knownEdam, 14);
34246 		}
34247                 else if(ajStrGetLen(knownEdam))
34248 		    ajWarn("Knowntype '%S' in file %S line %d - EDAM badly formatted '%S'",
34249 			   knownType, knownFName, iline, knownEdam);
34250                 ajStrRemoveWhiteExcess(&knownDesc);
34251 		ajTablePut(*desctable, knownName2, knownDesc);
34252 
34253 /*                ajUser("name '%S' type '%S' desc '%S' edam '%S'",
34254                   knownName, knownType, knownDesc, knownEdam);*/
34255 	        knownName = NULL;
34256 	        knownName2 = NULL;
34257 		knownType = NULL;
34258 		knownDesc = NULL;
34259 	    }
34260 	    else
34261 		ajErr("Bad record in file %S:\n%S",
34262 		      knownFName, knownLine);
34263 	}
34264     }
34265 
34266     ajFileClose(&knownFile);
34267     ajStrDel(&knownFName);
34268     ajStrDel(&knownRoot);
34269     ajStrDel(&knownRootInst);
34270     ajStrDel(&knownPack);
34271     ajStrDel(&knownLine);
34272     ajStrDel(&knownName);
34273     ajStrDel(&knownType);
34274     ajStrDel(&knownEdam);
34275     ajStrDel(&knownDesc);
34276     ajStrDel(&knownRest);
34277 
34278     return;
34279 }
34280 
34281 
34282 
34283 
34284 /* @funcstatic acdValidApplGroup **********************************************
34285 **
34286 ** Validation for application groups
34287 **
34288 ** @param [r] groups [const AjPStr] Group name(s)
34289 ** @return [void]
34290 **
34291 ** @release 2.7.0
34292 ** @@
34293 ******************************************************************************/
34294 
acdValidApplGroup(const AjPStr groups)34295 static void acdValidApplGroup(const AjPStr groups)
34296 {
34297     AjPRegexp grpexp         = NULL;
34298     AjPStr tmpGroups         = NULL;
34299     AjPStr grpName           = NULL;
34300     const AjPStr grpDesc     = NULL;
34301 
34302     if(!acdDoValid)
34303 	return;
34304 
34305     acdGrpTable = acdReadGroups();
34306 
34307     ajStrAssignS(&tmpGroups, groups);
34308 
34309     /* step through each group */
34310     grpexp = ajRegCompC("([^,|]+),?");
34311 
34312     while(ajRegExec(grpexp, tmpGroups))
34313     {
34314 	ajRegSubI(grpexp, 1, &grpName);
34315 	ajStrRemoveWhiteExcess(&grpName);
34316 	grpDesc = ajTableFetchS(acdGrpTable, grpName);
34317 
34318 	if(!grpDesc)
34319 	    acdErrorValid("Unknown group '%S' for application", grpName);
34320 
34321 	ajRegPost(grpexp, &tmpGroups);
34322     }
34323 
34324     ajStrDel(&grpName);
34325     ajStrDel(&tmpGroups);
34326     ajRegFree(&grpexp);
34327 
34328     return;
34329 }
34330 
34331 
34332 
34333 
34334 /* @funcstatic acdValidApplKeywords *******************************************
34335 **
34336 ** Validation for application keywords
34337 **
34338 ** @param [r] keys [const AjPStr] Keyword(s)
34339 ** @return [void]
34340 **
34341 ** @release 4.0.0
34342 ** @@
34343 ******************************************************************************/
34344 
acdValidApplKeywords(const AjPStr keys)34345 static void acdValidApplKeywords(const AjPStr keys)
34346 {
34347     static AjPTable keyTable = NULL;
34348     AjPRegexp keyexp         = NULL;
34349     AjPStr tmpKeys           = NULL;
34350     AjPStr keyName           = NULL;
34351     const AjPStr keyDesc     = NULL;
34352 
34353     if(!acdDoValid)
34354 	return;
34355 
34356     keyTable = acdReadKeywords();
34357 
34358     ajStrAssignS(&tmpKeys, keys);
34359 
34360     /* step through each group */
34361     keyexp = ajRegCompC("([^,|]+),?");
34362 
34363     while(ajRegExec(keyexp, tmpKeys))
34364     {
34365 	ajRegSubI(keyexp, 1, &keyName);
34366 	ajStrRemoveWhiteExcess(&keyName);
34367 	keyDesc = ajTableFetchS(keyTable, keyName);
34368 
34369 	if(!keyDesc)
34370 	    acdErrorValid("Unknown keyword '%S' for application", keyName);
34371 
34372 	ajRegPost(keyexp, &tmpKeys);
34373     }
34374 
34375     ajStrDel(&keyName);
34376     ajStrDel(&tmpKeys);
34377     ajRegFree(&keyexp);
34378 
34379     return;
34380 }
34381 
34382 
34383 
34384 
34385 /* @funcstatic acdReadGroups **************************************************
34386 **
34387 ** Read standard table of application groups
34388 **
34389 ** @return [AjPTable] String table of group names and descriptions
34390 **
34391 ** @release 2.7.0
34392 ** @@
34393 ******************************************************************************/
34394 
acdReadGroups(void)34395 static AjPTable acdReadGroups(void)
34396 {
34397     AjPTable ret = ajTablestrNewCase(50);
34398 
34399     AjPFile grpFile    = NULL;
34400     AjPStr grpFName    = NULL;
34401     AjPStr grpRoot     = NULL;
34402     AjPStr grpRootInst = NULL;
34403     AjPStr grpPack     = NULL;
34404     AjPStr grpLine     = NULL;
34405     AjPRegexp grpxp    = NULL;
34406     AjPStr grpName     = NULL;
34407     AjPStr grpDesc     = NULL;
34408 
34409     ajStrAssignS(&grpPack, ajNamValuePackage());
34410     ajStrAssignS(&grpRootInst, ajNamValueInstalldir());
34411     ajDirnameFix(&grpRootInst);
34412 
34413     if(ajNamGetValueC("acdroot", &grpRoot))
34414     {
34415 	ajDirnameFix(&grpRoot);
34416 	ajFmtPrintS(&grpFName, "%Sgroups.standard", grpRoot);
34417 	grpFile = ajFileNewInNameS(grpFName);
34418 	acdLog("Group file in acdroot: '%S'\n", grpFName);
34419     }
34420     else
34421     {
34422 	ajFmtPrintS(&grpFName, "%Sshare/%S/acd/groups.standard",
34423 		    grpRootInst, grpPack);
34424 	acdLog("Group file installed: '%S'\n", grpFName);
34425 	grpFile = ajFileNewInNameS(grpFName);
34426 
34427 	if(!grpFile)
34428 	{
34429 	    acdLog("Grp file '%S' not opened\n", grpFName);
34430 	    ajStrAssignS(&grpRoot, ajNamValueRootdir());
34431 	    ajDirnameFix(&grpRoot);
34432 	    ajFmtPrintS(&grpFName, "%Sacd/groups.standard", grpRoot);
34433 	    acdLog("Grp file from source dir: '%S'\n", grpFName);
34434 	    grpFile = ajFileNewInNameS(grpFName);
34435 	}
34436     }
34437 
34438     if(!grpFile)			/* test acdc-grpmissing */
34439 	ajDie("Group file %S not found", grpFName);
34440     else
34441 	acdLog("Group file %F used\n", grpFile);
34442 
34443     grpxp = ajRegCompC("^EDAM_[a-z]+:\\d+\\s+([^ ]+) +([^ ].*)");
34444 
34445     while(grpFile && ajReadlineTrim(grpFile, &grpLine))
34446     {
34447 	if(ajStrCutComments(&grpLine))
34448 	{
34449 	    ajStrRemoveWhiteExcess(&grpLine);
34450 
34451 	    if(ajRegExec(grpxp, grpLine))
34452 	    {
34453 		ajRegSubI(grpxp, 1, &grpName);
34454 		ajRegSubI(grpxp, 2, &grpDesc);
34455 		ajStrExchangeKK(&grpName, '_', ' ');
34456 
34457 		if(ajTablePut(ret, grpName, grpDesc))
34458 		    ajWarn("Duplicate group name '%S' in file %S",
34459 			   grpName, grpFName);
34460 		grpName = NULL;
34461 		grpDesc = NULL;
34462 	    }
34463 	    else
34464 		ajErr("Bad record in file %S:\n%S",
34465 		      grpFName, grpLine);
34466 	}
34467     }
34468     ajFileClose(&grpFile);
34469 
34470     ajStrDel(&grpFName);
34471     ajStrDel(&grpRoot);
34472     ajStrDel(&grpRootInst);
34473     ajStrDel(&grpPack);
34474     ajStrDel(&grpLine);
34475     ajStrDel(&grpName);
34476     ajStrDel(&grpDesc);
34477 
34478     ajRegFree(&grpxp);
34479 
34480     return ret;
34481 }
34482 
34483 
34484 
34485 
34486 /* @funcstatic acdReadKeywords ************************************************
34487 **
34488 ** Read standard table of application keywords
34489 **
34490 ** @return [AjPTable] String table of keyword names and descriptions
34491 **
34492 ** @release 4.0.0
34493 ** @@
34494 ******************************************************************************/
34495 
acdReadKeywords(void)34496 static AjPTable acdReadKeywords(void)
34497 {
34498     AjPTable ret = ajTablestrNewCase(50);
34499 
34500     AjPFile keyFile    = NULL;
34501     AjPStr keyFName    = NULL;
34502     AjPStr keyRoot     = NULL;
34503     AjPStr keyRootInst = NULL;
34504     AjPStr keyPack     = NULL;
34505     AjPStr keyLine     = NULL;
34506     AjPRegexp keyxp    = NULL;
34507     AjPStr keyName     = NULL;
34508     AjPStr keyDesc     = NULL;
34509 
34510     if(!acdGrpTable)
34511 	acdGrpTable = acdReadGroups();
34512 
34513     ajStrAssignS(&keyPack, ajNamValuePackage());
34514     ajStrAssignS(&keyRootInst, ajNamValueInstalldir());
34515     ajDirnameFix(&keyRootInst);
34516 
34517     if(ajNamGetValueC("acdroot", &keyRoot))
34518     {
34519 	ajDirnameFix(&keyRoot);
34520 	ajFmtPrintS(&keyFName, "%Skeywords.standard", keyRoot);
34521 	keyFile = ajFileNewInNameS(keyFName);
34522 	acdLog("Keyword file in acdroot: '%S'\n", keyFName);
34523     }
34524     else
34525     {
34526 	ajFmtPrintS(&keyFName, "%Sshare/%S/acd/keywords.standard",
34527 		    keyRootInst, keyPack);
34528 	acdLog("Keyword file installed: '%S'\n", keyFName);
34529 	keyFile = ajFileNewInNameS(keyFName);
34530 
34531 	if(!keyFile)
34532 	{
34533 	    acdLog("keyword file '%S' not opened\n", keyFName);
34534 	    ajStrAssignS(&keyRoot, ajNamValueRootdir());
34535 	    ajDirnameFix(&keyRoot);
34536 	    ajFmtPrintS(&keyFName, "%Sacd/keywords.standard", keyRoot);
34537 	    acdLog("Keywords file from source dir: '%S'\n", keyFName);
34538 	    keyFile = ajFileNewInNameS(keyFName);
34539 	}
34540     }
34541 
34542     if(!keyFile)			/* test acdc-keymissing */
34543 	ajDie("Keyword file %S not found", keyFName);
34544     else
34545 	acdLog("Keyword file %F used\n", keyFile);
34546 
34547     keyxp = ajRegCompC("([^ ]+) +([^ ].*)");
34548     while(keyFile && ajReadlineTrim(keyFile, &keyLine))
34549     {
34550 	if(ajStrCutComments(&keyLine))
34551 	{
34552 	    ajStrRemoveWhiteExcess(&keyLine);
34553 
34554 	    if(ajRegExec(keyxp, keyLine))
34555 	    {
34556 		ajRegSubI(keyxp, 1, &keyName);
34557 		ajRegSubI(keyxp, 2, &keyDesc);
34558 		ajStrExchangeKK(&keyName, '_', ' ');
34559 
34560 		if(ajTableFetchS(acdGrpTable, keyName))
34561 		    ajWarn("Keyword %S in file %S is a known group",
34562 			   keyName, keyFName);
34563 		if(ajTablePut(ret, keyName, keyDesc))
34564 		    ajWarn("Duplicate keyword in file %S",
34565 			   keyFName);
34566 		keyName = NULL;
34567 		keyDesc = NULL;
34568 	    }
34569 	    else
34570 		ajErr("Bad record in file %S:\n%S",
34571 		      keyFName, keyLine);
34572 	}
34573     }
34574 
34575     ajFileClose(&keyFile);
34576 
34577     ajStrDel(&keyFName);
34578     ajStrDel(&keyRoot);
34579     ajStrDel(&keyRootInst);
34580     ajStrDel(&keyPack);
34581     ajStrDel(&keyLine);
34582     ajStrDel(&keyName);
34583     ajStrDel(&keyDesc);
34584 
34585     ajRegFree(&keyxp);
34586 
34587     return ret;
34588 }
34589 
34590 
34591 
34592 
34593 /* @funcstatic acdReadSections ************************************************
34594 **
34595 ** Read standard file of ACD sections and store in AjPTable objects
34596 **
34597 ** @param [wN] typetable [AjPTable*] String table of section names and types
34598 ** @param [wN] infotable [AjPTable*] String table of section names and
34599 **                                 descriptions
34600 ** @return [void]
34601 **
34602 ** @release 2.8.0
34603 ** @@
34604 ******************************************************************************/
34605 
acdReadSections(AjPTable * typetable,AjPTable * infotable)34606 static void acdReadSections(AjPTable* typetable, AjPTable* infotable)
34607 {
34608     AjPFile sectFile    = NULL;
34609     AjPStr sectFName    = NULL;
34610     AjPStr sectRoot     = NULL;
34611     AjPStr sectRootInst = NULL;
34612     AjPStr sectPack     = NULL;
34613     AjPStr sectLine     = NULL;
34614     AjPRegexp sectxp    = NULL;
34615     AjPStr sectName     = NULL;
34616     AjPStr sectType     = NULL;
34617     AjPStr sectDesc     = NULL;
34618 
34619     ajStrAssignS(&sectPack, ajNamValuePackage());
34620     ajStrAssignS(&sectRootInst, ajNamValueInstalldir());
34621     ajDirnameFix(&sectRootInst);
34622 
34623     *typetable = ajTablestrNewCase(50);
34624     *infotable = ajTablestrNewCase(50);
34625 
34626     if(ajNamGetValueC("acdroot", &sectRoot))
34627     {
34628 	ajDirnameFix(&sectRoot);
34629 	ajFmtPrintS(&sectFName, "%Ssections.standard", sectRoot);
34630 	sectFile = ajFileNewInNameS(sectFName);
34631 	acdLog("Section file in acdroot: '%S'\n", sectFName);
34632     }
34633     else
34634     {
34635 	ajFmtPrintS(&sectFName, "%Sshare/%S/acd/sections.standard",
34636 		    sectRootInst, sectPack);
34637 	acdLog("Section file installed: '%S'\n", sectFName);
34638 	sectFile = ajFileNewInNameS(sectFName);
34639 
34640 	if(!sectFile)
34641 	{
34642 	    acdLog("Sect file '%S' not opened\n", sectFName);
34643 	    ajStrAssignS(&sectRoot, ajNamValueRootdir());
34644 	    ajDirnameFix(&sectRoot);
34645 	    ajFmtPrintS(&sectFName, "%Sacd/sections.standard", sectRoot);
34646 	    acdLog("Sect file from source dir: '%S'\n", sectFName);
34647 	    sectFile = ajFileNewInNameS(sectFName);
34648 	}
34649     }
34650 
34651     if(!sectFile)			/* test acdc-sectmissing */
34652 	ajDie("Section file %S not found", sectFName);
34653     else
34654 	acdLog("Section file %F used\n", sectFile);
34655 
34656     sectxp = ajRegCompC("([^ ]+) +([^ ]+) +([^ ].*)");
34657 
34658     while(sectFile && ajReadlineTrim(sectFile, &sectLine))
34659     {
34660 	if(ajStrCutComments(&sectLine))
34661 	{
34662 	    ajStrRemoveWhiteExcess(&sectLine);
34663 
34664 	    if(ajRegExec(sectxp, sectLine))
34665 	    {
34666 		ajRegSubI(sectxp, 1, &sectName);
34667 		ajRegSubI(sectxp, 2, &sectType);
34668 		ajRegSubI(sectxp, 3, &sectDesc);
34669 		ajStrExchangeKK(&sectName, '_', ' ');
34670 
34671 		if(ajTablePut(*typetable, sectName, sectType))
34672 		    ajWarn("Duplicate section name in file %S",
34673 			   sectFName);
34674 
34675 		if(ajTablePut(*infotable, sectName, sectDesc))
34676 		    ajWarn("Duplicate section name in file %S",
34677 			   sectFName);
34678 		sectName = NULL;
34679 		sectType = NULL;
34680 		sectDesc = NULL;
34681 	    }
34682 	    else
34683 		ajErr("Bad record in file %S:\n%S",
34684 		      sectFName, sectLine);
34685 	}
34686     }
34687 
34688     ajFileClose(&sectFile);
34689     ajStrDel(&sectFName);
34690     ajStrDel(&sectRoot);
34691     ajStrDel(&sectRootInst);
34692     ajStrDel(&sectPack);
34693     ajStrDel(&sectLine);
34694     ajStrDel(&sectName);
34695     ajStrDel(&sectType);
34696     ajStrDel(&sectDesc);
34697     ajRegFree(&sectxp);
34698 
34699 
34700     return;
34701 }
34702 
34703 
34704 
34705 
34706 /* @funcstatic acdValidSectionMatch *******************************************
34707 **
34708 ** Tests whether a named section appears in the current section list
34709 **
34710 ** @param [r] secname [const char*] Section name
34711 ** @return [AjBool] ajTrue if the named section was found
34712 **
34713 ** @release 2.9.0
34714 ** @@
34715 ******************************************************************************/
34716 
acdValidSectionMatch(const char * secname)34717 static AjBool acdValidSectionMatch(const char* secname)
34718 {
34719     AjIList iter = NULL;
34720     AjPStr listsecname;
34721     AjBool ret = ajFalse;
34722 
34723     if(!ajListGetLength(acdSecList))
34724 	return ajFalse;
34725 
34726     iter = ajListIterNewread(acdSecList);
34727 
34728     while (!ajListIterDone(iter))
34729     {
34730 	listsecname = ajListIterGet(iter);
34731 
34732 	if(ajStrMatchC(listsecname, secname))
34733 	{
34734 	    ret = ajTrue;
34735 	    break;
34736 	}
34737     }
34738 
34739     ajListIterDel(&iter);
34740 
34741     return ret;
34742 }
34743 
34744 
34745 
34746 
34747 /* @funcstatic acdValidSectionFull ********************************************
34748 **
34749 ** Returns the full section name with the top level and any frame
34750 ** sub-sections
34751 **
34752 ** @param [w] secname [AjPStr*] Section name
34753 ** @return [void]
34754 **
34755 ** @release 2.9.0
34756 ******************************************************************************/
34757 
acdValidSectionFull(AjPStr * secname)34758 static void acdValidSectionFull(AjPStr* secname)
34759 {
34760     AjIList iter = NULL;
34761     AjPStr listsecname;
34762 
34763     ajStrAssignClear(secname);
34764 
34765     if(!ajListGetLength(acdSecList))
34766 	return;
34767 
34768     iter = ajListIterNewread(acdSecList);
34769 
34770     while (!ajListIterDone(iter))
34771     {
34772 	listsecname = ajListIterGet(iter);
34773 
34774 	if (ajStrGetLen(*secname))
34775 	    ajStrAppendK(secname,':');
34776 
34777 	ajStrAppendS(secname, listsecname);
34778     }
34779 
34780     ajListIterDel(&iter);
34781 
34782     return;
34783 }
34784 
34785 
34786 
34787 
34788 /* @funcstatic acdOutFormatCpdb ***********************************************
34789 **
34790 ** Tests the output format for an outcpdb ACD type
34791 **
34792 ** @param [r] name [const AjPStr] Format name
34793 ** @param [w] iformat [ajint*] Index
34794 ** @return [AjBool] ajTrue on success.
34795 **
34796 ** @release 2.9.0
34797 ** @@
34798 ******************************************************************************/
34799 
acdOutFormatCpdb(const AjPStr name,ajint * iformat)34800 static AjBool acdOutFormatCpdb(const AjPStr name, ajint* iformat)
34801 {
34802     ajint i;
34803     const char* format[] =
34804     {
34805 	"cpdb",
34806 	NULL
34807     };
34808 
34809     for (i=0; format[i]; i++)
34810 	if(ajStrMatchCaseC(name, format[i]))
34811         {
34812             *iformat = i;
34813             return ajTrue;
34814         }
34815 
34816     return ajFalse;
34817 }
34818 
34819 
34820 
34821 
34822 /* @funcstatic acdOutFormatData ***********************************************
34823 **
34824 ** Tests the output format for an out ACD type
34825 **
34826 ** @param [r] name [const AjPStr] Format name
34827 ** @param [w] iformat [ajint*] Index
34828 ** @return [AjBool] ajTrue on success.
34829 **
34830 ** @release 2.9.0
34831 ** @@
34832 ******************************************************************************/
34833 
acdOutFormatData(const AjPStr name,ajint * iformat)34834 static AjBool acdOutFormatData(const AjPStr name, ajint* iformat)
34835 {
34836     ajint i;
34837     const char* format[] =
34838     {
34839 	"text",
34840 	NULL
34841     };
34842 
34843     for (i=0; format[i]; i++)
34844 	if(ajStrMatchCaseC(name, format[i]))
34845         {
34846             *iformat = i;
34847             return ajTrue;
34848         }
34849 
34850     return ajFalse;
34851 }
34852 
34853 
34854 
34855 
34856 /* @funcstatic acdOutFormatDiscrete *******************************************
34857 **
34858 ** Tests the output format for an out ACD type
34859 **
34860 ** @param [r] name [const AjPStr] Format name
34861 ** @param [w] iformat [ajint*] Index
34862 ** @return [AjBool] ajTrue on success.
34863 **
34864 ** @release 2.9.0
34865 ** @@
34866 ******************************************************************************/
34867 
acdOutFormatDiscrete(const AjPStr name,ajint * iformat)34868 static AjBool acdOutFormatDiscrete(const AjPStr name, ajint* iformat)
34869 {
34870     ajint i;
34871     const char* format[] =
34872     {
34873 	"phylip",
34874 	NULL
34875     };
34876 
34877     for (i=0; format[i]; i++)
34878 	if(ajStrMatchCaseC(name, format[i]))
34879         {
34880             *iformat = i;
34881             return ajTrue;
34882         }
34883 
34884     return ajFalse;
34885 }
34886 
34887 
34888 
34889 
34890 /* @funcstatic acdOutFormatDistance *******************************************
34891 **
34892 ** Tests the output format for an outdistance ACD type
34893 **
34894 ** @param [r] name [const AjPStr] Format name
34895 ** @param [w] iformat [ajint*] Index
34896 ** @return [AjBool] ajTrue on success.
34897 **
34898 ** @release 2.9.0
34899 ** @@
34900 ******************************************************************************/
34901 
acdOutFormatDistance(const AjPStr name,ajint * iformat)34902 static AjBool acdOutFormatDistance(const AjPStr name, ajint* iformat)
34903 {
34904     ajint i;
34905     const char* format[] =
34906     {
34907 	"phylip",
34908 	NULL
34909     };
34910 
34911    for (i=0; format[i]; i++)
34912 	if(ajStrMatchCaseC(name, format[i]))
34913         {
34914             *iformat = i;
34915             return ajTrue;
34916         }
34917 
34918     return ajFalse;
34919 }
34920 
34921 
34922 
34923 
34924 /* @funcstatic acdOutFormatFreq ***********************************************
34925 **
34926 ** Tests the output format for an outfreq ACD type
34927 **
34928 ** @param [r] name [const AjPStr] Format name
34929 ** @param [w] iformat [ajint*] Index
34930 ** @return [AjBool] ajTrue on success.
34931 **
34932 ** @release 2.9.0
34933 ** @@
34934 ******************************************************************************/
34935 
acdOutFormatFreq(const AjPStr name,ajint * iformat)34936 static AjBool acdOutFormatFreq(const AjPStr name, ajint* iformat)
34937 {
34938     ajint i;
34939     const char* format[] =
34940     {
34941 	"phylip",
34942 	NULL
34943     };
34944 
34945    for (i=0; format[i]; i++)
34946 	if(ajStrMatchCaseC(name, format[i]))
34947         {
34948             *iformat = i;
34949             return ajTrue;
34950         }
34951 
34952     return ajFalse;
34953 }
34954 
34955 
34956 
34957 
34958 /* @funcstatic acdOutFormatMatrix *********************************************
34959 **
34960 ** Tests the output format for an outmatrix ACD type
34961 **
34962 ** @param [r] name [const AjPStr] Format name
34963 ** @param [w] iformat [ajint*] Index
34964 ** @return [AjBool] ajTrue on success.
34965 **
34966 ** @release 2.9.0
34967 ** @@
34968 ******************************************************************************/
34969 
acdOutFormatMatrix(const AjPStr name,ajint * iformat)34970 static AjBool acdOutFormatMatrix(const AjPStr name, ajint* iformat)
34971 {
34972     ajint i;
34973     const char* format[] =
34974     {
34975 	"emboss",
34976 	NULL
34977     };
34978 
34979    for (i=0; format[i]; i++)
34980 	if(ajStrMatchCaseC(name, format[i]))
34981         {
34982             *iformat = i;
34983             return ajTrue;
34984         }
34985 
34986     return ajFalse;
34987 }
34988 
34989 
34990 
34991 
34992 /* @funcstatic acdOutFormatMatrixf ********************************************
34993 **
34994 ** Tests the output format for an outmatrixf ACD type
34995 **
34996 ** @param [r] name [const AjPStr] Format name
34997 ** @param [w] iformat [ajint*] Index
34998 ** @return [AjBool] ajTrue on success.
34999 **
35000 ** @release 2.9.0
35001 ** @@
35002 ******************************************************************************/
35003 
acdOutFormatMatrixf(const AjPStr name,ajint * iformat)35004 static AjBool acdOutFormatMatrixf(const AjPStr name, ajint* iformat)
35005 {
35006     ajint i;
35007     const char* format[] =
35008     {
35009 	"emboss",
35010 	NULL
35011     };
35012 
35013    for (i=0; format[i]; i++)
35014 	if(ajStrMatchCaseC(name, format[i]))
35015         {
35016             *iformat = i;
35017             return ajTrue;
35018         }
35019 
35020     return ajFalse;
35021 }
35022 
35023 
35024 
35025 
35026 /* @funcstatic acdOutFormatProperties *****************************************
35027 **
35028 ** Tests the output format for an outproperties ACD type
35029 **
35030 ** @param [r] name [const AjPStr] Format name
35031 ** @param [w] iformat [ajint*] Index
35032 ** @return [AjBool] ajTrue on success.
35033 **
35034 ** @release 2.9.0
35035 ** @@
35036 ******************************************************************************/
35037 
acdOutFormatProperties(const AjPStr name,ajint * iformat)35038 static AjBool acdOutFormatProperties(const AjPStr name, ajint* iformat)
35039 {
35040     ajint i;
35041     const char* format[] =
35042     {
35043 	"phylip",
35044 	NULL
35045     };
35046 
35047    for (i=0; format[i]; i++)
35048 	if(ajStrMatchCaseC(name, format[i]))
35049         {
35050             *iformat = i;
35051             return ajTrue;
35052         }
35053 
35054     return ajFalse;
35055 }
35056 
35057 
35058 
35059 
35060 /* @funcstatic acdOutFormatScop ***********************************************
35061 **
35062 ** Tests the output format for an outscop ACD type
35063 **
35064 ** @param [r] name [const AjPStr] Format name
35065 ** @param [w] iformat [ajint*] Index
35066 ** @return [AjBool] ajTrue on success.
35067 **
35068 ** @release 2.9.0
35069 ** @@
35070 ******************************************************************************/
35071 
acdOutFormatScop(const AjPStr name,ajint * iformat)35072 static AjBool acdOutFormatScop(const AjPStr name, ajint* iformat)
35073 {
35074     ajint i;
35075     const char* format[] =
35076     {
35077 	"scop",
35078 	NULL
35079     };
35080 
35081    for (i=0; format[i]; i++)
35082 	if(ajStrMatchCaseC(name, format[i]))
35083         {
35084             *iformat = i;
35085             return ajTrue;
35086         }
35087 
35088     return ajFalse;
35089 }
35090 
35091 
35092 
35093 
35094 /* @funcstatic acdOutFormatTree ***********************************************
35095 **
35096 ** Tests the output format for an outtree ACD type
35097 **
35098 ** @param [r] name [const AjPStr] Format name
35099 ** @param [w] iformat [ajint*] Index
35100 ** @return [AjBool] ajTrue on success.
35101 **
35102 ** @release 2.9.0
35103 ** @@
35104 ******************************************************************************/
35105 
acdOutFormatTree(const AjPStr name,ajint * iformat)35106 static AjBool acdOutFormatTree(const AjPStr name, ajint* iformat)
35107 {
35108     ajint i;
35109     const char* format[] =
35110     {
35111 	"phylip",
35112 	"newick",
35113 	NULL
35114     };
35115 
35116    for (i=0; format[i]; i++)
35117 	if(ajStrMatchCaseC(name, format[i]))
35118         {
35119             *iformat = i;
35120             return ajTrue;
35121         }
35122 
35123     return ajFalse;
35124 }
35125 
35126 
35127 
35128 
35129 /* @funcstatic acdKnownValueList **********************************************
35130 **
35131 ** Finds a list value associated with a known type
35132 **
35133 ** @param [r] thys [const AcdPAcd] ACD object
35134 ** @param [w] value [AjPStr*] Standard value
35135 ** @return [AjBool] ajTrue if a value was set
35136 **
35137 ** @release 3.0.0
35138 ** @@
35139 ******************************************************************************/
35140 
acdKnownValueList(const AcdPAcd thys,AjPStr * value)35141 static AjBool acdKnownValueList(const AcdPAcd thys, AjPStr* value)
35142 {
35143     const AjPStr type = NULL;
35144     AjPStr resource = NULL;
35145     AjPStr list = NULL;
35146     ajint i;
35147 
35148     type = acdAttrValue(thys, "knowntype");
35149 
35150     if(!type)
35151 	return ajFalse;
35152 
35153     for(i=0; acdResource[i]; i++)
35154 	if(ajStrMatchCaseC(type, acdResource[i]))
35155 	{
35156 	    resource = ajStrNewS(type);
35157 	    ajStrExchangeKK(&resource, ' ', '_');
35158 
35159 	    if(ajNamRsListValue(resource, &list))
35160 	    {
35161 		if(acdResourceList(thys, list, value))
35162 		    return ajTrue;
35163 	    }
35164 	}
35165 
35166     return ajFalse;
35167 }
35168 
35169 
35170 
35171 
35172 /* @funcstatic acdKnownValueSelect ********************************************
35173 **
35174 ** Finds a selection value associated with a known type
35175 **
35176 ** @param [r] thys [const AcdPAcd] ACD object
35177 ** @param [w] value [AjPStr*] Standard value
35178 ** @return [AjBool] ajTrue if a value was set
35179 **
35180 ** @release 3.0.0
35181 ** @@
35182 ******************************************************************************/
35183 
acdKnownValueSelect(const AcdPAcd thys,AjPStr * value)35184 static AjBool acdKnownValueSelect(const AcdPAcd thys, AjPStr* value)
35185 {
35186     const AjPStr type = NULL;
35187     AjPStr resource = NULL;
35188     AjPStr list = NULL;
35189     ajint i;
35190 
35191     type = acdAttrValue(thys, "knowntype");
35192     if(!type)
35193 	return ajFalse;
35194 
35195     for(i=0; acdResource[i]; i++)
35196 	if(ajStrMatchCaseC(type, acdResource[i]))
35197 	{
35198 	    resource = ajStrNewS(type);
35199 	    ajStrExchangeKK(&resource, ' ', '_');
35200 
35201 	    if(ajNamRsListValue(resource, &list))
35202 	    {
35203 		if(acdResourceList(thys, list, value))
35204 		    return ajTrue;
35205 	    }
35206 	}
35207 
35208     return ajFalse;
35209 }
35210 
35211 
35212 
35213 
35214 /* @funcstatic acdResourceList ************************************************
35215 **
35216 ** Finds a list value associated with a known type
35217 **
35218 ** @param [r] thys [const AcdPAcd] ACD object
35219 ** @param [r] list [const AjPStr] Resource value
35220 ** @param [w] value [AjPStr*] Standard list value
35221 ** @return [AjBool] ajTrue if a value was set
35222 **
35223 ** @release 3.0.0
35224 ** @@
35225 ******************************************************************************/
35226 
acdResourceList(const AcdPAcd thys,const AjPStr list,AjPStr * value)35227 static AjBool acdResourceList(const AcdPAcd thys,
35228 			      const AjPStr list, AjPStr* value)
35229 {
35230     AjPStr delim = NULL;
35231     AjPStr codedelim = NULL;
35232     AjPFile infile = NULL;
35233     AjPStr line = NULL;
35234     AjPStr tok1 = NULL;
35235     AjPStr tok2 = NULL;
35236     AjPStrTok handle = NULL;
35237     AjPStr liststr = NULL;
35238 
35239     if (!ajStrGetLen(list))
35240 	return ajFalse;
35241 
35242     liststr = ajStrNewS(list);
35243 
35244     acdAttrValueStr(thys, "delimiter", ";", &delim);
35245     acdAttrValueStr(thys, "codedelimiter", ":", &codedelim);
35246 
35247     if(ajStrGetCharFirst(list) == '@')
35248     {
35249 	ajStrAssignClear(value);
35250 	ajStrCutStart(&liststr, 1);
35251 	infile = ajDatafileNewInNameS(liststr);
35252 
35253 	if(!infile)
35254 	    return ajFalse;
35255 
35256 	while(ajReadlineTrim(infile, &line))
35257 	{
35258 	    ajStrTrimWhite(&line);
35259 
35260 	    if(ajStrGetCharFirst(line) == '#')
35261 		continue;
35262 	    ajStrTokenAssignC(&handle, line, " ");
35263 	    ajStrTokenNextParse(handle, &tok1);
35264 	    ajStrTokenRestParse(handle, &tok2);
35265 
35266 	    if(ajStrGetLen(*value))
35267 		ajStrAppendS(value, delim);
35268 
35269 	    ajStrAppendS(value, tok1);
35270 	    ajStrAppendS(value, codedelim);
35271 	    ajStrAppendS(value, tok2);
35272 	}
35273 
35274 	ajFileClose(&infile);
35275 
35276 	return ajTrue;
35277     }
35278 
35279     /* value will use : and ; as delimiters */
35280 
35281     ajStrAssignS(value, liststr);
35282     ajStrExchangeKK(value, ';', '\1');
35283     ajStrExchangeKK(value, ':', '\2');
35284     ajStrExchangeKK(value, '\1', ajStrGetCharFirst(delim));
35285     ajStrExchangeKK(value, '\2', ajStrGetCharFirst(codedelim));
35286 
35287     return ajTrue;
35288 }
35289 
35290 
35291 
35292 
35293 /* @funcstatic acdDelAlign ****************************************************
35294 **
35295 ** Function with void** prototype to delete ACD alignment data
35296 **
35297 ** @param [d] PPval [void**] Value to be deleted
35298 ** @return [void]
35299 **
35300 ** @release 4.0.0
35301 ******************************************************************************/
35302 
acdDelAlign(void ** PPval)35303 static void acdDelAlign(void** PPval)
35304 {
35305     if(!*PPval)
35306         return;
35307 
35308     ajAlignDel((AjPAlign*)PPval);
35309 
35310     return;
35311 }
35312 
35313 
35314 
35315 
35316 /* @funcstatic acdDelAssembly *************************************************
35317 **
35318 ** Function with void** prototype to delete ACD assembly input data
35319 **
35320 ** @param [d] PPval [void**] Value to be deleted
35321 ** @return [void]
35322 **
35323 ** @release 6.5.0
35324 **
35325 ******************************************************************************/
35326 
acdDelAssembly(void ** PPval)35327 static void acdDelAssembly(void** PPval)
35328 {
35329     if(!*PPval)
35330         return;
35331 
35332     ajAssemDel((AjPAssem*)PPval);
35333 
35334     return;
35335 }
35336 
35337 
35338 
35339 
35340 /* @funcstatic acdDelCod ******************************************************
35341 **
35342 ** Function with void** prototype to delete ACD codon usage data
35343 **
35344 ** @param [d] PPval [void**] Value to be deleted
35345 ** @return [void]
35346 **
35347 ** @release 4.0.0
35348 ******************************************************************************/
35349 
acdDelCod(void ** PPval)35350 static void acdDelCod(void** PPval)
35351 {
35352     if(!*PPval)
35353         return;
35354 
35355     ajCodDel((AjPCod*)PPval);
35356 
35357     return;
35358 }
35359 
35360 
35361 
35362 
35363 /* @funcstatic acdDelDir ******************************************************
35364 **
35365 ** Function with void** prototype to delete ACD directory data
35366 **
35367 ** @param [d] PPval [void**] Value to be deleted
35368 ** @return [void]
35369 **
35370 ** @release 4.0.0
35371 ******************************************************************************/
35372 
acdDelDir(void ** PPval)35373 static void acdDelDir(void** PPval)
35374 {
35375     if(!*PPval)
35376         return;
35377 
35378     ajDirDel((AjPDir*)PPval);
35379 
35380     return;
35381 }
35382 
35383 
35384 
35385 
35386 /* @funcstatic acdDelDirout ***************************************************
35387 **
35388 ** Function with void** prototype to delete ACD directory data
35389 **
35390 ** @param [d] PPval [void**] Value to be deleted
35391 ** @return [void]
35392 **
35393 ** @release 6.0.0
35394 ******************************************************************************/
35395 
acdDelDirout(void ** PPval)35396 static void acdDelDirout(void** PPval)
35397 {
35398     if(!*PPval)
35399         return;
35400 
35401     ajDiroutDel((AjPDirout*)PPval);
35402 
35403     return;
35404 }
35405 
35406 
35407 
35408 
35409 /* @funcstatic acdDelFeattable ************************************************
35410 **
35411 ** Function with void** prototype to delete ACD feature table data
35412 **
35413 ** @param [d] PPval [void**] Value to be deleted
35414 ** @return [void]
35415 **
35416 ** @release 4.0.0
35417 ******************************************************************************/
35418 
acdDelFeattable(void ** PPval)35419 static void acdDelFeattable(void** PPval)
35420 {
35421     if(!*PPval)
35422         return;
35423 
35424     ajFeattaballDel((AjPFeattaball*)PPval);
35425 
35426     return;
35427 }
35428 
35429 
35430 
35431 
35432 /* @funcstatic acdDelFeattabOut ***********************************************
35433 **
35434 ** Function with void** prototype to delete ACD output feature table data
35435 **
35436 ** @param [d] PPval [void**] Value to be deleted
35437 ** @return [void]
35438 **
35439 ** @release 4.0.0
35440 ******************************************************************************/
35441 
acdDelFeattabOut(void ** PPval)35442 static void acdDelFeattabOut(void** PPval)
35443 {
35444     if(!*PPval)
35445         return;
35446 
35447     ajFeattabOutDel((AjPFeattabOut*)PPval);
35448 
35449     return;
35450 }
35451 
35452 
35453 
35454 
35455 /* @funcstatic acdDelFile *****************************************************
35456 **
35457 ** Function with void** prototype to delete ACD input file data
35458 **
35459 ** @param [d] PPval [void**] Value to be deleted
35460 ** @return [void]
35461 **
35462 ** @release 4.0.0
35463 ******************************************************************************/
35464 
acdDelFile(void ** PPval)35465 static void acdDelFile(void** PPval)
35466 {
35467     if(!*PPval)
35468         return;
35469 
35470     ajFileClose((AjPFile*)PPval);
35471 
35472     return;
35473 }
35474 
35475 
35476 
35477 
35478 /* @funcstatic acdDelFloat ****************************************************
35479 **
35480 ** Function with void** prototype to delete ACD floating point array data
35481 **
35482 ** @param [d] PPval [void**] Value to be deleted
35483 ** @return [void]
35484 **
35485 ** @release 4.0.0
35486 ******************************************************************************/
35487 
acdDelFloat(void ** PPval)35488 static void acdDelFloat(void** PPval)
35489 {
35490     if(!*PPval)
35491         return;
35492 
35493     ajFloatDel((AjPFloat*)PPval);
35494 
35495     return;
35496 }
35497 
35498 
35499 
35500 
35501 /* @funcstatic acdDelList *****************************************************
35502 **
35503 ** Function with void** prototype to delete ACD list/selection data
35504 **
35505 ** @param [d] PPval [void**] Value to be deleted
35506 ** @return [void]
35507 **
35508 ** @release 4.0.0
35509 ******************************************************************************/
35510 
acdDelList(void ** PPval)35511 static void acdDelList(void** PPval)
35512 {
35513     if(!*PPval)
35514         return;
35515 
35516     ajListstrFreeData((AjPList*)PPval);
35517 
35518     return;
35519 }
35520 
35521 
35522 
35523 
35524 /* @funcstatic acdDelMatrix ***************************************************
35525 **
35526 ** Function with void** prototype to delete ACD integer comparison matrix data
35527 **
35528 ** @param [d] PPval [void**] Value to be deleted
35529 ** @return [void]
35530 **
35531 ** @release 4.0.0
35532 ******************************************************************************/
35533 
acdDelMatrix(void ** PPval)35534 static void acdDelMatrix(void** PPval)
35535 {
35536     if(!*PPval)
35537         return;
35538 
35539     ajMatrixDel((AjPMatrix*)PPval);
35540 
35541     return;
35542 }
35543 
35544 
35545 
35546 
35547 /* @funcstatic acdDelMatrixf **************************************************
35548 **
35549 ** Function with void** prototype to delete ACD floating point comparison
35550 ** matrix data
35551 **
35552 ** @param [d] PPval [void**] Value to be deleted
35553 ** @return [void]
35554 **
35555 ** @release 4.0.0
35556 ******************************************************************************/
35557 
acdDelMatrixf(void ** PPval)35558 static void acdDelMatrixf(void** PPval)
35559 {
35560     if(!*PPval)
35561         return;
35562 
35563     ajMatrixfDel((AjPMatrixf*)PPval);
35564 
35565     return;
35566 }
35567 
35568 
35569 
35570 
35571 /* @funcstatic acdDelObo ******************************************************
35572 **
35573 ** Function with void** prototype to delete ACD obo term input data
35574 **
35575 ** @param [d] PPval [void**] Value to be deleted
35576 ** @return [void]
35577 **
35578 ** @release 6.4.0
35579 ******************************************************************************/
35580 
acdDelObo(void ** PPval)35581 static void acdDelObo(void** PPval)
35582 {
35583     if(!*PPval)
35584         return;
35585 
35586     ajOboallDel((AjPOboall*)PPval);
35587 
35588     return;
35589 }
35590 
35591 
35592 
35593 
35594 /* @funcstatic acdDelOutfile **************************************************
35595 **
35596 ** Function with void** prototype to delete ACD output file data
35597 **
35598 ** @param [d] PPval [void**] Value to be deleted
35599 ** @return [void]
35600 **
35601 ** @release 4.0.0
35602 ******************************************************************************/
35603 
acdDelOutfile(void ** PPval)35604 static void acdDelOutfile(void** PPval)
35605 {
35606     if(!*PPval)
35607         return;
35608 
35609     ajOutfileClose((AjPOutfile*)PPval);
35610 
35611     return;
35612 }
35613 
35614 
35615 
35616 
35617 /* @funcstatic acdDelPatlist **************************************************
35618 **
35619 ** Function with void** prototype to delete ACD pattern list data
35620 **
35621 ** @param [d] PPval [void**] Value to be deleted
35622 ** @return [void]
35623 **
35624 ** @release 4.0.0
35625 ******************************************************************************/
35626 
acdDelPatlist(void ** PPval)35627 static void acdDelPatlist(void** PPval)
35628 {
35629     if(!*PPval)
35630         return;
35631 
35632     ajPatlistSeqDel((AjPPatlistSeq*)PPval);
35633 
35634     return;
35635 }
35636 
35637 
35638 
35639 
35640 /* @funcstatic acdDelPhyloDist ************************************************
35641 **
35642 ** Function with void** prototype to delete ACD phylogenetic distance data
35643 **
35644 ** @param [d] PPval [void**] Value to be deleted
35645 ** @return [void]
35646 **
35647 ** @release 4.0.0
35648 ******************************************************************************/
35649 
acdDelPhyloDist(void ** PPval)35650 static void acdDelPhyloDist(void** PPval)
35651 {
35652     if(!*PPval)
35653         return;
35654 
35655     ajPhyloDistDel((AjPPhyloDist*)PPval);
35656 
35657     return;
35658 }
35659 
35660 
35661 
35662 
35663 /* @funcstatic acdDelPhyloFreq ************************************************
35664 **
35665 ** Function with void** prototype to delete ACD phylogenetic frequency data
35666 **
35667 ** @param [d] PPval [void**] Value to be deleted
35668 ** @return [void]
35669 **
35670 ** @release 4.0.0
35671 ******************************************************************************/
35672 
acdDelPhyloFreq(void ** PPval)35673 static void acdDelPhyloFreq(void** PPval)
35674 {
35675     ajUser("acdDelPhyloFreq '%x'", *PPval);
35676 
35677     if(!*PPval)
35678         return;
35679 
35680     ajPhyloFreqDel((AjPPhyloFreq*)PPval);
35681 
35682     return;
35683 }
35684 
35685 
35686 
35687 
35688 /* @funcstatic acdDelPhyloProp ************************************************
35689 **
35690 ** Function with void** prototype to delete ACD phylogenetic properties data
35691 **
35692 ** @param [d] PPval [void**] Value to be deleted
35693 ** @return [void]
35694 **
35695 ** @release 4.0.0
35696 ******************************************************************************/
35697 
acdDelPhyloProp(void ** PPval)35698 static void acdDelPhyloProp(void** PPval)
35699 {
35700     if(!*PPval)
35701         return;
35702 
35703     ajPhyloPropDel((AjPPhyloProp*)PPval);
35704 
35705     return;
35706 }
35707 
35708 
35709 
35710 
35711 /* @funcstatic acdDelPhyloState ***********************************************
35712 **
35713 ** Function with void** prototype to delete ACD phylogenetic state data
35714 **
35715 ** @param [d] PPval [void**] Value to be deleted
35716 ** @return [void]
35717 **
35718 ** @release 4.0.0
35719 ******************************************************************************/
35720 
acdDelPhyloState(void ** PPval)35721 static void acdDelPhyloState(void** PPval)
35722 {
35723     if(!*PPval)
35724         return;
35725 
35726     ajPhyloStateDel((AjPPhyloState*)PPval);
35727 
35728     return;
35729 }
35730 
35731 
35732 
35733 
35734 /* @funcstatic acdDelPhyloTree ************************************************
35735 **
35736 ** Function with void** prototype to delete ACD phylogenetic tree data
35737 **
35738 ** @param [d] PPval [void**] Value to be deleted
35739 ** @return [void]
35740 **
35741 ** @release 4.0.0
35742 ******************************************************************************/
35743 
acdDelPhyloTree(void ** PPval)35744 static void acdDelPhyloTree(void** PPval)
35745 {
35746     if(!*PPval)
35747         return;
35748 
35749     ajPhyloTreeDelarray((AjPPhyloTree**)PPval);
35750 
35751     return;
35752 }
35753 
35754 
35755 
35756 
35757 /* @funcstatic acdDelRange ****************************************************
35758 **
35759 ** Function with void** prototype to delete ACD range data
35760 **
35761 ** @param [d] PPval [void**] Value to be deleted
35762 ** @return [void]
35763 **
35764 ** @release 4.0.0
35765 ******************************************************************************/
35766 
acdDelRange(void ** PPval)35767 static void acdDelRange(void** PPval)
35768 {
35769     if(!*PPval)
35770         return;
35771 
35772     ajRangeDel((AjPRange*)PPval);
35773 
35774     return;
35775 }
35776 
35777 
35778 
35779 
35780 /* @funcstatic acdDelRefseq ***************************************************
35781 **
35782 ** Function with void** prototype to delete ACD reference sequence input data
35783 **
35784 ** @param [d] PPval [void**] Value to be deleted
35785 ** @return [void]
35786 **
35787 ** @release 6.5.0
35788 **
35789 ******************************************************************************/
35790 
acdDelRefseq(void ** PPval)35791 static void acdDelRefseq(void** PPval)
35792 {
35793     if(!*PPval)
35794         return;
35795 
35796     ajRefseqDel((AjPRefseq*)PPval);
35797 
35798     return;
35799 }
35800 
35801 
35802 
35803 
35804 /* @funcstatic acdDelReg ******************************************************
35805 **
35806 ** Function with void** prototype to delete ACD regular expression data
35807 **
35808 ** @param [d] PPval [void**] Value to be deleted
35809 ** @return [void]
35810 **
35811 ** @release 4.0.0
35812 ******************************************************************************/
35813 
acdDelReg(void ** PPval)35814 static void acdDelReg(void** PPval)
35815 {
35816     if(!*PPval)
35817         return;
35818 
35819     ajPatlistRegexDel((AjPPatlistRegex*)PPval);
35820 
35821     return;
35822 }
35823 
35824 
35825 
35826 
35827 /* @funcstatic acdDelReport ***************************************************
35828 **
35829 ** Function with void** prototype to delete ACD report data
35830 **
35831 ** @param [d] PPval [void**] Value to be deleted
35832 ** @return [void]
35833 **
35834 ** @release 4.0.0
35835 ******************************************************************************/
35836 
acdDelReport(void ** PPval)35837 static void acdDelReport(void** PPval)
35838 {
35839     if(!*PPval)
35840         return;
35841 
35842     ajReportDel((AjPReport*)PPval);
35843 
35844     return;
35845 }
35846 
35847 
35848 
35849 
35850 /* @funcstatic acdDelResource *************************************************
35851 **
35852 ** Function with void** prototype to delete ACD data resource input data
35853 **
35854 ** @param [d] PPval [void**] Value to be deleted
35855 ** @return [void]
35856 **
35857 ** @release 6.4.0
35858 ******************************************************************************/
35859 
acdDelResource(void ** PPval)35860 static void acdDelResource(void** PPval)
35861 {
35862     if(!*PPval)
35863         return;
35864 
35865     ajResourceallDel((AjPResourceall*)PPval);
35866 
35867     return;
35868 }
35869 
35870 
35871 
35872 
35873 /* @funcstatic acdDelSeq ******************************************************
35874 **
35875 ** Function with void** prototype to delete ACD sequence data
35876 **
35877 ** @param [d] PPval [void**] Value to be deleted
35878 ** @return [void]
35879 **
35880 ** @release 4.0.0
35881 ******************************************************************************/
35882 
acdDelSeq(void ** PPval)35883 static void acdDelSeq(void** PPval)
35884 {
35885     if(!*PPval)
35886         return;
35887 
35888     ajSeqDel((AjPSeq*)PPval);
35889 
35890     return;
35891 }
35892 
35893 
35894 
35895 
35896 /* @funcstatic acdDelSeqall ***************************************************
35897 **
35898 ** Function with void** prototype to delete ACD sequence stream data
35899 **
35900 ** @param [d] PPval [void**] Value to be deleted
35901 ** @return [void]
35902 **
35903 ** @release 4.0.0
35904 ******************************************************************************/
35905 
acdDelSeqall(void ** PPval)35906 static void acdDelSeqall(void** PPval)
35907 {
35908     if(!*PPval)
35909         return;
35910 
35911     ajSeqallDel((AjPSeqall*)PPval);
35912 
35913     return;
35914 }
35915 
35916 
35917 
35918 
35919 /* @funcstatic acdDelSeqout ***************************************************
35920 **
35921 ** Function with void** prototype to delete ACD sequence output data
35922 **
35923 ** @param [d] PPval [void**] Value to be deleted
35924 ** @return [void]
35925 **
35926 ** @release 4.0.0
35927 ******************************************************************************/
35928 
acdDelSeqout(void ** PPval)35929 static void acdDelSeqout(void** PPval)
35930 {
35931     if(!*PPval)
35932         return;
35933 
35934     ajSeqoutDel((AjPSeqout*)PPval);
35935 
35936     return;
35937 }
35938 
35939 
35940 
35941 
35942 /* @funcstatic acdDelSeqset ***************************************************
35943 **
35944 ** Function with void** prototype to delete ACD sequence set data
35945 **
35946 ** @param [d] PPval [void**] Value to be deleted
35947 ** @return [void]
35948 **
35949 ** @release 4.0.0
35950 ******************************************************************************/
35951 
acdDelSeqset(void ** PPval)35952 static void acdDelSeqset(void** PPval)
35953 {
35954     if(!*PPval)
35955         return;
35956 
35957     ajSeqsetDel((AjPSeqset*)PPval);
35958 
35959     return;
35960 }
35961 
35962 
35963 
35964 
35965 /* @funcstatic acdDelSeqsetArray **********************************************
35966 **
35967 ** Function with void** prototype to delete ACD sequence sets data
35968 **
35969 ** @param [d] PPval [void**] Value to be deleted
35970 ** @return [void]
35971 **
35972 ** @release 4.0.0
35973 ******************************************************************************/
35974 
acdDelSeqsetArray(void ** PPval)35975 static void acdDelSeqsetArray(void** PPval)
35976 {
35977     if(!*PPval)
35978         return;
35979 
35980     ajSeqsetDelarray((AjPSeqset**)PPval);
35981 
35982     return;
35983 }
35984 
35985 
35986 
35987 
35988 /* @funcstatic acdDelStr ******************************************************
35989 **
35990 ** Function with void** prototype to delete ACD string data
35991 **
35992 ** @param [d] PPval [void**] Value to be deleted
35993 ** @return [void]
35994 **
35995 ** @release 4.0.0
35996 ******************************************************************************/
35997 
acdDelStr(void ** PPval)35998 static void acdDelStr(void** PPval)
35999 {
36000     if(!*PPval)
36001         return;
36002 
36003     ajStrDel((AjPStr*)PPval);
36004 
36005     return;
36006 }
36007 
36008 
36009 
36010 
36011 /* @funcstatic acdDelStrArray *************************************************
36012 **
36013 ** Function with void** prototype to delete ACD string array data
36014 **
36015 ** @param [d] PPval [void**] Value to be deleted
36016 ** @return [void]
36017 **
36018 ** @release 4.0.0
36019 ******************************************************************************/
36020 
acdDelStrArray(void ** PPval)36021 static void acdDelStrArray(void** PPval)
36022 {
36023     if(!*PPval)
36024         return;
36025 
36026     ajStrDelarray((AjPStr**)PPval);
36027 
36028     return;
36029 }
36030 
36031 
36032 
36033 
36034 /* @funcstatic acdDelTaxon ****************************************************
36035 **
36036 ** Function with void** prototype to delete ACD taxonomy input data
36037 **
36038 ** @param [d] PPval [void**] Value to be deleted
36039 ** @return [void]
36040 **
36041 ** @release 6.4.0
36042 ******************************************************************************/
36043 
acdDelTaxon(void ** PPval)36044 static void acdDelTaxon(void** PPval)
36045 {
36046     if(!*PPval)
36047         return;
36048 
36049     ajTaxallDel((AjPTaxall*)PPval);
36050 
36051     return;
36052 }
36053 
36054 
36055 
36056 
36057 /* @funcstatic acdDelText *****************************************************
36058 **
36059 ** Function with void** prototype to delete ACD text input data
36060 **
36061 ** @param [d] PPval [void**] Value to be deleted
36062 ** @return [void]
36063 **
36064 ** @release 6.4.0
36065 ******************************************************************************/
36066 
acdDelText(void ** PPval)36067 static void acdDelText(void** PPval)
36068 {
36069     if(!*PPval)
36070         return;
36071 
36072     ajTextallDel((AjPTextall*)PPval);
36073 
36074     return;
36075 }
36076 
36077 
36078 
36079 
36080 /* @funcstatic acdDelUrl ******************************************************
36081 **
36082 ** Function with void** prototype to delete ACD URL input data
36083 **
36084 ** @param [d] PPval [void**] Value to be deleted
36085 ** @return [void]
36086 **
36087 ** @release 6.4.0
36088 ******************************************************************************/
36089 
acdDelUrl(void ** PPval)36090 static void acdDelUrl(void** PPval)
36091 {
36092     if(!*PPval)
36093         return;
36094 
36095     ajUrlallDel((AjPUrlall*)PPval);
36096 
36097     return;
36098 }
36099 
36100 
36101 
36102 
36103 /* @funcstatic acdDelVariation ************************************************
36104 **
36105 ** Function with void** prototype to delete ACD variation input data
36106 **
36107 ** @param [d] PPval [void**] Value to be deleted
36108 ** @return [void]
36109 **
36110 ** @release 6.4.0
36111 ******************************************************************************/
36112 
acdDelVariation(void ** PPval)36113 static void acdDelVariation(void** PPval)
36114 {
36115     if(!*PPval)
36116         return;
36117 
36118     ajVarloadDel((AjPVarload*)PPval);
36119 
36120     return;
36121 }
36122 
36123 
36124 
36125 
36126 /* @funcstatic acdDelXml ******************************************************
36127 **
36128 ** Function with void** prototype to delete ACD xml input data
36129 **
36130 ** @param [d] PPval [void**] Value to be deleted
36131 ** @return [void]
36132 **
36133 ** @release 6.6.0
36134 **
36135 ******************************************************************************/
36136 
acdDelXml(void ** PPval)36137 static void acdDelXml(void** PPval)
36138 {
36139     if(!*PPval)
36140         return;
36141 
36142     ajXmlallDel((AjPXmlall*)PPval);
36143 
36144     return;
36145 }
36146 
36147 
36148 
36149 
36150 /* @funcstatic acdFree ********************************************************
36151 **
36152 ** Function to delete ACD data using the standard free function
36153 **
36154 ** @param [d] PPval [void**] Value to be deleted
36155 ** @return [void]
36156 **
36157 ** @release 4.0.0
36158 ******************************************************************************/
36159 
acdFree(void ** PPval)36160 static void acdFree(void** PPval)
36161 {
36162     if(!*PPval)
36163         return;
36164 
36165     AJFREE(*PPval);
36166 
36167     return;
36168 }
36169 
36170 
36171 
36172 
36173 /* @section unused ************************************************************
36174 **
36175 ** @fdata [none]
36176 **
36177 ** @nam3rule Unused Contains dummy calls to unused functions to keep
36178 **                 compilers happy
36179 **
36180 ** @valrule * [void]
36181 ** @fcategory misc
36182 **
36183 ******************************************************************************/
36184 
36185 
36186 
36187 
36188 /* @func ajAcdUnused **********************************************************
36189 **
36190 ** Dummy function to catch all unused functions defined in the ajacd
36191 ** source file.
36192 **
36193 ** @return [void]
36194 **
36195 **
36196 ** @release 4.0.0
36197 ******************************************************************************/
36198 
ajAcdUnused(void)36199 void ajAcdUnused(void)
36200 {
36201     AjPStr ajpstr=NULL;
36202     AcdPAcd acdpacd=NULL;
36203     float f=0.0;
36204     char c;
36205 
36206     acdSetXxxx(acdpacd);	    /* template function for acdSet */
36207     acdAttrToChar(acdpacd, "attr", '.', &c);
36208     acdQualToFloat(acdpacd, "", 0.0, 0, &f, &ajpstr);
36209     acdCountType("outfile");
36210     acdPrintUsed();
36211 
36212     return;
36213 }
36214 
36215 
36216 
36217 
36218 /* @section deprecated ********************************************************
36219 **
36220 ** @fdata [none]
36221 ** @fcategory misc
36222 **
36223 ** @nam3rule Graphics Graphics application
36224 ** @suffix P Package name given
36225 ** @suffix V Package version given
36226 **
36227 ** @argrule Graphics pgm [const char*] Program name
36228 ** @argrule Graphics argc [ajint] Number of arguments
36229 ** @argrule Graphics argv [char* const[]] Command line arguments
36230 ** @argrule P package [const char*] Package name
36231 ** @argrule V packversion [const char*] Package version
36232 **
36233 ** @valrule * [void]
36234 ******************************************************************************/
36235 
36236 
36237 
36238 
36239 /* @funcstatic acdRangeTestCalc ***********************************************
36240 **
36241 ** Tests for calculated minimum and maximum attributes. If found, requires
36242 ** other attributes to be defined to control the bahviour if the range
36243 ** is impossible in the current case
36244 **
36245 ** @param [r] thys [const AcdPAcd] Acd object
36246 ** @return [AjBool] True if a calculated value was found
36247 **
36248 **
36249 ** @release 6.3.0
36250 ******************************************************************************/
36251 
acdRangeTestCalc(const AcdPAcd thys)36252 static AjBool acdRangeTestCalc(const AcdPAcd thys)
36253 {
36254     const AjPStr tmpstr;
36255     AjBool toggle = ajFalse;
36256     AjBool iscalcmin = ajFalse;
36257     AjBool iscalcmax = ajFalse;
36258     AjBool iscalc = ajFalse;
36259     AjBool failrange = ajFalse;
36260     AjBool truemin = ajFalse;
36261 
36262     tmpstr = acdAttrValue(thys, "minimum");
36263     if(!MAJSTRGETLEN(tmpstr))
36264         return ajFalse;
36265 
36266     if(acdVarTestValid(tmpstr, &toggle))
36267         iscalcmin = ajTrue;
36268 
36269     tmpstr = acdAttrValue(thys, "maximum");
36270     if(!MAJSTRGETLEN(tmpstr))
36271         return ajFalse;
36272 
36273     if(acdVarTestValid(tmpstr, &toggle))
36274         iscalcmax = ajTrue;
36275 
36276     if(iscalcmin || iscalcmax)
36277     {
36278         iscalc = ajTrue;
36279         if(!acdAttrToBool(thys, "failrange", ajFalse, &failrange))
36280         {
36281             acdErrorAcd(thys,
36282                         "Attribute %s: required with any calculated min/max",
36283                         "failrange", acdType[thys->Type].Name);
36284         }
36285         else
36286         {
36287             if(failrange)
36288             {
36289                 tmpstr = acdAttrValue(thys, "rangemessage");
36290                 if(!tmpstr)
36291                     acdErrorAcd(thys,
36292                                 "Attribute %s: required for failrange: \"Y\"",
36293                                 "rangemessage", acdType[thys->Type].Name);
36294             }
36295             else
36296             {
36297                 if(!acdAttrToBool(thys, "trueminimum",ajFalse, &truemin))
36298                     acdErrorAcd(thys,
36299                                 "Attribute %s: required for failrange: \"N\"",
36300                                 "trueminimum", acdType[thys->Type].Name);
36301             }
36302 
36303         }
36304 
36305     }
36306 
36307     return iscalc;
36308 }
36309 
36310 
36311 
36312 
36313 /* @funcstatic acdRegVarDefine ************************************************
36314 **
36315 ** Define regular expressions for parsing variables and functions
36316 **
36317 ** @return [void]
36318 **
36319 ** @release 6.3.0
36320 ******************************************************************************/
36321 
acdRegVarDefine(void)36322 static void acdRegVarDefine(void)
36323 {
36324     if(!acdRegVarname)
36325 	acdRegVarname = ajRegCompC("^(.*)\\$\\(([a-zA-Z0-9_.]+)\\)");
36326 
36327     if(!acdRegToggle)
36328 	acdRegToggle = ajRegCompC("^(@\\([!])?(\\$\\([a-zA-Z0-9_.]+\\))\\)?$");
36329 
36330     if(!acdRegFunction)
36331         acdRegFunction = ajRegCompC("^(.*)\\@\\(([^()]+)\\)");
36332 
36333     return;
36334 }
36335 
36336 
36337 
36338 
36339 /* @section edam **************************************************************
36340 **
36341 ** @fdata [none]
36342 ** @fcategory misc
36343 **
36344 ** @nam2rule Acdedam EDAM parsing
36345 ** @nam3rule Parse Parse an ACD relation string
36346 ** @nam2rule Acdtype ACD type groups
36347 ** @nam3rule AcdtypeGet ACD type cast
36348 ** @nam4rule AcdtypeGetGroup Return ACD type group classification
36349 **
36350 ** @argrule Parse  relation [const AjPStr] Relation single attribute value
36351 ** @argrule Parse  id [AjPStr*] EDAM term numeric id
36352 ** @argrule Parse  namespace [AjPStr*] EDAM term namespace
36353 ** @argrule Parse  name [AjPStr*] EDAM term name
36354 ** @argrule Get    type [const AjPStr] ACD type name
36355 **
36356 ** @valrule *Parse [AjBool] True on success
36357 ** @valrule *Get [const char*] Group name
36358 ******************************************************************************/
36359 
36360 
36361 
36362 
36363 /* @funcstatic acdEdamTest ****************************************************
36364 **
36365 ** Test an EDAM term from a relations attribute
36366 **
36367 ** @param [r] relation [const AjPStr] Relation single attribute value
36368 ** @return [const AjPStr] Namespace
36369 **
36370 ** @release 6.3.0
36371 ******************************************************************************/
36372 
acdEdamTest(const AjPStr relation)36373 static const AjPStr acdEdamTest(const AjPStr relation)
36374 {
36375     AjPStr term = NULL;
36376     AjPStr name = NULL;
36377     AjPStr id = NULL;
36378     AjPStrTok handle = NULL;
36379     AjPStr token = NULL;
36380     AjPStr namespace = NULL;
36381     AjPObo oboterm = NULL;
36382     AjPObo obonameterm = NULL;
36383     AjPStr namequery = NULL;
36384     AjBool obonamefound = ajFalse;
36385 
36386     if(!acdEdam)
36387         return NULL;
36388 
36389     if(!ajStrPrefixC(relation, "EDAM"))
36390     {
36391         ajFmtPrintS(&namequery, "data:%S", relation);
36392         obonameterm = ajObodataFetchName(acdEdam, namequery);
36393         if(obonameterm)
36394         {
36395             obonamefound = ajTrue;
36396             acdErrorValid("Relation '%S' matches EDAM term EDAM_data:%S %S",
36397                           relation, oboterm->Namespace, oboterm->Id);
36398         }
36399 
36400         ajFmtPrintS(&namequery, "topic:%S", relation);
36401         obonameterm = ajObodataFetchName(acdEdam, namequery);
36402         if(obonameterm)
36403         {
36404             obonamefound = ajTrue;
36405             acdErrorValid("Relation '%S' matches EDAM term EDAM_topic:%S %S",
36406                           relation, oboterm->Id, oboterm->Namespace);
36407         }
36408 
36409         ajFmtPrintS(&namequery, "operation:%S", relation);
36410         obonameterm = ajObodataFetchName(acdEdam, namequery);
36411         if(obonameterm)
36412         {
36413             obonamefound = ajTrue;
36414             acdErrorValid("Relation '%S' matches EDAM term EDAM_operation:%S %S",
36415                           relation, oboterm->Id, oboterm->Namespace);
36416         }
36417 
36418         if(!obonamefound)
36419             acdErrorValid("Not an EDAM term in relation '%S'", relation);
36420 
36421         return NULL;
36422     }
36423 
36424     ajStrExtractFirst(relation, &name, &term);
36425 
36426     handle = ajStrTokenNewC(term, ":");
36427     if(!ajStrTokenNextParse(handle, &namespace)) /* EDAM */
36428         acdErrorValid("Bad relation term '%S'", term);
36429     else if(!ajStrTokenNextParse(handle, &token)) /* ID */
36430         acdErrorValid("Bad relation term '%S'", term);
36431 
36432     if(ajStrPrefixC(namespace, "EDAM_"))
36433         ajStrCutStart(&namespace, 5);
36434 
36435     if(!ajStrGetLen(namespace))
36436         acdErrorValid("Bad relation no namespace");
36437 
36438     ajFmtPrintS(&id, "EDAM_%S:%S", namespace, token);
36439 
36440     oboterm =  ajObodataFetchId(acdEdam, id);
36441 
36442     if(!oboterm)
36443     {
36444         acdErrorValid("Unknown relation term '%S' fetch failed for '%S'",
36445                       term, id);
36446         return NULL;
36447     }
36448 
36449     if(ajOboIsObsolete(oboterm))
36450     {
36451         if(ajOboGetReplaced(oboterm))
36452         {
36453             obonameterm = ajObodataFetchId(acdEdam, ajOboGetReplaced(oboterm));
36454             if(obonameterm)
36455                 acdErrorValid("Relation term '%S' obsolete, "
36456                               "possible replacement %S %S %S",
36457                               term, ajOboGetReplaced(oboterm),
36458                               obonameterm->Namespace, obonameterm->Name);
36459             else
36460                 acdErrorValid("Relation term '%S' obsolete, "
36461                               "possible replacement '%S'",
36462                               term, ajOboGetReplaced(oboterm));
36463         }
36464         else
36465         {
36466                 acdErrorValid("Relation term '%S' obsolete",
36467                               term);
36468         }
36469     }
36470 
36471     if(!ajStrMatchS(id, oboterm->Id))
36472         acdErrorValid("Relation term '%S' bad id, expected '%S' (%S)",
36473                       term, oboterm->Id, id);
36474 
36475     if(!ajStrMatchS(name, oboterm->Name))
36476     {
36477         obonamefound = ajFalse;
36478 
36479         ajFmtPrintS(&namequery, "%S:%S", namespace, name);
36480         obonameterm = ajObodataFetchName(acdEdam, namequery);
36481         if(obonameterm)
36482         {
36483             obonamefound = ajTrue;
36484             if(ajStrMatchS(id, obonameterm->Id))
36485                 acdErrorValid("Relation term '%S' bad name, expected '%S' "
36486                               "but matches synonym",
36487                               term, oboterm->Name);
36488             else
36489                 acdErrorValid("Relation term '%S' bad name, expected '%S' "
36490                               "but matches name for %S %S %S",
36491                               term, oboterm->Name,
36492                               obonameterm->Id, obonameterm->Namespace,
36493                               obonameterm->Name);
36494         }
36495 
36496         if(!ajStrMatchC(namespace, "topic")){
36497             ajFmtPrintS(&namequery, "topic:%S", name);
36498             obonameterm = ajObodataFetchName(acdEdam, namequery);
36499             if(obonameterm)
36500             {
36501                 obonamefound = ajTrue;
36502                 acdErrorValid("Relation term '%S' bad name, expected '%S' "
36503                               "but matches name for %S %S %S",
36504                               term, oboterm->Name,
36505                               obonameterm->Id, obonameterm->Namespace,
36506                               obonameterm->Name);
36507             }
36508         }
36509 
36510         if(!ajStrMatchC(namespace, "operation")){
36511             ajFmtPrintS(&namequery, "operation:%S", name);
36512             obonameterm = ajObodataFetchName(acdEdam, namequery);
36513             if(obonameterm)
36514             {
36515                 obonamefound = ajTrue;
36516                 acdErrorValid("Relation term '%S' bad name, expected '%S' "
36517                               "but matches name for %S %S %S",
36518                               term, oboterm->Name,
36519                               obonameterm->Id, obonameterm->Namespace,
36520                               obonameterm->Name);
36521             }
36522         }
36523 
36524         if(!obonamefound)
36525             acdErrorValid("Relation term '%S' bad name, expected '%S'",
36526                     term, oboterm->Name);
36527     }
36528 
36529     if(!ajStrMatchS(namespace, oboterm->Namespace))
36530         acdErrorValid("Relation term '%S' bad namespace, expected '%S'",
36531                     term, oboterm->Namespace);
36532 
36533     return oboterm->Namespace;
36534 }
36535 
36536 
36537 
36538 
36539 /* @func ajAcdedamParse *******************************************************
36540 **
36541 ** Parse an EDAM term from a relations attribute
36542 **
36543 ** @param [r] relation [const AjPStr] Relation single attribute value
36544 ** @param [w] id [AjPStr*] EDAM term numeric id
36545 ** @param [w] namespace [AjPStr*] EDAM term namespace
36546 ** @param [w] name [AjPStr*] EDAM term name
36547 ** @return [AjBool] True on success
36548 **
36549 **
36550 ** @release 6.4.0
36551 ******************************************************************************/
36552 
ajAcdedamParse(const AjPStr relation,AjPStr * id,AjPStr * namespace,AjPStr * name)36553 AjBool ajAcdedamParse(const AjPStr relation, AjPStr* id,
36554                       AjPStr* namespace, AjPStr* name)
36555 {
36556     AjPStr token = NULL;
36557     AjPStr term = NULL;
36558     AjPStr rest = NULL;
36559     AjPStrTok handle = NULL;
36560 
36561     if(!ajStrPrefixC(relation, "EDAM_"))
36562         return ajFalse;
36563 
36564     ajStrExtractFirst(relation, &rest, &term);
36565 
36566     handle = ajStrTokenNewC(term, ":_");
36567     if(!ajStrTokenNextParse(handle, &token)) /* EDAM */
36568         return ajFalse;
36569     else if(!ajStrTokenNextParse(handle, namespace)) /* namespace */
36570         return ajFalse;
36571     else if(!ajStrTokenNextParse(handle, id)) /* ID */
36572     {
36573         ajStrSetClear(namespace);
36574         return ajFalse;
36575     }
36576 
36577     ajStrAssignS(name, rest);
36578 
36579     ajStrDel(&token);
36580     ajStrDel(&term);
36581     ajStrDel(&rest);
36582     ajStrTokenDel(&handle);
36583 
36584     return ajTrue;
36585 }
36586 
36587 
36588 
36589 
36590 /* @func ajAcdtypeGetGroup ****************************************************
36591 **
36592 ** Return the ACD group for an ACD datatype
36593 **
36594 ** @param [r] type [const AjPStr] ACD type name
36595 ** @return [const char*] Group name
36596 **
36597 **
36598 ** @release 6.4.0
36599 ******************************************************************************/
36600 
ajAcdtypeGetGroup(const AjPStr type)36601 const char* ajAcdtypeGetGroup(const AjPStr type)
36602 {
36603     ajuint i;
36604 
36605     i =  0;
36606     while(acdType[i].Name)		/* ACD types as qualifiers */
36607     {
36608         if(ajStrMatchC(type, acdType[i].Name))
36609             return acdType[i].Group;
36610         i++;
36611     }
36612 
36613     return NULL;
36614 }
36615 
36616 
36617 
36618 
36619 #ifdef AJ_COMPILE_DEPRECATED_BOOK
36620 #endif
36621 #ifdef AJ_COMPILE_DEPRECATED
36622 static AjBool    acdTestDebugIsSet(void);
36623 static AjBool    acdTestDebug(void);
36624 static AjBool    acdTestFilter(void);
36625 static AjBool    acdTestStdout(void);
36626 #endif
36627 
36628 
36629 
36630 
36631 #ifdef AJ_COMPILE_DEPRECATED
36632 /* @funcstatic acdTestDebugIsSet **********************************************
36633 **
36634 ** Tests whether the command line switch for debug messages has been set
36635 ** by testing internal variable 'acdDebugSet'
36636 **
36637 ** @return [AjBool] Debugging status.
36638 **
36639 ** @release 4.0.0
36640 ** @@
36641 ******************************************************************************/
36642 
acdTestDebugIsSet(void)36643 static AjBool acdTestDebugIsSet(void)
36644 {
36645     ajDebug("acdTestDebugIsSet returning %B\n", acdDebugSet);
36646     return acdDebugSet;
36647 }
36648 
36649 
36650 
36651 
36652 /* @funcstatic acdTestDebug ***************************************************
36653 **
36654 ** Tests whether debug messages are required by checking
36655 ** internal variable 'acdDebug'
36656 **
36657 ** @return [AjBool] Debugging status.
36658 **
36659 ** @release 4.0.0
36660 ** @@
36661 ******************************************************************************/
36662 
acdTestDebug(void)36663 static AjBool acdTestDebug(void)
36664 {
36665     ajDebug("acdDebug returning %B\n", acdDebug);
36666     return acdDebug;
36667 }
36668 
36669 
36670 
36671 
36672 /* @funcstatic acdTestFilter **************************************************
36673 **
36674 ** Tests whether input and output use stdin and stdout as a filter
36675 ** by returning internal variable 'acdFilter'
36676 **
36677 ** @return [AjBool] Filter status.
36678 **
36679 ** @release 4.0.0
36680 ** @@
36681 ******************************************************************************/
36682 
acdTestFilter(void)36683 static AjBool acdTestFilter(void)
36684 {
36685     return acdFilter;
36686 }
36687 
36688 
36689 
36690 
36691 /* @funcstatic acdTestStdout **************************************************
36692 **
36693 ** Tests whether output uses stdout for output by default
36694 ** by returning internal variable 'acdStdout'
36695 **
36696 ** @return [AjBool] Stdout status.
36697 **
36698 ** @release 4.0.0
36699 ** @@
36700 ******************************************************************************/
36701 
acdTestStdout(void)36702 static AjBool acdTestStdout(void)
36703 {
36704     return acdStdout;
36705 }
36706 
36707 
36708 
36709 
36710 /* @obsolete ajAcdGetDiscretestatesI
36711 ** @replace ajAcdGetDiscretestatesSingle (1,2/1)
36712 */
36713 
ajAcdGetDiscretestatesI(const char * token,ajint num)36714 __deprecated AjPPhyloState  ajAcdGetDiscretestatesI(const char *token,
36715 						   ajint num)
36716 {
36717     AjPPhyloState* val;
36718     ajint i;
36719 
36720     val = acdGetValue(token, "discretestates");
36721     for(i=0; val[i]; i++)
36722 	continue;
36723 
36724     if(num > i)
36725 	ajWarn("value %d not found for %s, last value was %d",
36726 	       num, token, i-1);
36727 
36728     return val[num-1];
36729 }
36730 
36731 
36732 
36733 
36734 /* @obsolete ajAcdGetFeat
36735 ** @rename ajAcdGetFeatures
36736 */
36737 
ajAcdGetFeat(const char * token)36738 __deprecated AjPFeattable ajAcdGetFeat(const char *token)
36739 {
36740     return ajAcdGetFeatures(token);
36741 }
36742 
36743 
36744 
36745 
36746 /* @obsolete ajAcdGetListI
36747 ** @replace ajAcdGetListSingle (1,2/1)
36748 */
36749 
ajAcdGetListI(const char * token,ajint num)36750 __deprecated AjPStr  ajAcdGetListI(const char *token, ajint num)
36751 {
36752     AjPStr *val;
36753     ajint i;
36754 
36755     val = acdGetValue(token, "list");
36756 
36757     for(i=0; val[i]; i++)
36758 	continue;
36759 
36760     if(num > i)
36761 	ajWarn("value %d not found for %s, last value was %d",
36762 	       num, token, i-1);
36763 
36764     return val[num-1];
36765 }
36766 
36767 
36768 
36769 
36770 /* @obsolete ajAcdGetSelectI
36771 ** @replace ajAcdGetSelectSingle (1,2/1)
36772 */
36773 
ajAcdGetSelectI(const char * token,ajint num)36774 __deprecated AjPStr  ajAcdGetSelectI(const char *token, ajint num)
36775 {
36776     AjPStr* val;
36777     ajint i;
36778 
36779     val =  acdGetValue(token, "select");
36780 
36781     for(i=0; val[i]; i++)
36782 	continue;
36783 
36784     if(num > i)
36785 	ajWarn("value %d not found for %s, last value was %d",
36786 	       num, token, i-1);
36787 
36788     return val[num-1];
36789 }
36790 
36791 
36792 
36793 
36794 /* @obsolete ajAcdGetSeqsetallI
36795 ** @replace ajAcdGetSeqsetallSingle (1,2/1)
36796 */
36797 
ajAcdGetSeqsetallI(const char * token,ajint num)36798 __deprecated AjPSeqset  ajAcdGetSeqsetallI(const char *token, ajint num)
36799 {
36800     AjPSeqset *val;
36801     ajint i;
36802 
36803     val = acdGetValue(token, "seqsetall");
36804 
36805     for(i=0; val[i]; i++)
36806 	continue;
36807 
36808     if(num > i)
36809 	ajWarn("value %d not found for %s, last value was %d",
36810 	       num, token, i-1);
36811 
36812     return val[num-1];
36813 }
36814 
36815 
36816 
36817 
36818 /* @obsolete ajAcdGetTreeI
36819 ** @replace ajAcdGetTreeSingle (1,2/1)
36820 */
36821 
ajAcdGetTreeI(const char * token,ajint num)36822 __deprecated AjPPhyloTree  ajAcdGetTreeI(const char *token, ajint num)
36823 {
36824     AjPPhyloTree *val;
36825     ajint i;
36826 
36827     val = acdGetValue(token, "tree");
36828 
36829     for(i=0; val[i]; i++)
36830 	continue;
36831 
36832     if(num > i)
36833 	ajWarn("value %d not found for %s, last value was %d",
36834 	       num, token, i-1);
36835 
36836     return val[num-1];
36837 }
36838 
36839 
36840 
36841 
36842 /* @obsolete ajAcdValue
36843 ** @rename ajAcdGetValue
36844 */
36845 
ajAcdValue(const char * token)36846 __deprecated const AjPStr  ajAcdValue(const char *token)
36847 {
36848     return ajAcdGetValue(token);
36849 }
36850 
36851 
36852 
36853 
36854 /* @obsolete ajAcdIsUserdefined
36855 ** @rename ajAcdIsUserdefinedC
36856 */
ajAcdIsUserdefined(const char * token)36857 __deprecated AjBool ajAcdIsUserdefined(const char *token)
36858 {
36859     return ajAcdIsUserdefinedC(token);
36860 }
36861 
36862 
36863 
36864 
36865 /* @obsolete ajAcdDebug
36866 ** @remove No longer public
36867 */
36868 
ajAcdDebug(void)36869 __deprecated AjBool  ajAcdDebug(void)
36870 {
36871     return acdTestDebug();
36872 }
36873 
36874 
36875 
36876 
36877 /* @obsolete ajAcdDebugIsSet
36878 ** @remove No longer public
36879 */
36880 
ajAcdDebugIsSet(void)36881 __deprecated AjBool  ajAcdDebugIsSet(void)
36882 {
36883     return acdTestDebugIsSet();
36884 }
36885 
36886 
36887 
36888 
36889 /* @obsolete ajAcdStdout
36890 ** @remove No longer public
36891 */
36892 
ajAcdStdout(void)36893 __deprecated AjBool  ajAcdStdout(void)
36894 {
36895     return acdTestStdout();
36896 }
36897 
36898 
36899 
36900 
36901 /* @obsolete ajGraphicsInit
36902 ** @rename ajAcdGraphicsInit
36903 */
ajGraphicsInit(const char * pgm,ajint argc,char * const argv[])36904 __deprecated void ajGraphicsInit(const char *pgm,
36905 				 ajint argc, char * const argv[])
36906 {
36907     ajAcdGraphicsInit(pgm, argc, argv);
36908     return;
36909 }
36910 
36911 
36912 
36913 
36914 /* @obsolete ajGraphInit
36915 ** @rename ajAcdGraphicsInit
36916 */
36917 
ajGraphInit(const char * pgm,ajint argc,char * const argv[])36918 __deprecated void ajGraphInit(const char *pgm, ajint argc, char * const argv[])
36919 {
36920     ajAcdGraphicsInit(pgm, argc, argv);
36921     return;
36922 }
36923 
36924 
36925 
36926 
36927 /* @obsolete ajGraphicsInitPV
36928 ** @rename ajAcdGraphicsInitPV
36929 */
36930 
ajGraphicsInitPV(const char * pgm,ajint argc,char * const argv[],const char * package,const char * packversion)36931 __deprecated void ajGraphicsInitPV(const char *pgm,
36932 				   ajint argc, char *const argv[],
36933 				   const char *package,
36934 				   const char *packversion)
36935 {
36936     ajAcdGraphicsInitPV(pgm, argc, argv, package, packversion);
36937     return;
36938 }
36939 
36940 
36941 
36942 
36943 /* @obsolete ajGraphInitPV
36944 ** @rename ajAcdGraphicsInitPV
36945 */
36946 
ajGraphInitPV(const char * pgm,ajint argc,char * const argv[],const char * package,const char * packversion)36947 __deprecated void ajGraphInitPV(const char *pgm, ajint argc, char *const argv[],
36948                                 const char *package,const char *packversion)
36949 {
36950     ajAcdGraphicsInitPV(pgm, argc, argv, package, packversion);
36951     return;
36952 }
36953 
36954 
36955 
36956 
36957 /* @obsolete ajAcdGetBool
36958 ** @rename ajAcdGetBoolean
36959 */
36960 
ajAcdGetBool(const char * token)36961 __deprecated AjBool ajAcdGetBool(const char *token)
36962 {
36963     return ajAcdGetBoolean(token);
36964 }
36965 
36966 
36967 
36968 
36969 /*
36970 ** @obsolete ajAcdGraphicsInit
36971 ** @rename embInit
36972 */
36973 
ajAcdGraphicsInit(const char * pgm,ajint argc,char * const argv[])36974 __deprecated void ajAcdGraphicsInit(const char *pgm,
36975                                     ajint argc, char * const argv[])
36976 {
36977     ajSeqdbInit();
36978     ajNamInit("emboss");
36979     ajAcdInit(pgm, argc, argv);
36980 
36981     return;
36982 }
36983 
36984 
36985 
36986 
36987 /*
36988 ** @obsolete ajAcdGraphicsInitPV
36989 ** @rename embInitPV
36990 */
36991 
ajAcdGraphicsInitPV(const char * pgm,ajint argc,char * const argv[],const char * package,const char * packversion)36992 __deprecated void ajAcdGraphicsInitPV(const char *pgm,
36993                                       ajint argc, char *const argv[],
36994                                       const char *package,
36995                                       const char *packversion)
36996 {
36997     ajSeqdbInit();
36998     ajNamInit("emboss");
36999     ajAcdInitPV(pgm, argc, argv,package, packversion);
37000 
37001     return;
37002 }
37003 #endif
37004