1 /* @source ajnam **************************************************************
2 **
3 ** AJAX nam functions
4 **
5 ** Creates a hash table of initial values and allow access to this
6 ** via the routines ajNamDatabase and ajNamGetValueS.
7 **
8 ** @author Copyright (C) 1998 Ian Longden
9 ** @version $Revision: 1.190 $
10 ** @modified 2000-2011 Peter Rice
11 ** @modified $Date: 2013/01/24 15:31:46 $ by $Author: rice $
12 ** @@
13 **
14 ** This library is free software; you can redistribute it and/or
15 ** modify it under the terms of the GNU Lesser General Public
16 ** License as published by the Free Software Foundation; either
17 ** version 2.1 of the License, or (at your option) any later version.
18 **
19 ** This library is distributed in the hope that it will be useful,
20 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 ** Lesser General Public License for more details.
23 **
24 ** You should have received a copy of the GNU Lesser General Public
25 ** License along with this library; if not, write to the Free Software
26 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 ** MA 02110-1301, USA.
28 **
29 ******************************************************************************/
30
31 #include "ajlib.h"
32
33 #include "ajnam.h"
34 #include "ajsys.h"
35 #include "ajfileio.h"
36 #include "ajquery.h"
37 #include "ajreg.h"
38 #include "ajtagval.h"
39 #include "ajassemread.h"
40 #include "ajfeatread.h"
41 #include "ajoboread.h"
42 #include "ajrefseqread.h"
43 #include "ajresourceread.h"
44 #include "ajseqread.h"
45 #include "ajtaxread.h"
46 #include "ajtextread.h"
47 #include "ajurlread.h"
48 #include "ajvarread.h"
49 #include "ajxmlread.h"
50
51 #ifndef WIN32
52 #include <dirent.h>
53 #include <unistd.h>
54 #else /* !WIN32 */
55 #include "win32.h"
56 #include <winsock2.h>
57 #include <stdlib.h>
58 #endif /* WIN32 */
59
60 #ifdef HAVE_MCHECK
61 #include <mcheck.h>
62 #endif /* ! HAVE_MCHECK */
63
64
65 enum NamEType
66 {
67 TYPE_UNKNOWN, /* no type set */
68 TYPE_ENV, /* env or set variable */
69 TYPE_SVR, /* server definition */
70 TYPE_DB, /* database definition */
71 TYPE_RESOURCE, /* resource definition */
72 TYPE_IFILE, /* include filename */
73 TYPE_ALIAS, /* database alias */
74 TYPE_SVRDB, /* server:database table */
75 TYPE_SVRALI, /* server:alias table */
76 TYPE_IF,
77 TYPE_IFDEF,
78 TYPE_ELSE,
79 TYPE_ENDIF,
80 TYPE_MAX
81 };
82
83 enum NamEAttrtype
84 {
85 ATTR_UNKNOWN, /* no type set */
86 ATTR_STR, /* string */
87 ATTR_BOOL, /* boolean */
88 ATTR_LIST, /* list of strings */
89 };
90
91 const char* namTypes[] = { "unknown", "SET",
92 "SERVER", "DBNAME", "RESOURCE",
93 "INCLUDE", "ALIAS",
94 "SERVER:DB", "SERVER:ALIAS",
95 "IF", "ELSE", "ENDIF",
96 "MAX"
97 };
98
99 #define NAM_INCLUDE_ESTIMATE 5 /* estimate of maximum number of include */
100 /* statements in emboss.default */
101
102 /* Scope values for entry methods returned from name*Method2Scope */
103 #define SLOW_ENTRY 8
104 #define SLOW_QUERY 16
105
106 static AjBool namDoDebug = AJFALSE;
107 static AjBool namDoValid = AJFALSE;
108 static AjBool namDoHomeRc = AJTRUE;
109 static AjPStr namRootStr = NULL;
110 static AjPStr namStandardFilename = NULL;
111 static AjPStr namStandardDir = NULL;
112 static AjPStr namUserDir = NULL;
113 static AjPStr namUserFilename = NULL;
114 static AjPStr namValNameTmp = NULL;
115
116 static AjBool namListParseOK = AJFALSE;
117
118 static ajuint namIfBlock = 0;
119 static AjBool namIfNow = AJTRUE;
120
121 static AjPList namIfList = NULL;
122 static AjBool *namIfValue;
123 static AjBool namTrue = AJTRUE;
124 static AjBool namFalse = AJFALSE;
125
126 /* source directory where control and data files can be found */
127
128 #ifdef AJAX_FIXED_ROOT
129 static char namFixedRoot[] = AJAX_FIXED_ROOT;
130 #else
131 static char namFixedRoot[] = "/nfs/WWW/data/EMBOSS";
132 #endif
133
134 /* install target directory where installed control and data files can
135 be found - this is the --prefix= from ./configure */
136
137 #ifdef PREFIX
138 static char namInstallRoot[] = PREFIX;
139 #else
140 #ifndef WIN32
141 static char namInstallRoot[] = "/usr/local";
142 #else
143 static char namInstallRoot[MAX_PATH];
144 #endif
145 #endif
146
147 /* package name from the makefile */
148
149 #ifdef PACKAGE
150 static char namPackage[] = PACKAGE;
151 #else
152 static char namPackage[] = "EMBOSS";
153 #endif
154
155 #ifdef VERSION
156 static char namVersion[] = VERSION;
157 #else
158 static char namVersion[] = "6.x.x";
159 #endif
160
161 #ifdef AJAX_SYSTEM
162 static char namSystem[] = AJAX_SYSTEM;
163 #else
164 #ifdef WIN32
165 static char namSystem[] = "windows";
166 #else
167 static char namSystem[] = "unknown";
168 #endif
169 #endif
170
171 /* string versions of char* constants set in ajNamInit */
172 static AjPStr namFixedBaseStr = NULL;
173 static AjPStr namFixedRootStr = NULL;
174 static AjPStr namFixedInstallStr = NULL;
175 static AjPStr namFixedPackageStr = NULL;
176 static AjPStr namFixedSystemStr = NULL;
177 static AjPStr namFixedVersionStr = NULL;
178 static AjPStr namPrefixStr = NULL;
179 static AjPStr namFileOrig = NULL;
180
181 static AjPTable namDbTypeTable = NULL;
182 static AjPTable namAliasMasterTable = NULL;
183 static AjPTable namVarMasterTable = NULL;
184 static AjPTable namSvrMasterTable = NULL;
185 static AjPTable namDbMasterTable = NULL;
186 static AjPTable namResMasterTable = NULL;
187 static AjPTable namSvrAttrTable = NULL;
188 static AjPTable namDbAttrTable = NULL;
189 static AjPTable namResAttrTable = NULL;
190 static AjPTable namSvrDatabaseTable = NULL;
191 static AjPTable namSvrAliasTable = NULL;
192 static ajint namParseType = 0;
193 static AjPStr namFileName = NULL;
194 static ajint namLine = 0;
195 static ajint namErrorCount = 0;
196
197 static AjPRegexp namNameExp = NULL;
198 static AjPRegexp namVarExp = NULL;
199
200
201 static AjPStr namCmpStr = NULL;
202
203 /* @datastatic NamPAttr *******************************************************
204 **
205 ** Resource attribute definition structure
206 **
207 ** @alias NamSAttr
208 ** @alias NamOAttr
209 **
210 ** @attr Name [const char*] Attribute name
211 ** @attr Type [enum NamEAttrtype] Type of value
212 ** @attr Defval [const char*] Default value, usually an empty string
213 ** @attr Comment [const char*] Comment for documentation purposes
214 ** @@
215 ******************************************************************************/
216
217 typedef struct NamSAttr
218 {
219 const char* Name;
220 enum NamEAttrtype Type;
221 const char* Defval;
222 const char* Comment;
223 } NamOAttr;
224
225 #define NamPAttr NamOAttr*
226
227
228
229
230 /* @datastatic NamPValid ******************************************************
231 **
232 ** Resource attribute validation structure
233 **
234 ** @alias NamSValid
235 ** @alias NamOValid
236 **
237 ** @attr Name [const char*] Attribute name
238 ** @attr Comment [const char*] Comment for documentation purposes
239 ** @@
240 ******************************************************************************/
241
242 typedef struct NamSValid
243 {
244 const char* Name;
245 const char* Comment;
246 } NamOValid;
247
248 #define NamPValid NamOValid*
249
250
251
252
253 /* @datastatic NamPType ******************************************************
254 **
255 ** Resource attribute validation structure
256 **
257 ** @alias NamSType
258 ** @alias NamOType
259 **
260 ** @attr Name [const char*] Type name
261 ** @attr Scope [const char*] Type scope
262 ** @attr Comment [const char*] Comment for documentation purposes
263 ** @attr DataType [ajuint] Enumerated datatype matching scope
264 ** @@
265 ******************************************************************************/
266
267 typedef struct NamSType
268 {
269 const char* Name;
270 const char* Scope;
271 const char* Comment;
272 ajuint DataType;
273 } NamOType;
274
275 #define NamPType NamOType*
276
277
278
279
280 NamOAttr namSvrAttrs[] =
281 {
282 {"method", ATTR_STR, "",
283 "access method (required, at some level)"},
284 {"type", ATTR_STR, "",
285 "database type(s) 'Nucleotide', 'Protein', etc (required)"},
286 {"cachedirectory", ATTR_STR, "",
287 "cache directory name"},
288 {"cachefile", ATTR_STR, "", "cache file name"},
289
290 {"accession", ATTR_STR, "",
291 "secondary identifier field"},
292 {"app", ATTR_STR, "",
293 "external application commandline (APP, EXTERNAL)"},
294 {"appall", ATTR_STR, "",
295 "external commandline for 'methodall' (APP, EXTERNAL)"},
296 {"appentry", ATTR_STR, "",
297 "external commandline for 'methodentry' (APP, EXTERNAL)"},
298 {"appquery", ATTR_STR, "",
299 "external commandline for 'methodquery' (APP, EXTERNAL)"},
300
301 {"caseidmatch", ATTR_BOOL, "N",
302 "match exact case of entry identifier"},
303 {"comment", ATTR_STR, "",
304 "text comment for the server definition"},
305 {"directory", ATTR_STR, "",
306 "data directory"},
307 /* {"exclude", ATTR_STR, "",
308 "wildcard filenames to exclude from 'filename'"},*/
309 {"field", ATTR_LIST, "",
310 "database query field, with altnames and description"},
311 {"filters", ATTR_STR, "",
312 "database query filters to apply to all retrievals"},
313 /* {"filename", "",
314 "(wildcard) database filename"},*/
315
316 {"format", ATTR_STR, "",
317 "database entry format(s)"},
318 {"formatall", ATTR_STR, "",
319 "database entry format(s) for 'methodall' access"},
320 {"formatentry", ATTR_STR, "",
321 "database entry format(s) for 'methodentry' access"},
322 {"formatquery", ATTR_STR, "",
323 "database query format(s) for 'methodquery' access"},
324
325 {"hasaccession", ATTR_BOOL, "Y",
326 "database has an acc field as an alternate id"},
327 {"httpversion", ATTR_STR, "",
328 "HTTP version for GET requests"},
329 {"identifier", ATTR_STR, "",
330 "standard identifier field"},
331 {"indexdirectory", ATTR_STR, "",
332 "Index directory, defaults to data 'directory'"},
333
334 {"methodall", ATTR_STR, "",
335 "access method for all entries"},
336 {"methodentry", ATTR_STR, "",
337 "access method for single entry"},
338 {"methodquery", ATTR_STR, "",
339 "access method for query (several entries)"},
340
341 {"proxy", ATTR_STR, "",
342 "http proxy server, or ':' to cancel a global proxy "},
343 {"query", ATTR_STR, "",
344 "database query (SQL, SPARQL, etc.)"},
345 /* {"release", ATTR_STR, "",
346 "release of the database, comment only"},*/
347 {"return", ATTR_STR, "",
348 "names fields to be returned"},
349 {"sequence", ATTR_STR, "",
350 "sequence field to be returned"},
351 {"serverversion", ATTR_STR, "",
352 "Version of database server"},
353 {"special", ATTR_LIST, "",
354 "name:value attributes for access method"},
355 {"url", ATTR_STR, "",
356 "Basic URL for data access"},
357 {"view", ATTR_STR, "",
358 "Access method view"},
359
360 {"edamdat", ATTR_LIST, "",
361 "EDAM datatype term references"},
362 {"edamfmt", ATTR_LIST, "",
363 "EDAM format term references"},
364 {"edamid", ATTR_LIST, "",
365 "EDAM identifier term references"},
366 {"edamtpc", ATTR_LIST, "",
367 "EDAM topic term references"},
368 {"taxon", ATTR_LIST, "",
369 "taxon id and name"},
370
371 {NULL, ATTR_UNKNOWN, NULL,
372 NULL}
373 };
374
375 NamOAttr namDbAttrs[] =
376 {
377 {"format", ATTR_STR, "",
378 "database entry format(s) (required, at some level)"},
379 {"method", ATTR_STR, "",
380 "access method (required, at some level)"},
381 {"type", ATTR_STR, "",
382 "database type(s) 'Nucleotide', 'Protein', etc (required)"},
383
384 {"accession", ATTR_STR, "",
385 "secondary identifier field"},
386 {"app", ATTR_STR, "",
387 "external application commandline (APP, EXTERNAL)"},
388 {"appall", ATTR_STR, "",
389 "external commandline for 'methodall' (APP, EXTERNAL)"},
390 {"appentry", ATTR_STR, "",
391 "external commandline for 'methodentry' (APP, EXTERNAL)"},
392 {"appquery", ATTR_STR, "",
393 "external commandline for 'methodquery' (APP, EXTERNAL)"},
394
395 {"caseidmatch", ATTR_BOOL, "N",
396 "match exact case of entry identifier"},
397 {"comment", ATTR_STR, "",
398 "text comment for the DB definition"},
399 {"dbalias", ATTR_STR, "",
400 "database name(s) to be used by access method if different"},
401 {"directory", ATTR_STR, "",
402 "data directory"},
403 {"example", ATTR_LIST, "",
404 "example identifier"},
405 {"exclude", ATTR_STR, "",
406 "wildcard filenames to exclude from 'filename'"},
407 {"field", ATTR_LIST, "",
408 "database query field, with altnames and description"},
409 {"fields", ATTR_STR, "",
410 "extra database query fields, ID and ACC are standard"},
411 {"filters", ATTR_STR, "",
412 "database query filters to apply to all retrievals"},
413 {"filename", ATTR_STR, "",
414 "(wildcard) database filename"},
415
416 {"formatall", ATTR_STR, "",
417 "database entry format(s) for 'methodall' access"},
418 {"formatentry", ATTR_STR, "",
419 "database entry format(s) for 'methodentry' access"},
420 {"formatquery", ATTR_STR, "",
421 "database query format(s) for 'methodquery' access"},
422
423 {"hasaccession", ATTR_BOOL, "Y",
424 "database has an acc field as an alternate id"},
425 {"httpversion", ATTR_STR, "", "HTTP version for GET requests"},
426 {"identifier", ATTR_STR, "", "standard identifier field"},
427 {"indexdirectory", ATTR_STR, "",
428 "Index directory, defaults to data 'directory'"},
429
430 {"methodall", ATTR_STR, "",
431 "access method for all entries"},
432 {"methodentry", ATTR_STR, "",
433 "access method for single entry"},
434 {"methodquery", ATTR_STR, "",
435 "access method for query (several entries)"},
436
437 {"namespace", ATTR_STR, "",
438 "namespace query to restrict ontology searches"},
439 {"organisms", ATTR_STR, "",
440 "organism/taxonomy query to restrict biological searches"},
441 {"proxy", ATTR_STR, "",
442 "http proxy server, or ':' to cancel a global proxy"},
443 {"query", ATTR_STR, "",
444 "database query (SQL, SPARQL, etc.)"},
445 {"release", ATTR_STR, "",
446 "release of the database, comment only"},
447 {"return", ATTR_STR, "",
448 "names of fields to be returned"},
449 {"sequence", ATTR_STR, "",
450 "sequence field to be returned"},
451 {"serverversion", ATTR_STR, "",
452 "version of database server"},
453 {"special", ATTR_LIST, "",
454 "name:value attributes for access method"},
455 {"url", ATTR_STR, "",
456 "Basic URL for data access"},
457 {"view", ATTR_STR, "",
458 "Access method view"},
459
460 {"edamdat", ATTR_LIST, "",
461 "EDAM datatype term references"},
462 {"edamfmt", ATTR_LIST, "",
463 "EDAM format term references"},
464 {"edamid", ATTR_LIST, "",
465 "EDAM identifier term references"},
466 {"edamtpc", ATTR_LIST, "",
467 "EDAM topic term references"},
468 {"taxon", ATTR_LIST, "",
469 "taxon id and name"},
470
471 {NULL, ATTR_UNKNOWN, NULL,
472 NULL}
473 };
474
475 NamOAttr namRsAttrs[] =
476 {
477 {"type", ATTR_STR, "",
478 "resource type (required)"},
479
480 /* {"identifier",ATTR_STR, "",
481 "standard identifier (defaults to name)"},*/
482 {"release", ATTR_STR, "",
483 "release of the resource"},
484 {"pagesize", ATTR_STR, "",
485 "default index pagesize"},
486 {"secpagesize", ATTR_STR, "",
487 "default index secondary pagesize"},
488 {"cachesize", ATTR_STR, "",
489 "default index cache size"},
490 {"seccachesize", ATTR_STR, "",
491 "default index secondary cache size"},
492
493 {"fields", ATTR_STR,
494 "id,acc,sv,key,des,org,nam,isa,xref",
495 "known database query fields"},
496
497 {"value", ATTR_STR, "",
498 "value appropriate to the resource type"},
499 {NULL, ATTR_UNKNOWN, NULL,
500 NULL}
501 };
502
503 NamOType namDbTypes[] =
504 {
505 {"N", "sequence",
506 "Nucleotide (obsolete short name)",
507 AJDATATYPE_SEQUENCE},
508 {"P", "sequence",
509 "Protein (obsolete short name)",
510 AJDATATYPE_SEQUENCE},
511 {"Nucleotide", "sequence",
512 "Nucleotide sequence data",
513 AJDATATYPE_SEQUENCE},
514 {"Protein", "sequence",
515 "Protein sequence data",
516 AJDATATYPE_SEQUENCE},
517 {"Sequence", "sequence",
518 "Both nucleotide and protein sequence data",
519 AJDATATYPE_SEQUENCE},
520 {"Nucfeatures", "features",
521 "Nucleotide features data",
522 AJDATATYPE_FEATURES},
523 {"Protfeatures", "features",
524 "Protein features data",
525 AJDATATYPE_FEATURES},
526 {"Features", "features",
527 "Both nucleotide and protein features data",
528 AJDATATYPE_FEATURES},
529 /* {"Pattern", "pattern",
530 "Pattern data"},*/
531 {"Assembly", "assembly",
532 "Assembly of sequence reads",
533 AJDATATYPE_ASSEMBLY},
534 {"Obo", "obo",
535 "OBO ontology",
536 AJDATATYPE_OBO},
537 {"Refseq", "refseq",
538 "Reference sequence",
539 AJDATATYPE_REFSEQ},
540 {"Resource" , "resource",
541 "Data resource data",
542 AJDATATYPE_RESOURCE},
543 {"Taxonomy", "taxon",
544 "NCBI taxonomy",
545 AJDATATYPE_TAXON},
546 {"Html", "text",
547 "HTML data",
548 AJDATATYPE_TEXT},
549 {"Text", "text",
550 "Text data",
551 AJDATATYPE_TEXT},
552 {"Url", "url",
553 "Url",
554 AJDATATYPE_URL},
555 {"Variation", "variation",
556 "Variation",
557 AJDATATYPE_VARIATION},
558 {"Xml", "xml",
559 "XML data",
560 AJDATATYPE_XML},
561 {"Unknown", "text",
562 "Unknown type",
563 AJDATATYPE_UNKNOWN},
564 {NULL, NULL,
565 NULL,
566 AJDATATYPE_UNKNOWN}
567 };
568
569 NamOValid namRsTypes[] =
570 {
571 {"Blast", "Blast database file"},
572 {"Index", "EMBOSS database B+tree index"},
573 {"List", "List of possible values"},
574 {NULL, NULL}
575 };
576
577
578
579
580 /* @datastatic NamPEntry ******************************************************
581 **
582 ** Internal database standard structure
583 **
584 ** @alias NamSEntry
585 ** @alias NamOEntry
586 **
587 ** @attr name [AjPStr] token name
588 ** @attr value [AjPStr] token value for variables
589 ** @attr file [AjPStr] Short name for definitions file
590 ** @attr data [void*] Attribute names and values for databases
591 ** @@
592 ******************************************************************************/
593
594 typedef struct NamSEntry
595 {
596 AjPStr name;
597 AjPStr value;
598 AjPStr file;
599 void* data;
600 } NamOEntry;
601
602 #define NamPEntry NamOEntry*
603
604
605
606
607 static const AjPTable namQueryDbdata(const AjPQuery qry);
608 static const AjPTable namQuerySvrdata(const AjPQuery qry);
609 static AjBool namSvrCacheParseList(AjPList listwords,
610 AjPList listcount, AjPFile file,
611 AjPTable dbtable, AjPTable alitable);
612 static AjBool namSvrCacheParse(AjPFile cachefile, AjPTable dbtable,
613 AjPTable alitable);
614 static AjPFile namSvrCacheOpen(const AjPStr cachename);
615 static AjBool namSvrCacheRead(const AjPStr server, const AjPStr cachename);
616 static ajint namSvrAttrC(const char* str);
617 static ajint namSvrAttrS(const AjPStr thys);
618 static AjBool namSvrSetAttrBoolC(const AjPTable dbtable, const char* attrib,
619 AjBool* qrybool);
620 static AjBool namSvrSetAttrStrC(const AjPTable dbtable, const char* attrib,
621 AjPStr* qrystr);
622
623 static const char* namDatatype2Fields(ajint datatype);
624 static const char* namDatatype2Qlinks(ajint datatype);
625 static ajint namDbAttrC(const char* str);
626 static ajint namDbAttrS(const AjPStr thys);
627 static AjBool namDbSetAttrBoolC(const AjPTable dbtable, const char* attrib,
628 AjBool* qrybool);
629 static AjBool namDbSetAttrStrC(const AjPTable dbtable, const char* attrib,
630 AjPStr* qrystr);
631
632 static void namDebugServer(const AjPTable dbtable);
633 static void namDebugDatabase(const AjPTable dbtable);
634 static void namDebugResource(const AjPTable dbtable);
635 static void namDebugVariables(void);
636 static void namDebugAliases(void);
637 static void namDebugMaster(const AjPTable table, ajint which);
638
639 static void namEntryDelete(NamPEntry* pentry, ajint which);
640 static void namError(const char* fmt, ...);
641 static void namListParse(AjPList listwords, AjPList listcount,
642 AjPFile file, const AjPStr shortname);
643 static void namListMasterDelete(AjPTable table, ajint which);
644 static AjBool namAccessTest(const AjPStr method, const AjPStr dbtype);
645 static AjBool namInformatTest(const AjPStr format, const AjPStr dbtype);
646 static const char* namMethod2Qlinks(const AjPStr method, ajint datatype);
647 static ajuint namMethod2Scope(const AjPStr method, const AjPStr dbtype);
648 static void namNoColon(AjPStr *thys);
649 static AjBool namProcessFile(AjPFile file, const AjPStr shortname);
650 static ajint namRsAttrC(const char* str);
651 static ajint namRsAttrS(const AjPStr thys);
652 static ajint namRsAttrFieldC(const AjPTable rstable, const char* str);
653 static ajint namRsAttrFieldS(const AjPTable rstable, const AjPStr str);
654 static void namUser(const char *fmt, ...);
655 static AjBool namValid(const NamPEntry entry, ajint entrytype);
656 static AjBool namValidAlias(const NamPEntry entry);
657 static AjBool namValidDatabase(const NamPEntry entry);
658 static AjBool namValidResource(const NamPEntry entry);
659 static AjBool namValidServer(const NamPEntry entry);
660 static AjBool namValidVariable(const NamPEntry entry);
661 static AjBool namVarResolve(AjPStr* var);
662 static AjBool namDbtablePutAttrS(AjPTable dbtable, AjPStr *Pattribute,
663 AjPStr *Pvalue);
664 static AjBool namRstablePutAttrS(AjPTable rstable, AjPStr *Pattribute,
665 AjPStr *Pvalue);
666 static AjBool namSvrtablePutAttrS(AjPTable svrtable, AjPStr *Pattribute,
667 AjPStr *Pvalue);
668 static void namDbAttrtableFree(AjPTable* Ptable);
669 static void namRsAttrtableFree(AjPTable* Ptable);
670 static void namSvrAttrtableFree(AjPTable* Ptable);
671
672
673
674
675 /* @funcstatic namEntryDelete *************************************************
676 **
677 ** Deletes a variable, database, or resource entry from the internal table.
678 **
679 ** @param [d] Pentry [NamPEntry*] The entry to be deleted.
680 ** @param [r] which [ajint] Internal table entry type
681 ** @return [void]
682 **
683 ** @release 1.0.0
684 ** @@
685 ******************************************************************************/
686
namEntryDelete(NamPEntry * Pentry,ajint which)687 static void namEntryDelete(NamPEntry* Pentry, ajint which)
688 {
689
690 AjPTable attrtable;
691 NamPEntry entry;
692
693 entry = *Pentry;
694
695 ajStrDel(&entry->name);
696 ajStrDel(&entry->value);
697 ajStrDel(&entry->file);
698
699 if(which == TYPE_DB)
700 {
701 attrtable = (AjPTable) entry->data;
702 namDbAttrtableFree(&attrtable);
703 }
704
705 else if(which == TYPE_SVR)
706 {
707 attrtable = (AjPTable) entry->data;
708 namSvrAttrtableFree(&attrtable);
709 }
710
711 else if(which == TYPE_RESOURCE)
712 {
713 attrtable = (AjPTable) entry->data;
714 namRsAttrtableFree(&attrtable);
715 }
716
717 else if(which == TYPE_SVRDB)
718 {
719 attrtable = (AjPTable) entry->data;
720 namListMasterDelete(attrtable, TYPE_DB);
721 ajTableFree(&attrtable);
722 }
723
724 else if(which == TYPE_SVRALI)
725 {
726 attrtable = (AjPTable) entry->data;
727 namListMasterDelete(attrtable, TYPE_ENV);
728 ajTableFree(&attrtable);
729 }
730
731 else if(which == TYPE_ENV)
732 {
733 }
734
735 else if(which == TYPE_ALIAS)
736 {
737 }
738
739 AJFREE(entry);
740
741 return;
742 }
743
744
745
746
747 /* @funcstatic namDbAttrtableFree *********************************************
748 **
749 ** Free a database attribute table
750 **
751 ** @param [d] Ptable [AjPTable*] Attribute table
752 **
753 **
754 ** @release 6.4.0
755 ******************************************************************************/
756
namDbAttrtableFree(AjPTable * Ptable)757 static void namDbAttrtableFree(AjPTable* Ptable)
758 {
759 AjPStr *keys = NULL;
760 void** values = NULL;
761 ajulong n;
762 ajulong i;
763 const NamPAttr attr = NULL;
764
765 n = ajTableToarrayKeysValues(*Ptable, (void***)&keys, &values);
766
767 for(i=0UL; i < n; i++)
768 {
769 attr = ajTableFetchS(namDbAttrTable, keys[i]);
770
771 if(!attr)
772 ajStrDel((AjPStr*) &values[i]);
773 else
774 {
775 switch(attr->Type)
776 {
777 case ATTR_LIST:
778 ajListstrFreeData((AjPList*) &values[i]);
779 break;
780 default:
781 ajStrDel((AjPStr*) &values[i]);
782 break;
783 }
784 }
785
786 ajStrDel(&keys[i]);
787 }
788
789 ajTableFree(Ptable);
790
791 AJFREE(keys);
792 AJFREE(values);
793
794 return;
795 }
796
797
798
799
800 /* @funcstatic namRsAttrtableFree *********************************************
801 **
802 ** Free a resource attribute table
803 **
804 ** @param [d] Ptable [AjPTable*] Attribute table
805 **
806 **
807 ** @release 6.4.0
808 ******************************************************************************/
809
namRsAttrtableFree(AjPTable * Ptable)810 static void namRsAttrtableFree(AjPTable* Ptable)
811 {
812 AjPStr *keys = NULL;
813 void** values = NULL;
814 ajulong n;
815 ajulong i;
816 const NamPAttr attr = NULL;
817
818 n = ajTableToarrayKeysValues(*Ptable, (void***) &keys, &values);
819
820 for(i=0UL; i < n; i++)
821 {
822 attr = ajTableFetchS(namResAttrTable, keys[i]);
823
824 if(!attr)
825 ajStrDel((AjPStr*) &values[i]);
826 else
827 {
828 switch(attr->Type)
829 {
830 case ATTR_LIST:
831 ajListstrFreeData((AjPList*) &values[i]);
832 break;
833 default:
834 ajStrDel((AjPStr*) &values[i]);
835 break;
836 }
837 }
838
839 ajStrDel(&keys[i]);
840 }
841
842 ajTableFree(Ptable);
843
844 AJFREE(keys);
845 AJFREE(values);
846
847 return;
848 }
849
850
851
852
853 /* @funcstatic namSvrAttrtableFree ********************************************
854 **
855 ** Free a server attribute table
856 **
857 ** @param [d] Ptable [AjPTable*] Attribute table
858 **
859 **
860 ** @release 6.4.0
861 ******************************************************************************/
862
namSvrAttrtableFree(AjPTable * Ptable)863 static void namSvrAttrtableFree(AjPTable* Ptable)
864 {
865 AjPStr *keys = NULL;
866 void** values = NULL;
867 ajulong n;
868 ajulong i;
869 const NamPAttr attr = NULL;
870
871 n = ajTableToarrayKeysValues(*Ptable, (void***) &keys, &values);
872
873 for(i=0UL; i < n; i++)
874 {
875 attr = ajTableFetchS(namSvrAttrTable, keys[i]);
876
877 if(!attr)
878 ajStrDel((AjPStr*) &values[i]);
879 else
880 {
881 switch(attr->Type)
882 {
883 case ATTR_LIST:
884 ajListstrFreeData((AjPList*) &values[i]);
885 break;
886 default:
887 ajStrDel((AjPStr*) &values[i]);
888 break;
889 }
890 }
891
892 ajStrDel(&keys[i]);
893 }
894
895 ajTableFree(Ptable);
896
897 AJFREE(keys);
898 AJFREE(values);
899
900 return;
901 }
902
903
904
905
906 /* @funcstatic namListMasterDelete ********************************************
907 **
908 ** Deletes all databases in the internal table. The table is converted to
909 ** an array, and each entry in turn is passed to namEntryDelete.
910 **
911 ** @param [u] table [AjPTable] Table object
912 ** @param [r] which [ajint] Internal table entry type
913 ** @return [void]
914 **
915 ** @release 2.7.0
916 ** @@
917 ******************************************************************************/
918
namListMasterDelete(AjPTable table,ajint which)919 static void namListMasterDelete(AjPTable table, ajint which)
920 {
921 ajint i;
922 NamPEntry fnew = NULL;
923 void **keyarray = NULL;
924 void **valarray = NULL;
925
926 if(!table)
927 return;
928
929 ajTableToarrayKeysValues(table, &keyarray, &valarray);
930
931 for(i = 0; keyarray[i]; i++)
932 {
933 AJFREE(keyarray[i]); /* the key */
934 fnew = (NamPEntry) valarray[i];
935 namEntryDelete(&fnew, which);
936 }
937
938 AJFREE(keyarray);
939 AJFREE(valarray);
940
941 return;
942 }
943
944
945
946
947 /* @func ajNamPrintSvrAttr ****************************************************
948 **
949 ** Prints a report of the server attributes available (for entrails)
950 **
951 ** @param [u] outf [AjPFile] Output file
952 ** @param [r] full [AjBool] Full output if AjTrue
953 ** @return [void]
954 **
955 ** @release 6.4.0
956 ******************************************************************************/
957
ajNamPrintSvrAttr(AjPFile outf,AjBool full)958 void ajNamPrintSvrAttr(AjPFile outf, AjBool full)
959 {
960 ajint i;
961 AjPStr tmpstr = NULL;
962 ajuint maxtmp = 0;
963
964 (void) full; /* no extra detail to report */
965
966 ajFmtPrintF(outf, "# Server attributes\n");
967 ajFmtPrintF(outf, "# %-15s %-12s %s\n", "Attribute", "Default", "Comment");
968 ajFmtPrintF(outf, "namSvrAttrs {\n");
969
970 for(i=0; namSvrAttrs[i].Name; i++)
971 {
972 ajFmtPrintF(outf, " %-15s", namSvrAttrs[i].Name);
973 ajFmtPrintS(&tmpstr, "\"%s\"", namSvrAttrs[i].Defval);
974
975 if(ajStrGetLen(tmpstr) > maxtmp)
976 maxtmp = ajStrGetLen(tmpstr);
977
978 ajFmtPrintF(outf, " %-12S", tmpstr);
979 ajFmtPrintF(outf, " \"%s\"\n", namSvrAttrs[i].Comment);
980 }
981
982 if(maxtmp > 12)
983 ajWarn("ajNamPrintSvrAttr max tmpstr len %u",
984 maxtmp);
985
986 ajFmtPrintF(outf, "}\n\n");
987 ajStrDel(&tmpstr);
988
989 return;
990 }
991
992
993
994
995 /* @func ajNamPrintDbAttr *****************************************************
996 **
997 ** Prints a report of the database attributes available (for entrails)
998 **
999 ** @param [u] outf [AjPFile] Output file
1000 ** @param [r] full [AjBool] Full output if AjTrue
1001 ** @return [void]
1002 **
1003 ** @release 2.5.0
1004 ******************************************************************************/
1005
ajNamPrintDbAttr(AjPFile outf,AjBool full)1006 void ajNamPrintDbAttr(AjPFile outf, AjBool full)
1007 {
1008 ajint i;
1009 AjPStr tmpstr = NULL;
1010 ajuint maxtmp = 0;
1011
1012 (void) full; /* no extra detail to report */
1013
1014 ajFmtPrintF(outf, "# Database attributes\n");
1015 ajFmtPrintF(outf, "# %-15s %-12s %s\n", "Attribute", "Default", "Comment");
1016 ajFmtPrintF(outf, "namDbAttrs {\n");
1017
1018 for(i=0; namDbAttrs[i].Name; i++)
1019 {
1020 ajFmtPrintF(outf, " %-15s", namDbAttrs[i].Name);
1021 ajFmtPrintS(&tmpstr, "\"%s\"", namDbAttrs[i].Defval);
1022
1023 if(ajStrGetLen(tmpstr) > maxtmp)
1024 maxtmp = ajStrGetLen(tmpstr);
1025
1026 ajFmtPrintF(outf, " %-12S", tmpstr);
1027 ajFmtPrintF(outf, " \"%s\"\n", namDbAttrs[i].Comment);
1028 }
1029
1030 if(maxtmp > 12)
1031 ajWarn("ajNamPrintDbAttr max tmpstr len %u",
1032 maxtmp);
1033
1034 ajFmtPrintF(outf, "}\n\n");
1035 ajStrDel(&tmpstr);
1036
1037 return;
1038 }
1039
1040
1041
1042
1043 /* @func ajNamPrintRsAttr *****************************************************
1044 **
1045 ** Prints a report of the resource attributes available (for entrails)
1046 **
1047 ** @param [u] outf [AjPFile] Output file
1048 ** @param [r] full [AjBool] Full output if AjTrue
1049 ** @return [void]
1050 **
1051 ** @release 2.7.0
1052 ******************************************************************************/
1053
ajNamPrintRsAttr(AjPFile outf,AjBool full)1054 void ajNamPrintRsAttr(AjPFile outf, AjBool full)
1055 {
1056 ajint i;
1057 AjPStr tmpstr = NULL;
1058 ajuint maxtmp = 0;
1059
1060 (void) full; /* no extra detail to report */
1061
1062 ajFmtPrintF(outf, "# Resource attributes\n");
1063 ajFmtPrintF(outf, "# %-15s %-26s %s\n", "Attribute", "Default", "Comment");
1064 ajFmtPrintF(outf, "namRsAttrs {\n");
1065
1066 for(i=0; namRsAttrs[i].Name; i++)
1067 {
1068 ajFmtPrintF(outf, " %-15s", namRsAttrs[i].Name);
1069 ajFmtPrintS(&tmpstr, "\"%s\"", namRsAttrs[i].Defval);
1070
1071 if(ajStrGetLen(tmpstr) > maxtmp)
1072 maxtmp = ajStrGetLen(tmpstr);
1073
1074 ajFmtPrintF(outf, " %-36S", tmpstr);
1075 ajFmtPrintF(outf, " \"%s\"\n", namRsAttrs[i].Comment);
1076 }
1077
1078 ajFmtPrintF(outf, "}\n\n");
1079
1080 if(maxtmp > 36)
1081 ajWarn("ajNamPrintRsAttr max tmpstr len %u",
1082 maxtmp);
1083
1084 ajStrDel(&tmpstr);
1085
1086 return;
1087 }
1088
1089
1090
1091
1092 /* @funcstatic namDebugDatabase ***********************************************
1093 **
1094 ** Prints a report of defined attributes for a database definition.
1095 **
1096 ** @param [r] dbtable [const AjPTable] Attribute table from a database entry.
1097 ** @return [void]
1098 **
1099 ** @release 1.13.0
1100 ** @@
1101 ******************************************************************************/
1102
namDebugDatabase(const AjPTable dbtable)1103 static void namDebugDatabase(const AjPTable dbtable)
1104 {
1105 ajulong i;
1106 ajulong nkeys;
1107 AjPStr *names = NULL;
1108 AjPStr *values = NULL;
1109
1110 nkeys = ajTableToarrayKeysValues(dbtable,
1111 (void***) &names, (void***) &values);
1112
1113 for(i=0UL; i < nkeys; i++)
1114 if(ajStrGetLen(values[i]))
1115 namUser("\t%S: %S\n", names[i], values[i]);
1116
1117 AJFREE(names);
1118 AJFREE(values);
1119
1120 return;
1121 }
1122
1123
1124
1125
1126 /* @funcstatic namDebugServer *************************************************
1127 **
1128 ** Prints a report of defined attributes for a server definition.
1129 **
1130 ** @param [r] svrtable [const AjPTable] Attribute table from a server entry.
1131 ** @return [void]
1132 **
1133 ** @release 6.4.0
1134 ** @@
1135 ******************************************************************************/
1136
namDebugServer(const AjPTable svrtable)1137 static void namDebugServer(const AjPTable svrtable)
1138 {
1139 ajulong i;
1140 ajulong nkeys;
1141 AjPStr *names = NULL;
1142 AjPStr *values = NULL;
1143
1144 nkeys = ajTableToarrayKeysValues(svrtable,
1145 (void***) &names, (void***) &values);
1146
1147 for(i=0UL; i < nkeys; i++)
1148 if(ajStrGetLen(values[i]))
1149 namUser("\t%S: %S\n", names[i], values[i]);
1150
1151 AJFREE(names);
1152 AJFREE(values);
1153
1154 return;
1155 }
1156
1157
1158
1159
1160 /* @funcstatic namDebugResource ***********************************************
1161 **
1162 ** Prints a report of defined attributes for a resource definition.
1163 **
1164 ** @param [r] rstable [const AjPTable] Attribute table from a database entry.
1165 ** @return [void]
1166 **
1167 ** @release 2.7.0
1168 ** @@
1169 ******************************************************************************/
1170
namDebugResource(const AjPTable rstable)1171 static void namDebugResource(const AjPTable rstable)
1172 {
1173 ajulong i;
1174 ajulong nkeys;
1175 AjPStr *names = NULL;
1176 AjPStr *values = NULL;
1177
1178 nkeys = ajTableToarrayKeysValues(rstable,
1179 (void***) &names, (void***) &values);
1180
1181 for(i=0UL; i < nkeys; i++)
1182 if(ajStrGetLen(values[i]))
1183 namUser("\t%S: %S\n", names[i], values[i]);
1184
1185 AJFREE(names);
1186 AJFREE(values);
1187
1188 return;
1189 }
1190
1191
1192
1193
1194 /* @funcstatic namDebugMaster *************************************************
1195 **
1196 ** Lists databases or variables defined in the internal table.
1197 **
1198 ** @param [r] table [const AjPTable] Table object
1199 ** @param [r] which [ajint] Variable type, either TYPE_ENV for environment
1200 ** variables or TYPE_DB for databases or
1201 ** TYPE_RESOURCE for resources.
1202 ** @return [void]
1203 **
1204 ** @release 2.7.0
1205 ** @@
1206 ******************************************************************************/
1207
namDebugMaster(const AjPTable table,ajint which)1208 static void namDebugMaster(const AjPTable table, ajint which)
1209 {
1210 ajint i;
1211 NamPEntry fnew;
1212 void **keyarray = NULL;
1213 void **valarray = NULL;
1214 char *key;
1215
1216 ajTableToarrayKeysValues(table, &keyarray, &valarray);
1217
1218 for(i = 0; keyarray[i]; i++)
1219 {
1220 key = (char*) keyarray[i];
1221 fnew = (NamPEntry) valarray[i];
1222
1223 if(TYPE_SVR == which)
1224 {
1225 namUser("SVR %S\t *%s*\n", fnew->name, key);
1226 namDebugServer(fnew->data);
1227 namUser("\n");
1228 }
1229
1230 else if(TYPE_DB == which)
1231 {
1232 namUser("DB %S\t *%s*\n", fnew->name, key);
1233 namDebugDatabase(fnew->data);
1234 namUser("\n");
1235 }
1236
1237 else if(TYPE_RESOURCE == which)
1238 {
1239 namUser("RES %S\t *%s*\n", fnew->name, key);
1240 namDebugResource(fnew->data);
1241 namUser("\n");
1242 }
1243
1244 else if(TYPE_ENV == which)
1245 namUser("ENV %S\t%S\t *%s*\n",fnew->name,fnew->value,key);
1246
1247 else if(TYPE_ALIAS == which)
1248 namUser("ALIAS %S\t%S\t *%s*\n",fnew->name,fnew->value,key);
1249 }
1250
1251 AJFREE(keyarray);
1252 AJFREE(valarray);
1253
1254 return;
1255 }
1256
1257
1258
1259
1260 /* @func ajNamSvrGetAttrC *****************************************************
1261 **
1262 ** Return the value for a server attribute
1263 **
1264 ** @param [r] name [const AjPStr] server name
1265 ** @param [r] attribute [const char *] server attribute name
1266 ** @param [w] value [AjPStr *] attribute value
1267 **
1268 ** @return [AjBool] true if found
1269 **
1270 ** @release 6.4.0
1271 ** @@
1272 ******************************************************************************/
1273
ajNamSvrGetAttrC(const AjPStr name,const char * attribute,AjPStr * value)1274 AjBool ajNamSvrGetAttrC(const AjPStr name, const char *attribute,
1275 AjPStr *value)
1276 {
1277 ajint j;
1278 NamPEntry fnew = NULL;
1279 AjPTable svrtable;
1280 const AjPStr svrvalue;
1281
1282 ajDebug("ajNamSvrGetAttrC '%S' '%s'\n", name, attribute);
1283
1284 fnew = ajTableFetchmodS(namSvrMasterTable, name);
1285
1286 if(!fnew)
1287 {
1288 ajWarn("unknown server '%S'",
1289 name);
1290 return ajFalse;
1291 }
1292
1293 svrtable = (AjPTable) fnew->data;
1294 j = namSvrAttrC(attribute);
1295
1296 if(j < 0)
1297 {
1298 ajWarn("unknown attribute '%s' requested for server '%S'",
1299 attribute, name);
1300 return ajFalse;
1301 }
1302
1303 svrvalue = ajTableFetchmodC(svrtable, attribute);
1304
1305 if(ajStrGetLen(svrvalue))
1306 {
1307 ajStrAssignS(value,svrvalue);
1308
1309 return ajTrue;
1310 }
1311
1312 return ajFalse;
1313 }
1314
1315
1316
1317
1318 /* @func ajNamSvrGetAttrS *****************************************************
1319 **
1320 ** Return the value for a server attribute
1321 **
1322 ** @param [r] name [const AjPStr] server name
1323 ** @param [r] attribute [const AjPStr] server attribute name
1324 ** @param [w] value [AjPStr *] attribute value
1325 **
1326 ** @return [AjBool] true if found
1327 **
1328 ** @release 6.4.0
1329 ** @@
1330 ******************************************************************************/
1331
ajNamSvrGetAttrS(const AjPStr name,const AjPStr attribute,AjPStr * value)1332 AjBool ajNamSvrGetAttrS(const AjPStr name, const AjPStr attribute,
1333 AjPStr *value)
1334 {
1335 return ajNamSvrGetAttrC(name, MAJSTRGETPTR(attribute), value);
1336 }
1337
1338
1339
1340
1341 /* @func ajNamSvrGetAttrSpecialC **********************************************
1342 **
1343 ** Return the value for the first occurrence of a named special attribute
1344 **
1345 ** @param [r] name [const AjPStr] server name
1346 ** @param [r] attribute [const char*] special attribute name
1347 ** @param [w] value [AjPStr*] value
1348 **
1349 ** @return [ajuint] Number of matching special values
1350 **
1351 ** @release 6.5.0
1352 ** @@
1353 ******************************************************************************/
1354
ajNamSvrGetAttrSpecialC(const AjPStr name,const char * attribute,AjPStr * value)1355 ajuint ajNamSvrGetAttrSpecialC(const AjPStr name, const char *attribute,
1356 AjPStr* value)
1357 {
1358 ajuint ret = 0;
1359 ajint j;
1360 NamPEntry fnew = NULL;
1361 AjPTable svrtable;
1362 AjPList svrvalue;
1363 AjIList iter;
1364 const AjPStr tmpstr = NULL;
1365 ajuint attrlen = 0;
1366
1367 ajDebug("ajNamSvrGetAttrSpecial '%S' '%s'\n", name, attribute);
1368
1369 attrlen = strlen(attribute);
1370
1371 fnew = ajTableFetchmodS(namSvrMasterTable, name);
1372
1373 if(!fnew)
1374 {
1375 ajWarn("unknown database '%S'",
1376 name);
1377 return ajFalse;
1378 }
1379
1380 svrtable = (AjPTable) fnew->data;
1381 j = namSvrAttrC("special");
1382
1383 if(j < 0)
1384 {
1385 ajWarn("unknown attribute '%s' requested for server '%S'",
1386 "special", name);
1387 return ajFalse;
1388 }
1389
1390 svrvalue = ajTableFetchmodC(svrtable, "special");
1391
1392 if(ajListGetLength(svrvalue))
1393 {
1394 iter = ajListIterNewread(svrvalue);
1395
1396 while(!ajListIterDone(iter))
1397 {
1398 tmpstr = ajListIterGet(iter);
1399 if(ajStrPrefixC(tmpstr, attribute) &&
1400 ajStrGetCharPos(tmpstr, attrlen) == '=')
1401 {
1402 if(!ret++)
1403 {
1404 ajStrAssignS(value, tmpstr);
1405 ajStrCutStart(value, attrlen+1);
1406 }
1407 }
1408 }
1409
1410 ajListIterDel(&iter);
1411 }
1412
1413 return ret;
1414 }
1415
1416
1417
1418
1419 /* @func ajNamSvrGetAttrSpecialS **********************************************
1420 **
1421 ** Return the value for the first occurrence of a named special attribute
1422 **
1423 ** @param [r] name [const AjPStr] server name
1424 ** @param [r] attribute [const AjPStr] special attribute name
1425 ** @param [w] value [AjPStr*] value
1426 **
1427 ** @return [ajuint] Number of matching special values
1428 **
1429 ** @release 6.5.0
1430 ** @@
1431 ******************************************************************************/
1432
ajNamSvrGetAttrSpecialS(const AjPStr name,const AjPStr attribute,AjPStr * value)1433 ajuint ajNamSvrGetAttrSpecialS(const AjPStr name, const AjPStr attribute,
1434 AjPStr* value)
1435 {
1436 return ajNamSvrGetAttrSpecialC(name, MAJSTRGETPTR(attribute), value);
1437 }
1438
1439
1440
1441
1442 /* @func ajNamSvrGetAttrlist **************************************************
1443 **
1444 ** Return a list of names and values for all of a server defined attributes
1445 **
1446 ** @param [r] name [const AjPStr] server name
1447 **
1448 ** @return [AjPList] Tag-value list
1449 **
1450 ** @release 6.4.0
1451 ** @@
1452 ******************************************************************************/
1453
ajNamSvrGetAttrlist(const AjPStr name)1454 AjPList ajNamSvrGetAttrlist(const AjPStr name)
1455 {
1456 AjPList ret = NULL;
1457 AjPTagval tagval = NULL;
1458 NamPEntry fnew = NULL;
1459 AjPTable svrtable = NULL;
1460 const char* svrattr = NULL;
1461 NamOAttr attr;
1462 void* svrvalue;
1463 const AjPStr tmpstr;
1464 ajuint i;
1465 AjIList iter;
1466
1467 fnew = ajTableFetchmodS(namSvrMasterTable, name);
1468
1469 if(!fnew)
1470 return NULL;
1471
1472 ret = ajListNew();
1473 svrtable = (AjPTable) fnew->data;
1474
1475 for(i=0; namSvrAttrs[i].Name; i++)
1476 {
1477 attr = namSvrAttrs[i];
1478 svrattr = attr.Name;
1479
1480 svrvalue = ajTableFetchmodC(svrtable, svrattr);
1481 if(svrvalue)
1482 {
1483 switch(attr.Type)
1484 {
1485 case ATTR_LIST:
1486 iter = ajListIterNewread(svrvalue);
1487
1488 while(!ajListIterDone(iter))
1489 {
1490 tmpstr = ajListIterGet(iter);
1491 tagval = ajTagvalNewC(svrattr,MAJSTRGETPTR(tmpstr));
1492 ajListPushAppend(ret, tagval);
1493 }
1494
1495 ajListIterDel(&iter);
1496 break;
1497 default:
1498 tagval = ajTagvalNewC(svrattr,ajStrGetPtr(svrvalue));
1499 ajListPushAppend(ret, tagval);
1500 break;
1501 }
1502 }
1503 }
1504
1505 return ret;
1506
1507 }
1508
1509
1510
1511
1512 /* @func ajNamSvrGetdbAttrC ***************************************************
1513 **
1514 ** Return the value for a server database attribute
1515 **
1516 ** @param [r] name [const AjPStr] server name
1517 ** @param [r] dbname [const AjPStr] database name
1518 ** @param [r] attribute [const char *] database attribute name
1519 ** @param [w] value [AjPStr *] attribute value
1520 **
1521 ** @return [AjBool] true if found
1522 **
1523 ** @release 6.4.0
1524 ** @@
1525 ******************************************************************************/
1526
ajNamSvrGetdbAttrC(const AjPStr name,const AjPStr dbname,const char * attribute,AjPStr * value)1527 AjBool ajNamSvrGetdbAttrC(const AjPStr name, const AjPStr dbname,
1528 const char *attribute,
1529 AjPStr *value)
1530 {
1531 ajint j;
1532 NamPEntry dbdata = NULL;
1533 NamPEntry fnew = NULL;
1534 AjPTable sdbtable;
1535 AjPTable dbtable;
1536 const AjPStr dbvalue;
1537
1538 ajDebug("ajNamSvrGetdbAttrC '%S' '%S' '%s'\n",
1539 name, dbname, attribute);
1540
1541 if(!ajNamDatabaseServer(dbname, name))
1542 return ajFalse;
1543
1544 dbdata = ajTableFetchmodS(namSvrDatabaseTable, name);
1545 sdbtable = (AjPTable) dbdata->data;
1546
1547 fnew = ajTableFetchmodS(sdbtable, dbname);
1548
1549 dbtable = (AjPTable) fnew->data;
1550 j = namDbAttrC(attribute);
1551
1552 if(j < 0)
1553 {
1554 ajWarn("unknown attribute '%s' requested for database '%S'",
1555 attribute, name);
1556 return ajFalse;
1557 }
1558
1559 dbvalue = ajTableFetchmodC(dbtable, attribute);
1560
1561 if(ajStrGetLen(dbvalue))
1562 {
1563 ajStrAssignS(value,dbvalue);
1564
1565 return ajTrue;
1566 }
1567
1568 return ajFalse;
1569 }
1570
1571
1572
1573
1574 /* @func ajNamSvrGetdbAttrS ***************************************************
1575 **
1576 ** Return the value for a database attribute
1577 **
1578 ** @param [r] name [const AjPStr] server name
1579 ** @param [r] dbname [const AjPStr] database name
1580 ** @param [r] attribute [const AjPStr] database attribute name
1581 ** @param [w] value [AjPStr *] attribute value
1582 **
1583 ** @return [AjBool] true if found
1584 **
1585 ** @release 6.4.0
1586 ** @@
1587 ******************************************************************************/
1588
ajNamSvrGetdbAttrS(const AjPStr name,const AjPStr dbname,const AjPStr attribute,AjPStr * value)1589 AjBool ajNamSvrGetdbAttrS(const AjPStr name, const AjPStr dbname,
1590 const AjPStr attribute,
1591 AjPStr *value)
1592 {
1593 return ajNamSvrGetdbAttrC(name, dbname, MAJSTRGETPTR(attribute), value);
1594 }
1595
1596
1597
1598
1599 /* @func ajNamSvrGetdbAttrSpecialC ********************************************
1600 **
1601 ** Return the value for a server database special attribute
1602 **
1603 ** @param [r] name [const AjPStr] server name
1604 ** @param [r] dbname [const AjPStr] database name
1605 ** @param [r] attribute [const char *] database special attribute name
1606 ** @param [w] value [AjPStr *] attribute value
1607 **
1608 ** @return [ajuint] Number of matching special values
1609 **
1610 ** @release 6.5.0
1611 ** @@
1612 ******************************************************************************/
1613
ajNamSvrGetdbAttrSpecialC(const AjPStr name,const AjPStr dbname,const char * attribute,AjPStr * value)1614 ajuint ajNamSvrGetdbAttrSpecialC(const AjPStr name, const AjPStr dbname,
1615 const char *attribute,
1616 AjPStr *value)
1617 {
1618 ajuint ret = 0;
1619 ajint j;
1620 NamPEntry fnew = NULL;
1621 NamPEntry dbdata = NULL;
1622 AjPTable sdbtable;
1623 AjPTable dbtable;
1624 AjPList dbvalue;
1625 AjIList iter;
1626 const AjPStr tmpstr = NULL;
1627 ajuint attrlen = 0;
1628
1629 ajDebug("ajNamSvrGetdbAttrSpecialC '%S' '%S' '%s'\n",
1630 name, dbname, attribute);
1631
1632 if(!ajNamDatabaseServer(dbname, name))
1633 return ajFalse;
1634
1635 attrlen = strlen(attribute);
1636
1637 dbdata = ajTableFetchmodS(namSvrDatabaseTable, name);
1638 sdbtable = (AjPTable) dbdata->data;
1639
1640 fnew = ajTableFetchmodS(sdbtable, dbname);
1641
1642 dbtable = (AjPTable) fnew->data;
1643 j = namDbAttrC("special");
1644
1645 if(j < 0)
1646 {
1647 ajWarn("unknown attribute '%s' requested for database '%S'",
1648 "special", name);
1649 return ajFalse;
1650 }
1651
1652 dbvalue = ajTableFetchmodC(dbtable, "special");
1653
1654 if(ajListGetLength(dbvalue))
1655 {
1656 iter = ajListIterNewread(dbvalue);
1657
1658 while(!ajListIterDone(iter))
1659 {
1660 tmpstr = ajListIterGet(iter);
1661 if(ajStrPrefixC(tmpstr, attribute) &&
1662 ajStrGetCharPos(tmpstr, attrlen) == '=')
1663 {
1664 if(!ret++)
1665 {
1666 ajStrAssignS(value, tmpstr);
1667 ajStrCutStart(value, attrlen+1);
1668 }
1669 }
1670 }
1671
1672 ajListIterDel(&iter);
1673 }
1674
1675 return ret;
1676 }
1677
1678
1679
1680
1681 /* @func ajNamSvrGetdbAttrSpecialS ********************************************
1682 **
1683 ** Return the value for a database special attribute
1684 **
1685 ** @param [r] name [const AjPStr] server name
1686 ** @param [r] dbname [const AjPStr] database name
1687 ** @param [r] attribute [const AjPStr] database special attribute name
1688 ** @param [w] value [AjPStr *] attribute value
1689 **
1690 ** @return [ajuint] Number of matching special values
1691 **
1692 ** @release 6.5.0
1693 ** @@
1694 ******************************************************************************/
1695
ajNamSvrGetdbAttrSpecialS(const AjPStr name,const AjPStr dbname,const AjPStr attribute,AjPStr * value)1696 ajuint ajNamSvrGetdbAttrSpecialS(const AjPStr name, const AjPStr dbname,
1697 const AjPStr attribute,
1698 AjPStr *value)
1699 {
1700 return ajNamSvrGetdbAttrSpecialC(name, dbname, MAJSTRGETPTR(attribute),
1701 value);
1702 }
1703
1704
1705
1706
1707 /* @func ajNamSvrDetails ******************************************************
1708 **
1709 ** Returns server access method information
1710 **
1711 ** @param [r] name [const AjPStr] Server name
1712 ** @param [w] type [AjPStr*] datatype - 'Protein', 'Nucleic' etc.
1713 ** @param [w] scope [AjPStr*] datatype scope Sequence Features etc.
1714 ** @param [w] id [AjBool*] ajTrue = can access single entries
1715 ** @param [w] qry [AjBool*] ajTrue = can access wild/query entries
1716 ** @param [w] all [AjBool*] ajTrue = can access all entries
1717 ** @param [w] comment [AjPStr*] comment about server
1718 ** @param [w] svrversion [AjPStr*] Server version
1719 ** @param [w] methods [AjPStr*] server access methods formatted
1720 ** @param [w] defined [AjPStr*] server definition file short name
1721 ** @param [w] cachedirectory [AjPStr*] cache directory name
1722 ** @param [w] cachefile [AjPStr*] cache file name
1723 ** @param [w] url [AjPStr*] server URL
1724 ** @return [AjBool] ajTrue if server details were found
1725 **
1726 ** @release 6.4.0
1727 ** @@
1728 ******************************************************************************/
1729
ajNamSvrDetails(const AjPStr name,AjPStr * type,AjPStr * scope,AjBool * id,AjBool * qry,AjBool * all,AjPStr * comment,AjPStr * svrversion,AjPStr * methods,AjPStr * defined,AjPStr * cachedirectory,AjPStr * cachefile,AjPStr * url)1730 AjBool ajNamSvrDetails(const AjPStr name, AjPStr* type, AjPStr *scope,
1731 AjBool* id, AjBool* qry, AjBool* all,
1732 AjPStr* comment, AjPStr* svrversion,
1733 AjPStr* methods, AjPStr* defined,
1734 AjPStr *cachedirectory, AjPStr* cachefile,
1735 AjPStr *url)
1736 {
1737 NamPType namtype = NULL;
1738 NamPEntry fnew = NULL;
1739 AjPTable svrtable = NULL;
1740 ajint i;
1741 ajint qryscope;
1742 AjPStr attrname = NULL;
1743 const AjPStr attrval = NULL;
1744 const AjPStr svrtype = NULL;
1745 AjBool typetested = ajFalse;
1746 AjPStrTok handle = NULL;
1747 AjPStr nexttype = NULL;
1748
1749 AjPFile cacheopen = NULL;
1750
1751 AjBool *datatype;
1752
1753 *id = *qry = *all = ajFalse;
1754
1755 ajStrDelStatic(scope);
1756 ajStrDelStatic(type);
1757 ajStrDelStatic(comment);
1758 ajStrDelStatic(methods);
1759 ajStrDelStatic(defined);
1760 ajStrDelStatic(cachedirectory);
1761 ajStrDelStatic(cachefile);
1762 ajStrDelStatic(svrversion);
1763 ajStrDelStatic(url);
1764
1765 fnew = ajTableFetchmodS(namSvrMasterTable, name);
1766
1767 if(fnew)
1768 {
1769 ajDebug("ajNamSvrDetails '%S' found\n", name);
1770
1771 ajStrAssignS(defined, fnew->file);
1772
1773 svrtable = (AjPTable) fnew->data;
1774 svrtype = ajTableFetchmodC(svrtable, "type");
1775
1776 for(i=0; namSvrAttrs[i].Name; i++)
1777 {
1778 if(namSvrAttrs[i].Type != ATTR_STR)
1779 continue;
1780
1781 ajStrAssignC(&attrname, namSvrAttrs[i].Name);
1782 attrval = ajTableFetchmodS(svrtable, attrname);
1783 ajDebug("Attribute name = %S, value = %S\n",
1784 attrname, attrval);
1785
1786 if(ajStrGetLen(attrval))
1787 {
1788 if(ajStrMatchC(attrname, "type"))
1789 {
1790 ajStrTokenAssignC(&handle, attrval, " ,;");
1791 ajStrAssignC(type, "");
1792 ajStrAssignC(scope, "");
1793 AJCNEW0(datatype, AJDATATYPE_MAX);
1794
1795 while(ajStrTokenNextParse(handle, &nexttype))
1796 {
1797 if(ajStrGetLen(*type))
1798 ajStrAppendK(type, ' ');
1799
1800 if(ajStrMatchCaseC(attrval, "N"))
1801 ajStrAppendC(type, "Nucleotide");
1802 else if(ajStrMatchCaseC(attrval, "P"))
1803 ajStrAppendC(type, "Protein");
1804 else
1805 {
1806 ajStrFmtCapital(&nexttype);
1807 ajStrAppendS(type, nexttype);
1808 }
1809
1810 typetested = ajTrue;
1811 namtype = ajTableFetchmodS(namDbTypeTable, nexttype);
1812
1813 if(namtype)
1814 {
1815 if(!datatype[namtype->DataType]++)
1816 {
1817 if(ajStrGetLen(*scope))
1818 ajStrAppendK(scope, ' ');
1819
1820 ajStrAppendC(scope, namtype->Scope);
1821 }
1822 }
1823 else
1824 ajWarn("Server '%S' type '%S' unknown scope",
1825 name, nexttype);
1826 }
1827 ajStrTokenDel(&handle);
1828 AJFREE(datatype);
1829 ajStrDel(&nexttype);
1830 }
1831
1832 if(ajStrMatchC(attrname, "method"))
1833 {
1834 qryscope = namMethod2Scope(attrval, svrtype);
1835
1836 if(qryscope & AJMETHOD_ENTRY)
1837 *id = ajTrue;
1838
1839 if(qryscope & AJMETHOD_QUERY)
1840 *qry = ajTrue;
1841
1842 if(qryscope & AJMETHOD_ALL)
1843 *all = ajTrue;
1844
1845 ajStrAppendS(methods, attrval);
1846 }
1847
1848 if(ajStrMatchC(attrname, "methodentry"))
1849 {
1850 qryscope = namMethod2Scope(attrval, svrtype);
1851
1852 if(qryscope & AJMETHOD_ENTRY)
1853 *id = ajTrue;
1854
1855 if(ajStrGetLen(*methods))
1856 ajStrAppendC(methods, ",");
1857
1858 ajStrAppendS(methods, attrval);
1859 ajStrAppendC(methods, "(id)");
1860 }
1861
1862 if(ajStrMatchC(attrname, "methodquery"))
1863 {
1864 qryscope = namMethod2Scope(attrval, svrtype);
1865
1866 if(qryscope & AJMETHOD_ENTRY)
1867 *id = ajTrue;
1868
1869 if(qryscope & AJMETHOD_QUERY)
1870 *qry = ajTrue;
1871
1872 if(ajStrGetLen(*methods))
1873 ajStrAppendC(methods, ",");
1874
1875 ajStrAppendS(methods, attrval);
1876 ajStrAppendC(methods, "(qry)");
1877 }
1878
1879 if(ajStrMatchC(attrname, "methodall"))
1880 {
1881 qryscope = namMethod2Scope(attrval, svrtype);
1882
1883 if(qryscope & AJMETHOD_ALL)
1884 *all = ajTrue;
1885
1886 if(ajStrGetLen(*methods))
1887 ajStrAppendC(methods, ",");
1888
1889 ajStrAppendS(methods, attrval);
1890 ajStrAppendC(methods, "(all)");
1891 }
1892
1893 if(ajStrMatchC(attrname, "comment"))
1894 ajStrAssignS(comment, attrval);
1895
1896 if(ajStrMatchC(attrname, "serverversion"))
1897 ajStrAssignS(svrversion, attrval);
1898
1899 if(ajStrMatchC(attrname, "cachedirectory"))
1900 ajStrAssignS(cachedirectory, attrval);
1901
1902 if(ajStrMatchC(attrname, "cachefile"))
1903 ajStrAssignS(cachefile, attrval);
1904
1905 if(ajStrMatchC(attrname, "url"))
1906 ajStrAssignS(url, attrval);
1907 }
1908 }
1909
1910 if(!typetested)
1911 {
1912 ajDebug("Bad server definition for %S: No type. 'P' assumed\n",
1913 name);
1914 ajWarn("Bad server definition for %S: No type. 'P' assumed",
1915 name);
1916 ajStrAssignC(type, "P");
1917 }
1918
1919 if(!*id && !*qry && !*all)
1920 {
1921 ajDebug("Bad server definition for %S: No method(s) for access\n",
1922 name);
1923 ajWarn("Bad server definition for %S: No method(s) for access",
1924 name);
1925 }
1926
1927 ajStrDel(&attrname);
1928
1929 if(ajStrGetLen(*cachefile))
1930 {
1931 cacheopen = namSvrCacheOpen(*cachefile);
1932 if(cacheopen)
1933 {
1934 ajFmtPrintS(cachefile, "%F", cacheopen);
1935 ajFileClose(&cacheopen);
1936 }
1937 }
1938
1939 return ajTrue;
1940 }
1941
1942 ajDebug(" '%S' not found\n", name);
1943
1944 ajStrDel(&attrname);
1945
1946 return ajFalse;
1947 }
1948
1949
1950
1951
1952 /* @func ajNamDbGetAttrC ******************************************************
1953 **
1954 ** Return the value for a database attribute
1955 **
1956 ** @param [r] name [const AjPStr] database name
1957 ** @param [r] attribute [const char *] database attribute name
1958 ** @param [w] value [AjPStr *] attribute value
1959 **
1960 ** @return [AjBool] true if found
1961 **
1962 ** @release 6.4.0
1963 ** @@
1964 ******************************************************************************/
1965
ajNamDbGetAttrC(const AjPStr name,const char * attribute,AjPStr * value)1966 AjBool ajNamDbGetAttrC(const AjPStr name, const char *attribute,
1967 AjPStr *value)
1968 {
1969 ajint j;
1970 NamPEntry fnew = NULL;
1971 AjPTable dbtable;
1972 const AjPStr dbvalue;
1973
1974 ajDebug("ajNamDbGetAttrC '%S' '%s'\n", name, attribute);
1975
1976 fnew = ajTableFetchmodS(namDbMasterTable, name);
1977
1978 if(!fnew)
1979 {
1980 ajWarn("unknown database '%S'",
1981 name);
1982 return ajFalse;
1983 }
1984
1985 dbtable = (AjPTable) fnew->data;
1986 j = namDbAttrC(attribute);
1987
1988 if(j < 0)
1989 {
1990 ajWarn("unknown attribute '%s' requested for database '%S'",
1991 attribute, name);
1992 return ajFalse;
1993 }
1994
1995 dbvalue = ajTableFetchmodC(dbtable, attribute);
1996
1997 if(ajStrGetLen(dbvalue))
1998 {
1999 ajStrAssignS(value,dbvalue);
2000
2001 return ajTrue;
2002 }
2003
2004 return ajFalse;
2005 }
2006
2007
2008
2009
2010 /* @func ajNamDbGetAttrS ******************************************************
2011 **
2012 ** Return the value for a database attribute
2013 **
2014 ** @param [r] name [const AjPStr] database name
2015 ** @param [r] attribute [const AjPStr] database attribute name
2016 ** @param [w] value [AjPStr *] attribute value
2017 **
2018 ** @return [AjBool] true if found
2019 **
2020 ** @release 6.4.0
2021 ** @@
2022 ******************************************************************************/
2023
ajNamDbGetAttrS(const AjPStr name,const AjPStr attribute,AjPStr * value)2024 AjBool ajNamDbGetAttrS(const AjPStr name, const AjPStr attribute,
2025 AjPStr *value)
2026 {
2027 return ajNamDbGetAttrC(name, MAJSTRGETPTR(attribute), value);
2028 }
2029
2030
2031
2032
2033 /* @func ajNamDbGetAttrSpecialC ***********************************************
2034 **
2035 ** Return the value for the first occurrence of a named special attribute
2036 **
2037 ** @param [r] name [const AjPStr] database name
2038 ** @param [r] attribute [const char*] special attribute name
2039 ** @param [w] value [AjPStr*] value
2040 **
2041 ** @return [ajuint] Number of matching special values
2042 **
2043 ** @release 6.5.0
2044 ** @@
2045 ******************************************************************************/
2046
ajNamDbGetAttrSpecialC(const AjPStr name,const char * attribute,AjPStr * value)2047 ajuint ajNamDbGetAttrSpecialC(const AjPStr name, const char *attribute,
2048 AjPStr* value)
2049 {
2050 ajuint ret = 0;
2051 ajint j;
2052 NamPEntry fnew = NULL;
2053 AjPTable dbtable;
2054 AjPList dbvalue;
2055 AjIList iter;
2056 const AjPStr tmpstr = NULL;
2057 ajuint attrlen = 0;
2058
2059 ajDebug("ajNamDbGetAttrSpecial '%S' '%s'\n", name, attribute);
2060
2061 attrlen = strlen(attribute);
2062
2063 fnew = ajTableFetchmodS(namDbMasterTable, name);
2064
2065 if(!fnew)
2066 {
2067 ajWarn("unknown database '%S'",
2068 name);
2069 return ajFalse;
2070 }
2071
2072 dbtable = (AjPTable) fnew->data;
2073 j = namDbAttrC("special");
2074
2075 if(j < 0)
2076 {
2077 ajWarn("unknown attribute '%s' requested for database '%S'",
2078 "special", name);
2079 return ajFalse;
2080 }
2081
2082 dbvalue = ajTableFetchmodC(dbtable, "special");
2083
2084 if(ajListGetLength(dbvalue))
2085 {
2086 iter = ajListIterNewread(dbvalue);
2087
2088 while(!ajListIterDone(iter))
2089 {
2090 tmpstr = ajListIterGet(iter);
2091 if(ajStrPrefixC(tmpstr, attribute) &&
2092 ajStrGetCharPos(tmpstr, attrlen) == '=')
2093 {
2094 if(!ret++)
2095 {
2096 ajStrAssignS(value, tmpstr);
2097 ajStrCutStart(value, attrlen+1);
2098 }
2099 }
2100 }
2101
2102 ajListIterDel(&iter);
2103 }
2104
2105 return ret;
2106 }
2107
2108
2109
2110
2111 /* @func ajNamDbGetAttrSpecialS ***********************************************
2112 **
2113 ** Return the value for the first occurrence of a named special attribute
2114 **
2115 ** @param [r] name [const AjPStr] database name
2116 ** @param [r] attribute [const AjPStr] special attribute name
2117 ** @param [w] value [AjPStr*] value
2118 **
2119 ** @return [ajuint] Number of matching special values
2120 **
2121 ** @release 6.5.0
2122 ** @@
2123 ******************************************************************************/
2124
ajNamDbGetAttrSpecialS(const AjPStr name,const AjPStr attribute,AjPStr * value)2125 ajuint ajNamDbGetAttrSpecialS(const AjPStr name, const AjPStr attribute,
2126 AjPStr* value)
2127 {
2128 return ajNamDbGetAttrSpecialC(name, MAJSTRGETPTR(attribute), value);
2129 }
2130
2131
2132
2133
2134 /* @func ajNamDbGetAttrlist ***************************************************
2135 **
2136 ** Return a list of names and values for all of a database defined attributes
2137 **
2138 ** @param [r] name [const AjPStr] database name
2139 **
2140 ** @return [AjPList] Tag-value list
2141 **
2142 ** @release 6.4.0
2143 ** @@
2144 ******************************************************************************/
2145
ajNamDbGetAttrlist(const AjPStr name)2146 AjPList ajNamDbGetAttrlist(const AjPStr name)
2147 {
2148 AjPList ret = NULL;
2149 AjPTagval tagval = NULL;
2150 NamPEntry fnew = NULL;
2151 AjPTable dbtable = NULL;
2152 const char* dbattr = NULL;
2153 NamOAttr attr;
2154 void* dbvalue;
2155 const AjPStr tmpstr;
2156 ajuint i;
2157 AjIList iter;
2158
2159 fnew = ajTableFetchmodS(namDbMasterTable, name);
2160
2161 if(!fnew)
2162 {
2163 return NULL;
2164 }
2165
2166 ret = ajListNew();
2167 dbtable = (AjPTable) fnew->data;
2168
2169 for(i=0; namDbAttrs[i].Name; i++)
2170 {
2171 attr = namDbAttrs[i];
2172 dbattr = attr.Name;
2173
2174 dbvalue = ajTableFetchmodC(dbtable, dbattr);
2175
2176 if(dbvalue)
2177 {
2178 switch(attr.Type)
2179 {
2180 case ATTR_LIST:
2181 iter = ajListIterNewread(dbvalue);
2182
2183 while(!ajListIterDone(iter))
2184 {
2185 tmpstr = ajListIterGet(iter);
2186 tagval = ajTagvalNewC(dbattr, MAJSTRGETPTR(tmpstr));
2187 ajListPushAppend(ret, tagval);
2188 }
2189
2190 ajListIterDel(&iter);
2191 break;
2192 default:
2193 tagval = ajTagvalNewC(dbattr, ajStrGetPtr(dbvalue));
2194 ajListPushAppend(ret, tagval);
2195 break;
2196 }
2197 }
2198 }
2199
2200 return ret;
2201
2202 }
2203
2204
2205
2206
2207 /* @func ajNamDbGetAttrlistSvr ************************************************
2208 **
2209 ** Return a list of names and values for all of a database defined attributes
2210 ** where the database is defined for a server
2211 **
2212 ** @param [r] name [const AjPStr] database name
2213 ** @param [r] svrname [const AjPStr] server name
2214 **
2215 ** @return [AjPList] Tag-value list
2216 **
2217 ** @release 6.5.0
2218 ** @@
2219 ******************************************************************************/
2220
ajNamDbGetAttrlistSvr(const AjPStr name,const AjPStr svrname)2221 AjPList ajNamDbGetAttrlistSvr(const AjPStr name, const AjPStr svrname)
2222 {
2223 AjPList ret = NULL;
2224 AjPTagval tagval = NULL;
2225 NamPEntry svdata = NULL;
2226 NamPEntry fnew = NULL;
2227 const AjPTable dbtable = NULL;
2228 const AjPTable svtable = NULL;
2229 const char* dbattr = NULL;
2230 NamOAttr attr;
2231 void* dbvalue;
2232 const AjPStr tmpstr;
2233 ajuint i;
2234 AjIList iter;
2235
2236 svdata = ajTableFetchmodS(namSvrDatabaseTable, svrname);
2237 if(!svdata)
2238 return NULL;
2239
2240 fnew = ajTableFetchmodS(svdata->data, name);
2241
2242 if(!fnew)
2243 return NULL;
2244
2245 ret = ajListNew();
2246 dbtable = (const AjPTable) fnew->data;
2247
2248 svdata = ajTableFetchmodS(namSvrMasterTable, svrname);
2249 svtable = svdata->data;
2250
2251 for(i=0; namDbAttrs[i].Name; i++)
2252 {
2253 attr = namDbAttrs[i];
2254 dbattr = attr.Name;
2255
2256 dbvalue = ajTableFetchmodC(dbtable, dbattr);
2257 if(!dbvalue)
2258 dbvalue = ajTableFetchmodC(svtable, dbattr);
2259
2260 if(dbvalue)
2261 {
2262 switch(attr.Type)
2263 {
2264 case ATTR_LIST:
2265 iter = ajListIterNewread(dbvalue);
2266
2267 while(!ajListIterDone(iter))
2268 {
2269 tmpstr = ajListIterGet(iter);
2270 tagval = ajTagvalNewC(dbattr, MAJSTRGETPTR(tmpstr));
2271 ajListPushAppend(ret, tagval);
2272 }
2273
2274 ajListIterDel(&iter);
2275 break;
2276 default:
2277 tagval = ajTagvalNewC(dbattr, ajStrGetPtr(dbvalue));
2278 ajListPushAppend(ret, tagval);
2279 break;
2280 }
2281 }
2282 }
2283
2284 return ret;
2285
2286 }
2287
2288
2289
2290
2291 /* @funcstatic namDbtablePutAttrS *********************************************
2292 **
2293 ** Store the value for a database attribute
2294 **
2295 ** @param [u] dbtable [AjPTable] Database attribute table
2296 ** @param [u] Pattribute [AjPStr *] database attribute name
2297 ** @param [u] Pvalue [AjPStr*] attribute value
2298 **
2299 ** @return [AjBool] true if found
2300 **
2301 ** @release 6.4.0
2302 ** @@
2303 ******************************************************************************/
2304
namDbtablePutAttrS(AjPTable dbtable,AjPStr * Pattribute,AjPStr * Pvalue)2305 static AjBool namDbtablePutAttrS(AjPTable dbtable, AjPStr *Pattribute,
2306 AjPStr *Pvalue)
2307 {
2308 void *oldval;
2309 NamPAttr attr;
2310 AjPList fdlist = NULL;
2311
2312 attr = ajTableFetchmodS(namDbAttrTable, *Pattribute);
2313 namUser("store db attr '%S' => '%S'\n", *Pattribute, *Pvalue);
2314
2315 switch(attr->Type)
2316 {
2317 case ATTR_LIST:
2318 fdlist = ajTableFetchmodS(dbtable, *Pattribute);
2319
2320 if(!fdlist)
2321 {
2322 fdlist = ajListstrNew();
2323 ajTablePut(dbtable, (AjPStr) *Pattribute, (AjPList) fdlist);
2324 *Pattribute = NULL;
2325 }
2326 else
2327 ajStrDel(Pattribute);
2328
2329 ajListstrPushAppend(fdlist, *Pvalue);
2330 break;
2331
2332 default:
2333 oldval = ajTablePut(dbtable, (AjPStr) *Pattribute,
2334 (AjPStr) *Pvalue);
2335 if(oldval)
2336 ajWarn("duplicate db keyword value for '%S' = '%S'",
2337 *Pattribute, (AjPStr) oldval);
2338
2339 *Pattribute = NULL;
2340 break;
2341 }
2342
2343 *Pvalue = NULL;
2344
2345 return ajTrue;
2346 }
2347
2348
2349
2350
2351 /* @funcstatic namRstablePutAttrS *********************************************
2352 **
2353 ** Store the value for a resource attribute
2354 **
2355 ** @param [u] rstable [AjPTable] Resource attribute table
2356 ** @param [u] Pattribute [AjPStr*] resource attribute name
2357 ** @param [u] Pvalue [AjPStr*] attribute value
2358 **
2359 ** @return [AjBool] true if found
2360 **
2361 ** @release 6.4.0
2362 ** @@
2363 ******************************************************************************/
2364
namRstablePutAttrS(AjPTable rstable,AjPStr * Pattribute,AjPStr * Pvalue)2365 static AjBool namRstablePutAttrS(AjPTable rstable, AjPStr *Pattribute,
2366 AjPStr *Pvalue)
2367 {
2368 void *oldval;
2369 NamPAttr attr;
2370 AjPList fdlist = NULL;
2371
2372 attr = ajTableFetchmodS(namResAttrTable, *Pattribute);
2373 namUser("store resource attr '%S' => '%S\n", *Pattribute, *Pvalue);
2374
2375 if(!attr)
2376 ajTablePut(rstable, (AjPStr) *Pattribute,
2377 (AjPStr) *Pvalue);
2378 else
2379 {
2380 switch(attr->Type)
2381 {
2382 case ATTR_LIST:
2383 fdlist = ajTableFetchmodS(rstable, *Pattribute);
2384
2385 if(!fdlist)
2386 {
2387 fdlist = ajListstrNew();
2388 ajTablePut(rstable, (AjPStr) *Pattribute, (AjPList) fdlist);
2389 *Pattribute = NULL;
2390 }
2391 else
2392 ajStrDel(Pattribute);
2393
2394 ajListstrPushAppend(fdlist, *Pvalue);
2395 break;
2396
2397 default:
2398 oldval = ajTablePut(rstable, (AjPStr) *Pattribute,
2399 (AjPStr) *Pvalue);
2400 if(oldval)
2401 ajWarn("duplicate resource keyword value for '%S' = '%S'",
2402 *Pattribute, (AjPStr) oldval);
2403
2404 *Pattribute = NULL;
2405 break;
2406 }
2407 }
2408
2409 *Pvalue = NULL;
2410
2411 return ajTrue;
2412 }
2413
2414
2415
2416
2417 /* @funcstatic namSvrtablePutAttrS ********************************************
2418 **
2419 ** Store the value for a server attribute
2420 **
2421 ** @param [u] svrtable [AjPTable] Server attribute table
2422 ** @param [u] Pattribute [AjPStr*] server attribute name
2423 ** @param [u] Pvalue [AjPStr*] attribute value
2424 **
2425 ** @return [AjBool] true if found
2426 **
2427 ** @release 6.4.0
2428 ** @@
2429 ******************************************************************************/
2430
namSvrtablePutAttrS(AjPTable svrtable,AjPStr * Pattribute,AjPStr * Pvalue)2431 static AjBool namSvrtablePutAttrS(AjPTable svrtable, AjPStr *Pattribute,
2432 AjPStr *Pvalue)
2433 {
2434 void *oldval;
2435 NamPAttr attr;
2436 AjPList fdlist = NULL;
2437
2438 attr = ajTableFetchmodS(namSvrAttrTable, *Pattribute);
2439 namUser("store server attr '%S' => '%S\n", *Pattribute, *Pvalue);
2440
2441 switch(attr->Type)
2442 {
2443 case ATTR_LIST:
2444 fdlist = ajTableFetchmodS(svrtable, *Pattribute);
2445
2446 if(!fdlist)
2447 {
2448 fdlist = ajListstrNew();
2449 ajTablePut(svrtable, (AjPStr) *Pattribute, (AjPList) fdlist);
2450 *Pattribute = NULL;
2451 }
2452 else
2453 ajStrDel(Pattribute);
2454
2455 ajListstrPushAppend(fdlist, *Pvalue);
2456 break;
2457
2458 default:
2459 oldval = ajTablePut(svrtable, (AjPStr) *Pattribute,
2460 (AjPStr) *Pvalue);
2461 if(oldval)
2462 ajWarn("duplicate server keyword value for '%S' = '%S'",
2463 *Pattribute, (AjPStr) oldval);
2464
2465 *Pattribute = NULL;
2466 break;
2467 }
2468
2469 *Pvalue = NULL;
2470
2471 return ajTrue;
2472 }
2473
2474
2475
2476
2477 /* @func ajNamDbDetails *******************************************************
2478 **
2479 ** Returns database access method information
2480 **
2481 ** @param [r] name [const AjPStr] Database name
2482 ** @param [w] type [AjPStr*] sequence type
2483 ** @param [w] id [AjBool*] ajTrue = can access single entries
2484 ** @param [w] qry [AjBool*] ajTrue = can access wild/query entries
2485 ** @param [w] all [AjBool*] ajTrue = can access all entries
2486 ** @param [w] comment [AjPStr*] comment about database
2487 ** @param [w] release [AjPStr*] database release date
2488 ** @param [w] methods [AjPStr*] database access methods formatted
2489 ** @param [w] defined [AjPStr*] database definition file short name
2490 ** @return [AjBool] ajTrue if database details were found
2491 **
2492 ** @release 1.0.0
2493 ** @@
2494 ******************************************************************************/
2495
ajNamDbDetails(const AjPStr name,AjPStr * type,AjBool * id,AjBool * qry,AjBool * all,AjPStr * comment,AjPStr * release,AjPStr * methods,AjPStr * defined)2496 AjBool ajNamDbDetails(const AjPStr name, AjPStr* type, AjBool* id,
2497 AjBool* qry, AjBool* all,
2498 AjPStr* comment, AjPStr* release,
2499 AjPStr* methods, AjPStr* defined)
2500 {
2501 NamPEntry fnew = NULL;
2502 AjPTable dbtable = NULL;
2503 ajint i;
2504 ajint scope;
2505 AjPStr attrname = NULL;
2506 const AjPStr attrval = NULL;
2507 const AjPStr dbtype = NULL;
2508 AjBool typetested = ajFalse;
2509
2510 *id = *qry = *all = ajFalse;
2511
2512 ajStrDelStatic(type);
2513 ajStrDelStatic(comment);
2514 ajStrDelStatic(release);
2515 ajStrDelStatic(methods);
2516 ajStrDelStatic(defined);
2517
2518 fnew = ajTableFetchmodS(namDbMasterTable, name);
2519
2520 if(fnew)
2521 {
2522 ajDebug("ajNamDbDetails: '%S' found\n", name);
2523
2524 ajStrAssignS(defined, fnew->file);
2525
2526 dbtable = (AjPTable) fnew->data;
2527 dbtype = ajTableFetchmodC(dbtable, "type");
2528
2529 for(i=0; namDbAttrs[i].Name; i++)
2530 {
2531 if(namDbAttrs[i].Type != ATTR_STR)
2532 continue;
2533
2534 ajStrAssignC(&attrname, namDbAttrs[i].Name);
2535
2536 attrval = ajTableFetchmodS(dbtable, attrname);
2537 ajDebug("Attribute name = %S, value = %S\n",
2538 attrname, attrval);
2539
2540 if(ajStrGetLen(attrval))
2541 {
2542 if(ajStrMatchC(attrname, "type"))
2543 {
2544 if(ajStrMatchCaseC(attrval, "N"))
2545 ajStrAssignC(type, "Nucleotide");
2546 else if(ajStrMatchCaseC(attrval, "P"))
2547 ajStrAssignC(type, "Protein");
2548 else
2549 {
2550 ajStrAssignS(type, attrval);
2551 ajStrFmtCapital(type);
2552 }
2553
2554 typetested = ajTrue;
2555 }
2556
2557 if(ajStrMatchC(attrname, "method"))
2558 {
2559 scope = namMethod2Scope(attrval, dbtype);
2560
2561 if(scope & AJMETHOD_ENTRY)
2562 *id = ajTrue;
2563
2564 if(scope & AJMETHOD_QUERY)
2565 *qry = ajTrue;
2566
2567 if(scope & AJMETHOD_ALL)
2568 *all = ajTrue;
2569
2570 ajStrAppendS(methods, attrval);
2571 }
2572
2573 if(ajStrMatchC(attrname, "methodentry"))
2574 {
2575 scope = namMethod2Scope(attrval, dbtype);
2576
2577 if(scope & AJMETHOD_ENTRY)
2578 *id = ajTrue;
2579
2580 if(ajStrGetLen(*methods))
2581 ajStrAppendC(methods, ",");
2582
2583 ajStrAppendS(methods, attrval);
2584 ajStrAppendC(methods, "(id)");
2585 }
2586
2587 if(ajStrMatchC(attrname, "methodquery"))
2588 {
2589 scope = namMethod2Scope(attrval, dbtype);
2590
2591 if(scope & AJMETHOD_ENTRY)
2592 *id = ajTrue;
2593
2594 if(scope & AJMETHOD_QUERY)
2595 *qry = ajTrue;
2596
2597 if(ajStrGetLen(*methods))
2598 ajStrAppendC(methods, ",");
2599
2600 ajStrAppendS(methods, attrval);
2601 ajStrAppendC(methods, "(qry)");
2602 }
2603
2604 if(ajStrMatchC(attrname, "methodall"))
2605 {
2606 scope = namMethod2Scope(attrval, dbtype);
2607
2608 if(scope & AJMETHOD_ALL)
2609 *all = ajTrue;
2610
2611 if(ajStrGetLen(*methods))
2612 ajStrAppendC(methods, ",");
2613
2614 ajStrAppendS(methods, attrval);
2615 ajStrAppendC(methods, "(all)");
2616 }
2617
2618 if(ajStrMatchC(attrname, "comment"))
2619 ajStrAssignS(comment, attrval);
2620
2621 if(ajStrMatchC(attrname, "release"))
2622 ajStrAssignS(release, attrval);
2623 }
2624 }
2625
2626 if(!typetested)
2627 {
2628 ajDebug("Bad database definition for %S: No type. 'P' assumed\n",
2629 name);
2630 ajWarn("Bad database definition for %S: No type. 'P' assumed",
2631 name);
2632 ajStrAssignC(type, "P");
2633 }
2634
2635 if(!*id && !*qry && !*all)
2636 {
2637 ajDebug("Bad database definition for %S: No method(s) for access\n",
2638 name);
2639 ajWarn("Bad database definition for %S: No method(s) for access",
2640 name);
2641 }
2642
2643 ajStrDel(&attrname);
2644
2645 return ajTrue;
2646 }
2647
2648 ajDebug("ajNamDbDetails: FAILED '%S' not found\n", name);
2649
2650 ajStrDel(&attrname);
2651
2652 return ajFalse;
2653 }
2654
2655
2656
2657
2658 /* @func ajNamDbDetailsSvr ***************************************************
2659 **
2660 ** Returns database access method information for a database on a server
2661 **
2662 ** @param [r] name [const AjPStr] Database name
2663 ** @param [r] svrname [const AjPStr] Server name
2664 ** @param [w] type [AjPStr*] sequence type
2665 ** @param [w] id [AjBool*] ajTrue = can access single entries
2666 ** @param [w] qry [AjBool*] ajTrue = can access wild/query entries
2667 ** @param [w] all [AjBool*] ajTrue = can access all entries
2668 ** @param [w] comment [AjPStr*] comment about database
2669 ** @param [w] release [AjPStr*] database release date
2670 ** @param [w] methods [AjPStr*] database access methods formatted
2671 ** @param [w] defined [AjPStr*] database definition file short name
2672 ** @return [AjBool] ajTrue if database details were found
2673 **
2674 ** @release 6.5.0
2675 ** @@
2676 ******************************************************************************/
2677
ajNamDbDetailsSvr(const AjPStr name,const AjPStr svrname,AjPStr * type,AjBool * id,AjBool * qry,AjBool * all,AjPStr * comment,AjPStr * release,AjPStr * methods,AjPStr * defined)2678 AjBool ajNamDbDetailsSvr(const AjPStr name, const AjPStr svrname,
2679 AjPStr* type, AjBool* id,
2680 AjBool* qry, AjBool* all,
2681 AjPStr* comment, AjPStr* release,
2682 AjPStr* methods, AjPStr* defined)
2683 {
2684 const NamPEntry svdata = NULL;
2685 const NamPEntry dbdata = NULL;
2686 const AjPTable svrtable = NULL;
2687 const AjPTable dbtable = NULL;
2688 ajint i;
2689 ajint scope;
2690 AjPStr attrname = NULL;
2691 const AjPStr attrval = NULL;
2692 const AjPStr dbtype = NULL;
2693 const AjPStr svrtype = NULL;
2694 AjBool typetested = ajFalse;
2695
2696 *id = *qry = *all = ajFalse;
2697
2698 ajStrDelStatic(type);
2699 ajStrDelStatic(comment);
2700 ajStrDelStatic(release);
2701 ajStrDelStatic(methods);
2702 ajStrDelStatic(defined);
2703
2704 /* make sure we have read the server cache file */
2705
2706 if(!ajStrGetLen(svrname))
2707 {
2708 dbdata = ajTableFetchmodS(namDbMasterTable, name);
2709 }
2710 else
2711 {
2712 if(!ajNamDatabaseServer(name, svrname))
2713 return ajFalse;
2714
2715 svdata = ajTableFetchS(namSvrDatabaseTable, svrname);
2716 svrtable = (const AjPTable) svdata->data;
2717
2718 dbdata = ajTableFetchS(svrtable, name);
2719
2720 svdata = ajTableFetchS(namSvrMasterTable, svrname);
2721 svrtable = (const AjPTable) svdata->data;
2722
2723 svrtype = ajTableFetchmodC(svrtable, "type");
2724
2725 for(i=0; namSvrAttrs[i].Name; i++)
2726 {
2727 if(namSvrAttrs[i].Type != ATTR_STR)
2728 continue;
2729
2730 ajStrAssignC(&attrname, namSvrAttrs[i].Name);
2731
2732 attrval = ajTableFetchmodS(svrtable, attrname);
2733 ajDebug("Attribute name = %S, value = %S\n",
2734 attrname, attrval);
2735
2736 if(ajStrGetLen(attrval))
2737 {
2738 if(ajStrMatchC(attrname, "type"))
2739 {
2740 if(ajStrMatchCaseC(attrval, "N"))
2741 ajStrAssignC(type, "Nucleotide");
2742 else if(ajStrMatchCaseC(attrval, "P"))
2743 ajStrAssignC(type, "Protein");
2744 else
2745 {
2746 ajStrAssignS(type, attrval);
2747 ajStrFmtCapital(type);
2748 }
2749
2750 typetested = ajTrue;
2751 }
2752
2753 if(ajStrMatchC(attrname, "method"))
2754 {
2755 scope = namMethod2Scope(attrval, svrtype);
2756
2757 if(scope & AJMETHOD_ENTRY)
2758 *id = ajTrue;
2759
2760 if(scope & AJMETHOD_QUERY)
2761 *qry = ajTrue;
2762
2763 if(scope & AJMETHOD_ALL)
2764 *all = ajTrue;
2765
2766 ajStrAppendS(methods, attrval);
2767 }
2768
2769 if(ajStrMatchC(attrname, "methodentry"))
2770 {
2771 scope = namMethod2Scope(attrval, svrtype);
2772
2773 if(scope & AJMETHOD_ENTRY)
2774 *id = ajTrue;
2775
2776 if(ajStrGetLen(*methods))
2777 ajStrAppendC(methods, ",");
2778
2779 ajStrAppendS(methods, attrval);
2780 ajStrAppendC(methods, "(id)");
2781 }
2782
2783 if(ajStrMatchC(attrname, "methodquery"))
2784 {
2785 scope = namMethod2Scope(attrval, svrtype);
2786
2787 if(scope & AJMETHOD_ENTRY)
2788 *id = ajTrue;
2789
2790 if(scope & AJMETHOD_QUERY)
2791 *qry = ajTrue;
2792
2793 if(ajStrGetLen(*methods))
2794 ajStrAppendC(methods, ",");
2795
2796 ajStrAppendS(methods, attrval);
2797 ajStrAppendC(methods, "(qry)");
2798 }
2799
2800 if(ajStrMatchC(attrname, "methodall"))
2801 {
2802 scope = namMethod2Scope(attrval, svrtype);
2803
2804 if(scope & AJMETHOD_ALL)
2805 *all = ajTrue;
2806
2807 if(ajStrGetLen(*methods))
2808 ajStrAppendC(methods, ",");
2809
2810 ajStrAppendS(methods, attrval);
2811 ajStrAppendC(methods, "(all)");
2812 }
2813
2814 if(ajStrMatchC(attrname, "comment"))
2815 ajStrAssignS(comment, attrval);
2816
2817 if(ajStrMatchC(attrname, "release"))
2818 ajStrAssignS(release, attrval);
2819 }
2820 }
2821
2822 ajStrDel(&attrname);
2823 }
2824
2825
2826 if(dbdata)
2827 {
2828 ajDebug("ajNamDbDetails: '%S' found\n", name);
2829
2830 ajStrAssignS(defined, dbdata->file);
2831
2832 dbtable = (const AjPTable) dbdata->data;
2833 dbtype = ajTableFetchmodC(dbtable, "type");
2834 if(!dbtype)
2835 dbtype = svrtype;
2836
2837 for(i=0; namDbAttrs[i].Name; i++)
2838 {
2839 if(namDbAttrs[i].Type != ATTR_STR)
2840 continue;
2841
2842 ajStrAssignC(&attrname, namDbAttrs[i].Name);
2843
2844 attrval = ajTableFetchmodS(dbtable, attrname);
2845 ajDebug("Attribute name = %S, value = %S\n",
2846 attrname, attrval);
2847
2848 if(ajStrGetLen(attrval))
2849 {
2850 if(ajStrMatchC(attrname, "type"))
2851 {
2852 if(ajStrMatchCaseC(attrval, "N"))
2853 ajStrAssignC(type, "Nucleotide");
2854 else if(ajStrMatchC(attrval, "P"))
2855 ajStrAssignC(type, "Protein");
2856 else
2857 {
2858 ajStrAssignS(type, attrval);
2859 ajStrFmtCapital(type);
2860 }
2861
2862 typetested = ajTrue;
2863 }
2864
2865 if(ajStrMatchC(attrname, "method"))
2866 {
2867 scope = namMethod2Scope(attrval, dbtype);
2868
2869 if(scope & AJMETHOD_ENTRY)
2870 *id = ajTrue;
2871
2872 if(scope & AJMETHOD_QUERY)
2873 *qry = ajTrue;
2874
2875 if(scope & AJMETHOD_ALL)
2876 *all = ajTrue;
2877
2878 ajStrAppendS(methods, attrval);
2879 }
2880
2881 if(ajStrMatchC(attrname, "methodentry"))
2882 {
2883 scope = namMethod2Scope(attrval, dbtype);
2884
2885 if(scope & AJMETHOD_ENTRY)
2886 *id = ajTrue;
2887
2888 if(ajStrGetLen(*methods))
2889 ajStrAppendC(methods, ",");
2890
2891 ajStrAppendS(methods, attrval);
2892 ajStrAppendC(methods, "(id)");
2893 }
2894
2895 if(ajStrMatchC(attrname, "methodquery"))
2896 {
2897 scope = namMethod2Scope(attrval, dbtype);
2898
2899 if(scope & AJMETHOD_ENTRY)
2900 *id = ajTrue;
2901
2902 if(scope & AJMETHOD_QUERY)
2903 *qry = ajTrue;
2904
2905 if(ajStrGetLen(*methods))
2906 ajStrAppendC(methods, ",");
2907
2908 ajStrAppendS(methods, attrval);
2909 ajStrAppendC(methods, "(qry)");
2910 }
2911
2912 if(ajStrMatchC(attrname, "methodall"))
2913 {
2914 scope = namMethod2Scope(attrval, dbtype);
2915
2916 if(scope & AJMETHOD_ALL)
2917 *all = ajTrue;
2918
2919 if(ajStrGetLen(*methods))
2920 ajStrAppendC(methods, ",");
2921
2922 ajStrAppendS(methods, attrval);
2923 ajStrAppendC(methods, "(all)");
2924 }
2925
2926 if(ajStrMatchC(attrname, "comment"))
2927 ajStrAssignS(comment, attrval);
2928
2929 if(ajStrMatchC(attrname, "release"))
2930 ajStrAssignS(release, attrval);
2931 }
2932 }
2933
2934 if(!typetested)
2935 {
2936 ajDebug("Bad database definition for %S: No type. 'P' assumed\n",
2937 name);
2938 ajWarn("Bad database definition for %S: No type. 'P' assumed",
2939 name);
2940 ajStrAssignC(type, "P");
2941 }
2942
2943 if(!*id && !*qry && !*all)
2944 {
2945 ajDebug("Bad database definition for %S: No method(s) for access\n",
2946 name);
2947 ajWarn("Bad database definition for %S: No method(s) for access",
2948 name);
2949 }
2950
2951 ajStrDel(&attrname);
2952
2953 return ajTrue;
2954 }
2955
2956 ajDebug("ajNamDbDetails: FAILED '%S' not found\n", name);
2957
2958 ajStrDel(&attrname);
2959
2960 return ajFalse;
2961 }
2962
2963
2964
2965
2966 /* @funcstatic namAccessTest **************************************************
2967 **
2968 ** Tests whether a named access method is known for a given data type
2969 **
2970 ** @param [r] method [const AjPStr] Access method name
2971 ** @param [r] dbtype [const AjPStr] Database type
2972 ** @return [AjBool] True if found
2973 **
2974 ** @release 6.4.0
2975 ** @@
2976 ******************************************************************************/
2977
namAccessTest(const AjPStr method,const AjPStr dbtype)2978 static AjBool namAccessTest(const AjPStr method, const AjPStr dbtype)
2979 {
2980 AjBool result;
2981 NamPType namtype;
2982
2983 result = ajTextaccessMethodTest(method);
2984
2985 if(!result)
2986 {
2987 namtype = ajTableFetchmodS(namDbTypeTable, dbtype);
2988
2989 if(!namtype)
2990 return result;
2991
2992 if(namtype->DataType == AJDATATYPE_ASSEMBLY)
2993 result = ajAssemaccessMethodTest(method);
2994 else if(namtype->DataType == AJDATATYPE_FEATURES)
2995 result = ajFeattabaccessMethodTest(method);
2996 else if(namtype->DataType == AJDATATYPE_OBO)
2997 result = ajOboaccessMethodTest(method);
2998 else if(namtype->DataType == AJDATATYPE_REFSEQ)
2999 result = ajRefseqaccessMethodTest(method);
3000 else if(namtype->DataType == AJDATATYPE_RESOURCE)
3001 result = ajResourceaccessMethodTest(method);
3002 else if(namtype->DataType == AJDATATYPE_SEQUENCE)
3003 result = ajSeqaccessMethodTest(method);
3004 else if(namtype->DataType == AJDATATYPE_TAXON)
3005 result = ajTaxaccessMethodTest(method);
3006 else if(namtype->DataType == AJDATATYPE_URL)
3007 result = ajUrlaccessMethodTest(method);
3008 else if(namtype->DataType == AJDATATYPE_VARIATION)
3009 result = ajVaraccessMethodTest(method);
3010 else if(namtype->DataType == AJDATATYPE_XML)
3011 result = ajXmlaccessMethodTest(method);
3012 }
3013
3014 return result;
3015 }
3016
3017
3018
3019
3020 /* @funcstatic namInformatTest ************************************************
3021 **
3022 ** Tests whether a named data input format is known for a given data type
3023 **
3024 ** @param [r] format [const AjPStr] Format name
3025 ** @param [r] dbtype [const AjPStr] Database type
3026 ** @return [AjBool] True if found
3027 **
3028 ** @release 6.4.0
3029 ** @@
3030 ******************************************************************************/
3031
namInformatTest(const AjPStr format,const AjPStr dbtype)3032 static AjBool namInformatTest(const AjPStr format, const AjPStr dbtype)
3033 {
3034 AjBool result = ajFalse;
3035 NamPType namtype;
3036
3037 namtype = ajTableFetchmodS(namDbTypeTable, dbtype);
3038
3039 if(!namtype)
3040 return ajFalse;
3041
3042 ajDebug("namInformatTest format '%S' dbtype '%S' namtype '%s'\n",
3043 format, dbtype, namtype->Name);
3044
3045 if(namtype->DataType == AJDATATYPE_ASSEMBLY)
3046 result = ajAsseminformatTest(format);
3047 else if(namtype->DataType == AJDATATYPE_FEATURES)
3048 result = ajFeattabinformatTest(format);
3049 else if(namtype->DataType == AJDATATYPE_OBO)
3050 result = ajOboinformatTest(format);
3051 else if(namtype->DataType == AJDATATYPE_REFSEQ)
3052 result = ajRefseqinformatTest(format);
3053 else if(namtype->DataType == AJDATATYPE_RESOURCE)
3054 result = ajResourceinformatTest(format);
3055 else if(namtype->DataType == AJDATATYPE_SEQUENCE)
3056 result = ajSeqinformatTest(format);
3057 else if(namtype->DataType == AJDATATYPE_TAXON)
3058 result = ajTaxinformatTest(format);
3059 else if(namtype->DataType == AJDATATYPE_TEXT)
3060 result = ajTextinformatTest(format);
3061 else if(namtype->DataType == AJDATATYPE_URL)
3062 result = ajUrlinformatTest(format);
3063 else if(namtype->DataType == AJDATATYPE_VARIATION)
3064 result = ajVarinformatTest(format);
3065 else if(namtype->DataType == AJDATATYPE_XML)
3066 result = ajXmlinformatTest(format);
3067
3068 return result;
3069 }
3070
3071
3072
3073
3074 /* @funcstatic namMethod2Qlinks ***********************************************
3075 **
3076 ** Returns known query link operators
3077 ** for the various types of access method for databases.
3078 **
3079 ** @param [r] method [const AjPStr] Access method string
3080 ** @param [r] datatype [ajint] Enumerated database type
3081 ** @return [const char*] Query link operators
3082 **
3083 ** @release 6.4.0
3084 ** @@
3085 ******************************************************************************/
3086
namMethod2Qlinks(const AjPStr method,ajint datatype)3087 static const char* namMethod2Qlinks(const AjPStr method, ajint datatype)
3088 {
3089 const char* result = NULL;
3090
3091 result = ajTextaccessMethodGetQlinks(method);
3092
3093 if(ajCharMatchC(result, "DATA"))
3094 result = namDatatype2Qlinks(datatype);
3095
3096 ajDebug("namMethod2Qlinks method: '%S' datatype: %d text: '%s'\n",
3097 method, datatype, result);
3098
3099 if(datatype == AJDATATYPE_TEXT)
3100 return result;
3101
3102 if(!result)
3103 {
3104 if(datatype == AJDATATYPE_ASSEMBLY)
3105 result = ajAssemaccessMethodGetQlinks(method);
3106 else if(datatype == AJDATATYPE_FEATURES)
3107 result = ajFeattabaccessMethodGetQlinks(method);
3108 else if(datatype == AJDATATYPE_OBO)
3109 result = ajOboaccessMethodGetQlinks(method);
3110 else if(datatype == AJDATATYPE_RESOURCE)
3111 result = ajResourceaccessMethodGetQlinks(method);
3112 else if(datatype == AJDATATYPE_SEQUENCE)
3113 result = ajSeqaccessMethodGetQlinks(method);
3114 else if(datatype == AJDATATYPE_TAXON)
3115 result = ajTaxaccessMethodGetQlinks(method);
3116 else if(datatype == AJDATATYPE_URL)
3117 result = ajUrlaccessMethodGetQlinks(method);
3118 else if(datatype == AJDATATYPE_VARIATION)
3119 result = ajVaraccessMethodGetQlinks(method);
3120 else if(datatype == AJDATATYPE_XML)
3121 result = ajXmlaccessMethodGetQlinks(method);
3122 }
3123
3124 return result;
3125 }
3126
3127
3128
3129
3130 /* @funcstatic namMethod2Scope ************************************************
3131 **
3132 ** Returns OR'ed values of AJMETHOD_ENTRY, AJMETHOD_QUERY and AJMETHOD_ALL
3133 ** for the various types of access method for databases.
3134 **
3135 ** @param [r] method [const AjPStr] Access method string
3136 ** @param [r] dbtype [const AjPStr] Database type
3137 ** @return [ajuint] OR'ed values for the valid scope of the access method given
3138 **
3139 ** @release 1.0.0
3140 ** @@
3141 ******************************************************************************/
3142
namMethod2Scope(const AjPStr method,const AjPStr dbtype)3143 static ajuint namMethod2Scope(const AjPStr method, const AjPStr dbtype)
3144 {
3145 ajuint result = 0;
3146 NamPType namtype;
3147 AjPStrTok handle = NULL;
3148 AjPStr nexttype = NULL;
3149
3150 result = ajTextaccessMethodGetScope(method);
3151
3152 if(!result)
3153 {
3154 ajStrTokenAssignC(&handle, dbtype, " ,;");
3155
3156 while(ajStrTokenNextParse(handle, &nexttype))
3157 {
3158 namtype = ajTableFetchmodS(namDbTypeTable, nexttype);
3159
3160 if(!namtype)
3161 return result;
3162
3163 if(namtype->DataType == AJDATATYPE_ASSEMBLY)
3164 result |= ajAssemaccessMethodGetScope(method);
3165 else if(namtype->DataType == AJDATATYPE_FEATURES)
3166 result |= ajFeattabaccessMethodGetScope(method);
3167 else if(namtype->DataType == AJDATATYPE_OBO)
3168 result |= ajOboaccessMethodGetScope(method);
3169 else if(namtype->DataType == AJDATATYPE_REFSEQ)
3170 result |= ajRefseqaccessMethodGetScope(method);
3171 else if(namtype->DataType == AJDATATYPE_RESOURCE)
3172 result |= ajResourceaccessMethodGetScope(method);
3173 else if(namtype->DataType == AJDATATYPE_SEQUENCE)
3174 result |= ajSeqaccessMethodGetScope(method);
3175 else if(namtype->DataType == AJDATATYPE_TAXON)
3176 result |= ajTaxaccessMethodGetScope(method);
3177 else if(namtype->DataType == AJDATATYPE_URL)
3178 result |= ajUrlaccessMethodGetScope(method);
3179 else if(namtype->DataType == AJDATATYPE_VARIATION)
3180 result |= ajVaraccessMethodGetScope(method);
3181 else if(namtype->DataType == AJDATATYPE_XML)
3182 result |= ajXmlaccessMethodGetScope(method);
3183 }
3184 }
3185
3186 ajStrDel(&nexttype);
3187 ajStrTokenDel(&handle);
3188
3189 return result;
3190 }
3191
3192
3193
3194
3195 /* @funcstatic namDatatype2Fields *********************************************
3196 **
3197 ** Returns the list of fields that can be processed by the "Read"
3198 ** file parsing function for a specified datatype
3199 **
3200 ** @param [r] datatype [ajint] Enumerated data type
3201 ** @return [const char*] Field name list
3202 **
3203 ** @release 6.4.0
3204 ** @@
3205 ******************************************************************************/
3206
namDatatype2Fields(ajint datatype)3207 static const char* namDatatype2Fields(ajint datatype)
3208 {
3209 const char* result = NULL;
3210
3211 if(datatype == AJDATATYPE_ASSEMBLY)
3212 result = ajAsseminTypeGetFields();
3213 else if(datatype == AJDATATYPE_FEATURES)
3214 result = ajFeattabinTypeGetFields();
3215 else if(datatype == AJDATATYPE_OBO)
3216 result = ajOboinTypeGetFields();
3217 else if(datatype == AJDATATYPE_RESOURCE)
3218 result = ajResourceinTypeGetFields();
3219 else if(datatype == AJDATATYPE_SEQUENCE)
3220 result = ajSeqinTypeGetFields();
3221 else if(datatype == AJDATATYPE_TAXON)
3222 result = ajTaxinTypeGetFields();
3223 else if(datatype == AJDATATYPE_URL)
3224 result = ajUrlinTypeGetFields();
3225 else if(datatype == AJDATATYPE_VARIATION)
3226 result = ajVarinTypeGetFields();
3227 else if(datatype == AJDATATYPE_XML)
3228 result = ajXmlinTypeGetFields();
3229
3230 if(!result)
3231 result = ajTextinTypeGetFields();
3232
3233 return result;
3234 }
3235
3236
3237
3238
3239 /* @funcstatic namDatatype2Qlinks *********************************************
3240 **
3241 ** Returns the list of query links that can be processed by the "Read"
3242 ** file parsing function for a specified datatype
3243 **
3244 ** @param [r] datatype [ajint] Enumerated data type
3245 ** @return [const char*] Known query link operators
3246 **
3247 ** @release 6.4.0
3248 ** @@
3249 ******************************************************************************/
3250
namDatatype2Qlinks(ajint datatype)3251 static const char* namDatatype2Qlinks(ajint datatype)
3252 {
3253 const char* result = NULL;
3254
3255 if(datatype == AJDATATYPE_ASSEMBLY)
3256 result = ajAsseminTypeGetQlinks();
3257 else if(datatype == AJDATATYPE_FEATURES)
3258 result = ajFeattabinTypeGetQlinks();
3259 else if(datatype == AJDATATYPE_OBO)
3260 result = ajOboinTypeGetQlinks();
3261 else if(datatype == AJDATATYPE_RESOURCE)
3262 result = ajResourceinTypeGetQlinks();
3263 else if(datatype == AJDATATYPE_SEQUENCE)
3264 result = ajSeqinTypeGetQlinks();
3265 else if(datatype == AJDATATYPE_TAXON)
3266 result = ajTaxinTypeGetQlinks();
3267 else if(datatype == AJDATATYPE_URL)
3268 result = ajUrlinTypeGetQlinks();
3269 else if(datatype == AJDATATYPE_VARIATION)
3270 result = ajVarinTypeGetQlinks();
3271 else if(datatype == AJDATATYPE_XML)
3272 result = ajXmlinTypeGetQlinks();
3273
3274 if(!result)
3275 result = ajTextinTypeGetQlinks();
3276
3277 return result;
3278 }
3279
3280
3281
3282
3283 /* @func ajNamDebugOrigin *****************************************************
3284 **
3285 ** Writes a simple list of where the internal tables came from..
3286 **
3287 ** @return [void]
3288 **
3289 ** @release 1.13.0
3290 ** @@
3291 ******************************************************************************/
3292
ajNamDebugOrigin(void)3293 void ajNamDebugOrigin(void)
3294 {
3295 ajDebug("Defaults and .rc files: %S\n", namFileOrig);
3296
3297 return;
3298 }
3299
3300
3301
3302
3303 /* @func ajNamDebugServers ****************************************************
3304 **
3305 ** Writes a simple debug report of all servers in the internal table.
3306 **
3307 ** @return [void]
3308 **
3309 ** @release 6.4.0
3310 ** @@
3311 ******************************************************************************/
3312
ajNamDebugServers(void)3313 void ajNamDebugServers(void)
3314 {
3315 ajDebug("SERVER servers\n");
3316 ajDebug("==============\n");
3317 namDebugMaster(namSvrMasterTable, TYPE_SVR);
3318 ajDebug("[SVR done]\n\n");
3319
3320 return;
3321 }
3322
3323
3324
3325
3326 /* @func ajNamDebugDatabases **************************************************
3327 **
3328 ** Writes a simple debug report of all databases in the internal table.
3329 **
3330 ** @return [void]
3331 **
3332 ** @release 1.13.0
3333 ** @@
3334 ******************************************************************************/
3335
ajNamDebugDatabases(void)3336 void ajNamDebugDatabases(void)
3337 {
3338 ajDebug("DB databases\n");
3339 ajDebug("============\n");
3340 namDebugMaster(namDbMasterTable, TYPE_DB);
3341 ajDebug("[DB done]\n\n");
3342
3343 return;
3344 }
3345
3346
3347
3348
3349 /* @func ajNamDebugResources **************************************************
3350 **
3351 ** Writes a simple debug report of all databases in the internal table.
3352 **
3353 ** @return [void]
3354 **
3355 ** @release 2.7.0
3356 ** @@
3357 ******************************************************************************/
3358
ajNamDebugResources(void)3359 void ajNamDebugResources(void)
3360 {
3361 ajDebug("RES resources\n");
3362 ajDebug("=============\n");
3363 namDebugMaster(namResMasterTable, TYPE_RESOURCE);
3364 ajDebug("[RES done]\n\n");
3365
3366 return;
3367 }
3368
3369
3370
3371
3372 /* @func ajNamDebugVariables **************************************************
3373 **
3374 ** Writes a simple debug report of all environment variables
3375 ** in the internal table.
3376 **
3377 ** @return [void]
3378 **
3379 ** @release 2.7.0
3380 ** @@
3381 ******************************************************************************/
3382
ajNamDebugVariables(void)3383 void ajNamDebugVariables(void)
3384 {
3385 ajDebug("ENV variables\n");
3386 ajDebug("=============\n");
3387 namDebugMaster(namVarMasterTable, TYPE_ENV);
3388 ajDebug("[ENV done]\n\n");
3389
3390 return;
3391 }
3392
3393
3394
3395
3396 /* @func ajNamDebugAliases ****************************************************
3397 **
3398 ** Writes a simple debug report of all aliases
3399 ** in the internal table.
3400 **
3401 ** @return [void]
3402 **
3403 ** @release 6.4.0
3404 ** @@
3405 ******************************************************************************/
3406
ajNamDebugAliases(void)3407 void ajNamDebugAliases(void)
3408 {
3409 ajDebug("ALIAS names\n");
3410 ajDebug("=============\n");
3411 namDebugMaster(namAliasMasterTable, TYPE_ALIAS);
3412 ajDebug("[ALIAS done]\n\n");
3413
3414 return;
3415 }
3416
3417
3418
3419
3420 /* @func ajNamListListServers *************************************************
3421 **
3422 ** Creates a AjPList list of all servers in the internal table.
3423 **
3424 ** @param [w] svrnames [AjPList] Str List of names to be populated
3425 ** @return [void]
3426 **
3427 ** @release 6.4.0
3428 ** @@
3429 ******************************************************************************/
3430
ajNamListListServers(AjPList svrnames)3431 void ajNamListListServers(AjPList svrnames)
3432 {
3433 ajint i;
3434 NamPEntry fnew;
3435 void **valarray = NULL;
3436
3437 ajTableToarrayValues(namSvrMasterTable, &valarray);
3438 ajDebug("ajNamListListSevers\n");
3439
3440 for(i = 0; valarray[i]; i++)
3441 {
3442 fnew = (NamPEntry) valarray[i];
3443 ajDebug("SVR: %S\n", fnew->name);
3444 ajListstrPushAppend(svrnames, fnew->name);
3445 }
3446
3447 AJFREE(valarray);
3448
3449 return;
3450 }
3451
3452
3453
3454
3455 /* @func ajNamListFindAliases *************************************************
3456 **
3457 ** Creates a list of alias for a named database in the internal table.
3458 **
3459 ** @param [r] dbname [const AjPStr] Database name
3460 ** @param [w] dbnames [AjPList] Str List of names to be populated
3461 ** @return [void]
3462 **
3463 ** @release 6.6.0
3464 ** @@
3465 ******************************************************************************/
3466
ajNamListFindAliases(const AjPStr dbname,AjPList dbnames)3467 void ajNamListFindAliases(const AjPStr dbname, AjPList dbnames)
3468 {
3469 ajint i;
3470 NamPEntry fnew;
3471 AjPStr testname = ajStrNewS(dbname);
3472 void **valarray = NULL;
3473
3474 ajStrFmtLower(&testname);
3475
3476 ajTableToarrayValues(namAliasMasterTable, &valarray);
3477 ajDebug("ajNamListFindAliases '%S'\n", dbname);
3478
3479 for(i = 0; valarray[i]; i++)
3480 {
3481 fnew = (NamPEntry) valarray[i];
3482
3483 if(!ajStrMatchS(testname, fnew->value))
3484 continue;
3485
3486 ajDebug("ALIAS: %S %S\n", fnew->name, fnew->value);
3487 ajListstrPushAppend(dbnames, fnew->name);
3488 }
3489
3490 ajListSort(dbnames, ajStrVcmp);
3491
3492 ajStrDel(&testname);
3493 AJFREE(valarray);
3494
3495 return;
3496 }
3497
3498
3499
3500
3501 /* @func ajNamListListAliases *************************************************
3502 **
3503 ** Creates a AjPList list of all databases in the internal table.
3504 **
3505 ** @param [w] dbnames [AjPList] Str List of names to be populated
3506 ** @return [void]
3507 **
3508 ** @release 6.6.0
3509 ** @@
3510 ******************************************************************************/
3511
ajNamListListAliases(AjPList dbnames)3512 void ajNamListListAliases(AjPList dbnames)
3513 {
3514 ajint i;
3515 NamPEntry fnew;
3516 void **valarray = NULL;
3517
3518 ajTableToarrayValues(namAliasMasterTable, &valarray);
3519 ajDebug("ajNamListListAliases\n");
3520
3521 for(i = 0; valarray[i]; i++)
3522 {
3523 fnew = (NamPEntry) valarray[i];
3524 ajDebug("ALIAS: %S %S\n", fnew->name, fnew->value);
3525 ajListstrPushAppend(dbnames, fnew->name);
3526 }
3527
3528 ajListSort(dbnames, ajStrVcmp);
3529
3530 AJFREE(valarray);
3531
3532 return;
3533 }
3534
3535
3536
3537
3538 /* @func ajNamListListDatabases ***********************************************
3539 **
3540 ** Creates a AjPList list of all databases in the internal table.
3541 **
3542 ** @param [w] dbnames [AjPList] Str List of names to be populated
3543 ** @return [void]
3544 **
3545 ** @release 1.0.0
3546 ** @@
3547 ******************************************************************************/
3548
ajNamListListDatabases(AjPList dbnames)3549 void ajNamListListDatabases(AjPList dbnames)
3550 {
3551 ajint i;
3552 NamPEntry fnew;
3553 void **valarray = NULL;
3554
3555 ajTableToarrayValues(namDbMasterTable, &valarray);
3556 ajDebug("ajNamListListDatabases\n");
3557
3558 for(i = 0; valarray[i]; i++)
3559 {
3560 fnew = (NamPEntry) valarray[i];
3561 ajDebug("DB: %S\n", fnew->name);
3562 ajListstrPushAppend(dbnames, fnew->name);
3563 }
3564
3565 ajListSort(dbnames, ajStrVcmp);
3566
3567 AJFREE(valarray);
3568
3569 return;
3570 }
3571
3572
3573
3574
3575 /* @func ajNamListListResources ***********************************************
3576 **
3577 ** Creates a AjPList list of all databases in the internal table.
3578 **
3579 ** @param [w] rsnames [AjPList] Str List of names to be populated
3580 ** @return [void]
3581 **
3582 ** @release 2.7.0
3583 ** @@
3584 ******************************************************************************/
3585
ajNamListListResources(AjPList rsnames)3586 void ajNamListListResources(AjPList rsnames)
3587 {
3588 ajint i;
3589 NamPEntry fnew;
3590 void **valarray = NULL;
3591
3592 ajTableToarrayValues(namResMasterTable, &valarray);
3593
3594 for(i = 0; valarray[i]; i++)
3595 {
3596 fnew = (NamPEntry) valarray[i];
3597 ajDebug("RES: %S\n", fnew->name);
3598 ajListstrPushAppend(rsnames, fnew->name);
3599 }
3600
3601 AJFREE(valarray);
3602
3603 return;
3604 }
3605
3606
3607
3608
3609 /* @funcstatic namDebugVariables **********************************************
3610 **
3611 ** Writes a simple list of all variables in the internal table.
3612 **
3613 ** @return [void]
3614 **
3615 ** @release 2.7.0
3616 ** @@
3617 ******************************************************************************/
3618
namDebugVariables(void)3619 static void namDebugVariables(void)
3620 {
3621 namUser("ENV---------->\n");
3622 namDebugMaster(namVarMasterTable, TYPE_ENV);
3623 namUser("ENV---------->\n");
3624 namUser("\n");
3625
3626 return;
3627 }
3628
3629
3630
3631
3632 /* @funcstatic namDebugAliases ************************************************
3633 **
3634 ** Writes a simple list of all aliases in the internal table.
3635 **
3636 ** @return [void]
3637 **
3638 ** @release 6.4.0
3639 ** @@
3640 ******************************************************************************/
3641
namDebugAliases(void)3642 static void namDebugAliases(void)
3643 {
3644 namUser("ALIAS---------->\n");
3645 namDebugMaster(namAliasMasterTable, TYPE_ALIAS);
3646 namUser("ALIAS---------->\n");
3647 namUser("\n");
3648
3649 return;
3650 }
3651
3652
3653
3654
3655 /* @funcstatic namListParse ***************************************************
3656 **
3657 ** Parse the text in a list of tokens read from the input file.
3658 ** Derive environment variable and database definitions. Store
3659 ** all these in the internal tables.
3660 **
3661 ** @param [u] listwords [AjPList] String list of word tokens to parse
3662 ** @param [u] listcount [AjPList] List of word counts per line for
3663 ** generating error messages
3664 ** @param [u] file [AjPFile] Input file only for name in messages
3665 ** @param [r] shortname [const AjPStr] Definition file short name
3666 ** @return [void]
3667 **
3668 ** @release 1.0.0
3669 ** @@
3670 ******************************************************************************/
3671
namListParse(AjPList listwords,AjPList listcount,AjPFile file,const AjPStr shortname)3672 static void namListParse(AjPList listwords, AjPList listcount,
3673 AjPFile file, const AjPStr shortname)
3674 {
3675 static char* tabname = NULL;
3676 static AjPStr name = NULL;
3677 AjPStr value = NULL;
3678 static NamPAttr attrvalue = NULL;
3679 static char quoteopen = '\0';
3680 static char quoteclose = '\0';
3681 static AjPTable svattr = NULL;
3682 static AjPTable dbattr = NULL;
3683 static AjPTable rsattr = NULL;
3684 static ajint svr_input = -1;
3685 static ajint db_input = -1;
3686 static ajint rs_input = -1;
3687 AjPStr rs_name = NULL;
3688 AjPTable saveTable = NULL;
3689
3690 NamPEntry fnew = NULL;
3691 NamPEntry entry = NULL;
3692
3693 AjBool svrsave = ajFalse;
3694 AjBool dbsave = ajFalse;
3695 AjBool rssave = ajFalse;
3696 AjBool saveit = ajFalse;
3697 AjBool saveifblock = ajFalse;
3698 static ajint nsvrattr = 0;
3699 static ajint ndbattr = 0;
3700 static ajint ndbtype = 0;
3701 static ajint nrsattr = 0;
3702
3703 AjPStr includefn = NULL;
3704 AjPFile iinf = NULL;
3705 AjPStr key = NULL;
3706 AjPStr val = NULL;
3707 AjPStr oldval = NULL;
3708
3709 static AjPTable Ifiles = NULL;
3710 AjPStr curword = NULL;
3711
3712 ajint wordcount = 0;
3713 ajint linecount = 0;
3714 ajint lineword = 0;
3715 ajint *iword = NULL;
3716 AjBool namstatus;
3717 AjPStr saveshortname = NULL;
3718 AjPStr saveword = NULL;
3719 AjPStr teststr = NULL;
3720
3721 namUser("namListParse shortname: '%S'\n", shortname);
3722
3723 /* ndbtype = count database types*/
3724 if(!ndbtype)
3725 {
3726 if(!namDbTypeTable)
3727 namDbTypeTable = ajTablestrNewCase(30);
3728
3729 for(ndbtype=0; namDbTypes[ndbtype].Name; ndbtype++)
3730 {
3731 name = ajStrNewC(namDbTypes[ndbtype].Name);
3732 ajTablePut(namDbTypeTable, name, &namDbTypes[ndbtype]);
3733 }
3734
3735 name = NULL;
3736 }
3737
3738 /* nsvrattr = count server attributes */
3739 if(!nsvrattr)
3740 {
3741 if(!namSvrAttrTable)
3742 namSvrAttrTable = ajTablestrNew(30);
3743
3744 for(nsvrattr=0; namSvrAttrs[nsvrattr].Name; nsvrattr++)
3745 {
3746 name = ajStrNewC(namSvrAttrs[nsvrattr].Name);
3747 attrvalue = &namSvrAttrs[nsvrattr];
3748 oldval = ajTablePut(namSvrAttrTable, name, attrvalue);
3749 namUser("store server default '%S' => '%s\n",
3750 name, attrvalue->Defval);
3751
3752 if(oldval)
3753 {
3754 ajWarn("duplicate server attr value for '%S' = '%S'",
3755 name, oldval);
3756 ajStrDel(&oldval);
3757 }
3758 }
3759
3760 name = NULL;
3761 value = NULL;
3762 }
3763
3764 /* ndbattr = count database attributes */
3765 if(!ndbattr)
3766 {
3767 if(!namDbAttrTable)
3768 namDbAttrTable = ajTablestrNew(30);
3769
3770 for(ndbattr=0; namDbAttrs[ndbattr].Name; ndbattr++)
3771 {
3772 name = ajStrNewC(namDbAttrs[ndbattr].Name);
3773 attrvalue = &namDbAttrs[ndbattr];
3774 oldval = ajTablePut(namDbAttrTable, name, attrvalue);
3775 namUser("store database default '%S' => '%s\n",
3776 name, attrvalue->Defval);
3777
3778 if(oldval)
3779 {
3780 ajWarn("duplicate db attr value for '%S' = '%S'",
3781 name, oldval);
3782 ajStrDel(&oldval);
3783 }
3784 }
3785
3786 name = NULL;
3787 value = NULL;
3788 }
3789
3790 /* nrsattr = count resource attributes */
3791 if(!nrsattr)
3792 {
3793 if(!namResAttrTable)
3794 namResAttrTable = ajTablestrNew(30);
3795
3796 for(nrsattr=0; namRsAttrs[nrsattr].Name; nrsattr++)
3797 {
3798 name = ajStrNewC(namRsAttrs[nrsattr].Name);
3799 attrvalue = &namRsAttrs[nrsattr];
3800 oldval = ajTablePut(namResAttrTable, name, attrvalue);
3801 namUser("store resource default '%S' => '%s\n",
3802 name, attrvalue->Defval);
3803
3804 if(oldval)
3805 {
3806 ajWarn("duplicate res attr value for '%S' = '%S'",
3807 name, oldval);
3808 ajStrDel(&oldval);
3809 }
3810 }
3811
3812 name = NULL;
3813 value = NULL;
3814 }
3815
3816 ajStrAssignS(&saveshortname, shortname);
3817 ajStrDel(&name);
3818 ajStrDel(&value);
3819 quoteopen = '\0';
3820 quoteclose = '\0';
3821
3822 namLine = 1;
3823 namUser("namListParse of %F '%S' words: %Lu lines: %Lu\n",
3824 file, name, ajListGetLength(listwords), ajListGetLength(listcount));
3825
3826 while(ajListstrPop(listwords, &curword))
3827 {
3828 while(ajListGetLength(listcount) && (lineword < wordcount))
3829 {
3830 namUser("ajListPop %d < %d list %Lu\n",
3831 lineword, wordcount, ajListGetLength(listcount));
3832 ajListPop(listcount, (void**) &iword);
3833 lineword = *iword;
3834 linecount++;
3835 namLine = linecount-1;
3836 AJFREE(iword);
3837 }
3838
3839 wordcount++;
3840
3841 namUser("namListParse word: %d line: %d (%d) <%S>\n",
3842 wordcount, namLine, lineword, curword);
3843
3844 if(!namParseType)
3845 {
3846 namNoColon(&curword);
3847 ajStrFmtLower(&curword);
3848
3849 if(ajCharPrefixS("env", curword))
3850 namParseType = TYPE_ENV;
3851 else if(ajCharPrefixS("setenv", curword))
3852 namParseType = TYPE_ENV;
3853 else if(ajCharPrefixS("server",curword))
3854 namParseType = TYPE_SVR;
3855 else if(ajCharPrefixS("dbname",curword))
3856 namParseType = TYPE_DB;
3857 else if(ajCharPrefixS("resource",curword))
3858 namParseType = TYPE_RESOURCE;
3859 else if(ajCharPrefixS("alias",curword))
3860 namParseType = TYPE_ALIAS;
3861 else if(ajCharPrefixS("include",curword))
3862 namParseType = TYPE_IFILE;
3863 else if(ajCharPrefixS("if",curword))
3864 {
3865 namParseType = TYPE_IF;
3866 saveifblock = ajFalse;
3867 }
3868 else if(ajCharPrefixS("ifdef",curword))
3869 {
3870 namParseType = TYPE_IFDEF;
3871 saveifblock = ajFalse;
3872 }
3873 else if(ajCharPrefixS("else",curword))
3874 namParseType = TYPE_ELSE;
3875 else if(ajCharPrefixS("endif",curword))
3876 namParseType = TYPE_ENDIF;
3877
3878 if(!namParseType) /* test: badtype.rc */
3879 namError("Invalid definition type '%S'", curword);
3880
3881 namUser("type set to %s curword '%S'\n",
3882 namTypes[namParseType], curword);
3883 }
3884 else if(quoteopen && ajStrMatchC(curword, "]"))
3885 { /* test; dbnoquote.rc */
3886 namError("']' found, unclosed quotes in '%S'", value);
3887 quoteopen = '\0';
3888 namParseType = 0;
3889 }
3890 else if(quoteopen)
3891 {
3892 /*
3893 ** quote is open, so append word until close quote is found,
3894 ** and set the appropriate save flag
3895 */
3896 namUser("<%c>..<%c> quote processing\n", quoteopen, quoteclose);
3897 ajStrAppendC(&value," ");
3898 ajStrAppendS(&value,curword);
3899
3900 /* close quote here ?? */
3901 if(ajStrGetCharLast(curword) == quoteclose)
3902 {
3903 namUser("close quotes\n");
3904 ajStrCutEnd(&value, 1);
3905 quoteopen = quoteclose = '\0';
3906
3907 if(namParseType == TYPE_ENV) /* set save flag, value found */
3908 saveit = ajTrue;
3909 else if(namParseType == TYPE_SVR)
3910 svrsave = ajTrue;
3911 else if(namParseType == TYPE_DB)
3912 dbsave = ajTrue;
3913 else if(namParseType == TYPE_RESOURCE)
3914 rssave = ajTrue;
3915 else if(namParseType == TYPE_ALIAS)
3916 saveit = ajTrue;
3917 else if(namParseType == TYPE_IFDEF)
3918 saveifblock = ajTrue;
3919 else if(namParseType == TYPE_IF)
3920 saveifblock = ajTrue;
3921 }
3922 }
3923 else if(namParseType == TYPE_IF || namParseType == TYPE_IFDEF )
3924 {
3925 if(ajStrGetCharFirst(curword) == '\'')
3926 quoteopen = quoteclose = '\'';
3927 else if(ajStrGetCharFirst(curword) == '\"')
3928 quoteopen = quoteclose = '\"';
3929
3930 ajStrAssignS(&value, curword);
3931
3932 if(quoteopen)
3933 {
3934 /* trim the opening quote */
3935 ajStrCutStart(&value, 1);
3936
3937 if(!ajStrGetLen(value))
3938 ajErr("Bare quote %c found in namListParse",
3939 quoteopen);
3940 }
3941 else
3942 saveifblock = ajTrue;
3943
3944 if(ajStrGetCharLast(curword) == quoteclose)
3945 {
3946 /* end of quote on same word */
3947 quoteopen = quoteclose = '\0';
3948 /* remove quote at the end */
3949 ajStrCutEnd(&value, 1);
3950 saveifblock = ajTrue;
3951 }
3952
3953 namUser("if: save value '%S' saveif: %B\n", value, saveifblock);
3954 }
3955 else if(namParseType == TYPE_ENV)
3956 {
3957 if(name && value)
3958 saveit= ajTrue;
3959 else if(name)
3960 {
3961 /* if name already got then it must be the value */
3962 if(ajStrGetCharFirst(curword) == '\'')
3963 quoteopen = quoteclose = '\'';
3964 else if(ajStrGetCharFirst(curword) == '\"')
3965 quoteopen = quoteclose = '\"';
3966
3967 ajStrAssignS(&value, curword);
3968
3969 if(quoteopen)
3970 {
3971 /* trim the opening quote */
3972 ajStrCutStart(&value, 1);
3973
3974 if(!ajStrGetLen(value))
3975 ajErr("Bare quote %c found in namListParse",
3976 quoteopen);
3977 }
3978 else
3979 saveit = ajTrue;
3980
3981 if(ajStrGetCharLast(curword) == quoteclose)
3982 {
3983 /* end of quote on same word */
3984 quoteopen = quoteclose = '\0';
3985 saveit= ajTrue;
3986 /* remove quote at the end */
3987 ajStrCutEnd(&value, 1);
3988 }
3989
3990 if(saveit)
3991 ajNamResolve(&value);
3992 namUser("save value '%S' saveit: %B\n", value, saveit);
3993 }
3994 else
3995 {
3996 ajStrAssignS(&name, curword);
3997 namUser("save name '%S'\n", name);
3998 }
3999 }
4000
4001 else if(namParseType == TYPE_ALIAS)
4002 {
4003 namUser("ALIAS saveit: %B name: '%S' value '%S' "
4004 "quoteopen: '%c'\n",
4005 saveit, name, value, quoteopen);
4006 if(name && value)
4007 saveit= ajTrue;
4008 else if(name)
4009 {
4010 /* if name already got then it must be the value */
4011 if(ajStrGetCharFirst(curword) == '\'')
4012 quoteopen = quoteclose = '\'';
4013 else if(ajStrGetCharFirst(curword) == '\"')
4014 quoteopen = quoteclose = '\"';
4015
4016 ajStrAssignS(&value, curword);
4017
4018 if(quoteopen)
4019 {
4020 /* trim the opening quote */
4021 ajStrCutStart(&value, 1);
4022
4023 if(!ajStrGetLen(value))
4024 ajErr("Bare quote %c found in namListParse",
4025 quoteopen);
4026 }
4027 else
4028 saveit = ajTrue;
4029
4030 if(ajStrGetCharLast(curword) == quoteclose)
4031 {
4032 /* end of quote on same word */
4033 quoteopen = quoteclose = '\0';
4034 saveit= ajTrue;
4035 /* remove quote at the end */
4036 ajStrCutEnd(&value, 1);
4037 }
4038
4039 if(saveit)
4040 ajNamResolve(&value);
4041 namUser("save alias value '%S' saveit: %B\n", value, saveit);
4042 }
4043 else
4044 {
4045 ajStrAssignS(&name, curword);
4046 namUser("save alias name '%S'\n", name);
4047 }
4048 }
4049
4050
4051 else if(namParseType == TYPE_SVR)
4052 {
4053 if(ajStrMatchC(curword, "[")) /* [ therefore new server */
4054 svattr = ajTablestrNew(100); /* new server obj */
4055 else if(ajStrMatchC(curword, "]")) /* ] therefore end of server */
4056 saveit = ajTrue;
4057 else if(name)
4058 {
4059 if(svr_input >= 0)
4060 {
4061 /* So if keyword type has been set */
4062 if(ajStrGetCharFirst(curword) == '\'')
4063 {
4064 /* is there a quote? If so expect the */
4065 /* same at the end. No ()[] etc here*/
4066 quoteopen = quoteclose = '\'';
4067 }
4068 else if(ajStrGetCharFirst(curword) == '\"')
4069 quoteopen = quoteclose = '\"';
4070
4071 ajStrAssignS(&value, curword);
4072
4073 if(quoteopen)
4074 {
4075 ajStrCutStart(&value, 1); /* trim opening quote */
4076
4077 if(!ajStrGetLen(value))
4078 ajErr("Bare quote %c found in namListParse",
4079 quoteopen);
4080 }
4081 else
4082 svrsave = ajTrue; /* we are done - simple word */
4083
4084 if(ajStrGetCharLast(curword) == quoteclose)
4085 {
4086 quoteopen = quoteclose = '\0';
4087 ajStrCutEnd(&value,1); /* trim closing quote */
4088 svrsave = ajTrue;
4089 }
4090
4091 if(!quoteopen) /* if we just reset it above */
4092 svrsave = ajTrue;
4093
4094 if(svrsave)
4095 ajNamResolve(&value);
4096 }
4097 else if(ajStrGetCharLast(curword) == ':')
4098 {
4099 /* if last character is : then its a keyword */
4100 ajStrFmtLower(&curword); /* make it lower case */
4101 namNoColon(&curword);
4102 svr_input = namSvrAttrS(curword);
4103
4104 if(svr_input < 0)
4105 ajWarn("%F: bad attribute '%S' for server '%S'",
4106 file, curword, name);
4107 }
4108 else
4109 {
4110 ajWarn("%F: unexpected token '%S' for server '%S'",
4111 file, curword, name);
4112 }
4113 }
4114 else
4115 {
4116 ajStrAssignS(&name, curword);
4117
4118 if(!ajNamIsDbname(name))
4119 ajErr("Invalid server name '%S'", name);
4120
4121 namUser("saving svr name '%S'\n", name);
4122 }
4123 }
4124
4125 else if(namParseType == TYPE_DB)
4126 {
4127 if(ajStrMatchC(curword, "[")) /* [ therefore new database */
4128 dbattr = ajTablestrNew(100); /* new db obj */
4129 else if(ajStrMatchC(curword, "]")) /* ] therefore end of db */
4130 saveit = ajTrue;
4131 else if(name)
4132 {
4133 if(db_input >= 0)
4134 {
4135 /* So if keyword type has been set */
4136 if(ajStrGetCharFirst(curword) == '\'')
4137 {
4138 /* is there a quote? If so expect the */
4139 /* same at the end. No ()[] etc here*/
4140 quoteopen = quoteclose = '\'';
4141 }
4142 else if(ajStrGetCharFirst(curword) == '\"')
4143 quoteopen = quoteclose = '\"';
4144
4145 ajStrAssignS(&value, curword);
4146
4147 if(quoteopen)
4148 {
4149 ajStrCutStart(&value, 1); /* trim opening quote */
4150
4151 if(!ajStrGetLen(value))
4152 ajErr("Bare quote %c found in namListParse",
4153 quoteopen);
4154 }
4155 else
4156 dbsave = ajTrue; /* we are done - simple word */
4157
4158 if(ajStrGetCharLast(curword) == quoteclose)
4159 {
4160 quoteopen = quoteclose = '\0';
4161 ajStrCutEnd(&value,1); /* trim closing quote */
4162 dbsave = ajTrue;
4163 }
4164
4165 if(!quoteopen) /* if we just reset it above */
4166 dbsave = ajTrue;
4167
4168 if(dbsave)
4169 ajNamResolve(&value);
4170 }
4171 else if(ajStrGetCharLast(curword) == ':')
4172 {
4173 /* if last character is : then its a keyword */
4174 ajStrFmtLower(&curword); /* make it lower case */
4175 namNoColon(&curword);
4176 db_input = namDbAttrS(curword);
4177
4178 if(db_input < 0)
4179 ajWarn("%F: bad attribute '%S' for database '%S'",
4180 file, curword, name);
4181 }
4182 else
4183 {
4184 ajWarn("%F: unexpected token '%S' for database '%S'",
4185 file, curword, name);
4186 }
4187 }
4188 else
4189 {
4190 ajStrAssignS(&name, curword);
4191
4192 if(!ajNamIsDbname(name))
4193 ajErr("Invalid database name '%S'", name);
4194
4195 namUser("saving db name '%S'\n", name);
4196 }
4197 }
4198
4199
4200 else if(namParseType == TYPE_RESOURCE)
4201 {
4202 if(ajStrMatchC(curword, "[")) /* [ therefore new resource */
4203 rsattr = ajTablestrNew(100); /* new resource*/
4204 else if(ajStrMatchC(curword, "]")) /* ] end of resource */
4205 saveit = ajTrue;
4206 else if(name)
4207 {
4208 /* if last character is : */
4209 if(ajStrGetCharLast(curword) == ':')
4210 { /* then it is a keyword */
4211 ajStrFmtLower(&curword); /* make it lower case */
4212 namNoColon(&curword);
4213 rs_input = namRsAttrS(curword);
4214 ajStrDel(&rs_name);
4215
4216 if(rs_input < 0) /* test: badresattr.rc */
4217 {
4218 if(namRsAttrFieldS(rsattr, curword))
4219 {
4220 rs_name = ajStrNewRef(curword);
4221 }
4222 else
4223 namError("Bad attribute '%S' for resource '%S'",
4224 curword, name);
4225 }
4226 }
4227 else if(rs_name || rs_input >= 0)
4228 { /* So if keyword type has been set */
4229 if(ajStrGetCharFirst(curword) == '\'')
4230 { /* is there a quote? If so expect the */
4231 /* same at the end. No ()[] etc here */
4232 quoteopen = quoteclose = '\'';
4233 }
4234 else if(ajStrGetCharFirst(curword) == '\"')
4235 quoteopen = quoteclose = '\"';
4236
4237 ajStrAssignS(&value, curword);
4238
4239 if(quoteopen)
4240 {
4241 ajStrCutStart(&value, 1); /* trim opening quote */
4242
4243 if(!ajStrGetLen(value))
4244 ajErr("Bare quote %c found in namListParse",
4245 quoteopen);
4246 }
4247 else
4248 rssave = ajTrue;
4249
4250 if(ajStrGetCharLast(curword) == quoteclose)
4251 {
4252 quoteopen = quoteclose = '\0';
4253 ajStrCutEnd(&value,1); /* ignore quote if */
4254 /* one at end */
4255 rssave = ajTrue;
4256 }
4257
4258 if(!quoteopen)
4259 rssave = ajTrue;
4260 }
4261
4262 if(rssave)
4263 ajNamResolve(&value);
4264 }
4265 else
4266 {
4267 ajStrAssignS(&name, curword);
4268 namUser("saving resource name '%S'\n", name);
4269 }
4270 }
4271
4272
4273 else if(namParseType == TYPE_IFILE)
4274 {
4275 if(!Ifiles)
4276 Ifiles = ajTablestrNew(NAM_INCLUDE_ESTIMATE);
4277 namParseType = 0;
4278
4279 ajStrAssignS(&saveword, curword);
4280
4281 ajNamResolve(&curword);
4282
4283 if(ajTableFetchmodS(Ifiles,curword)) /* test: includeagain.rc */
4284 {
4285 if(ajStrMatchS(curword, saveword))
4286 namError("%S already read ... skipping", curword);
4287 else
4288 namError("%S (%S) already read ... skipping",
4289 saveword, curword);
4290 }
4291 else
4292 {
4293 includefn = ajStrNew();
4294 ajStrAssignS(&includefn,curword);
4295
4296 if(namFileOrig)
4297 ajStrAppendC(&namFileOrig,", ");
4298 ajStrAppendS(&namFileOrig,includefn);
4299
4300 key = ajStrNewS(includefn);
4301 val = ajStrNewS(includefn);
4302 oldval = ajTablePut(Ifiles,key,val);
4303 namUser("store file '%S' => '%S\n", key, val);
4304
4305 if(oldval)
4306 {
4307 ajWarn("duplicate include value for '%S' = '%S'",
4308 key, oldval);
4309 ajStrDel(&key);
4310 ajStrDel(&oldval);
4311 }
4312
4313 /* test: badinclude.rc */
4314 if(!(iinf = ajFileNewInNameS(includefn)))
4315 {
4316 if(ajStrMatchS(includefn, saveword))
4317 namError("Failed to open include file '%S'",
4318 includefn);
4319 else
4320 namError("Failed to open include file '%S' (%S)",
4321 saveword, includefn);
4322 ajStrAppendC(&namFileOrig,"(Failed)");
4323 }
4324 else
4325 {
4326 ajStrAppendC(&namFileOrig,"(OK)");
4327 /* replaces namFile */
4328 ajStrAssignS(&name, includefn);
4329 ajFilenameTrimPath(&name);
4330 namstatus = namProcessFile(iinf, name);
4331 ajFmtPrintS(&namFileName, "%F",file);/* reset saved name */
4332 namLine = linecount-1;
4333
4334 if(!namstatus) /* test: badsummary.rc */
4335 {
4336 if(ajStrMatchS(includefn, saveword))
4337 namError("Error(s) found in included file %F",
4338 iinf);
4339 else
4340 namError("Error(s) found in included file %S (%F)",
4341 saveword, iinf);
4342 }
4343
4344
4345 ajFileClose(&iinf);
4346 }
4347
4348 ajStrDel(&includefn);
4349 }
4350
4351 namListParseOK = ajTrue;
4352 }
4353
4354
4355 if(svrsave)
4356 {
4357 /* Save the keyword value */
4358 key = ajStrNewC(namSvrAttrs[svr_input].Name);
4359 namUser("store svr attr '%S' => '%S\n", key, value);
4360 namSvrtablePutAttrS(svattr, &key, &value);
4361
4362 svr_input =-1;
4363 svrsave = ajFalse;
4364 }
4365
4366 if(dbsave)
4367 {
4368 /* Save the keyword value */
4369 key = ajStrNewC(namDbAttrs[db_input].Name);
4370 namDbtablePutAttrS(dbattr, &key, &value);
4371
4372 db_input =-1;
4373 dbsave = ajFalse;
4374 }
4375
4376 if(rssave)
4377 {
4378 if(rs_input >= 0)
4379 /* Save the keyword value */
4380 key = ajStrNewC(namRsAttrs[rs_input].Name);
4381 else
4382 key = ajStrNewS(rs_name);
4383 namUser("store resource attr '%S' => '%S\n", key, value);
4384 namRstablePutAttrS(rsattr, &key, &value);
4385
4386 rs_input =-1;
4387 ajStrDel(&rs_name);
4388 rssave = ajFalse;
4389 }
4390
4391 namListParseOK = saveit;
4392
4393 if(namParseType == TYPE_ENDIF)
4394 {
4395 if(!namIfBlock)
4396 {
4397 namError("endif not in if-block");
4398 }
4399 else
4400 {
4401 --namIfBlock;
4402 ajListPop(namIfList, (void**) &namIfValue);
4403 namUser("endif restore %B (block %u)\n",
4404 namIfValue, namIfBlock);
4405
4406 if(*namIfValue)
4407 namIfNow = ajTrue;
4408 else
4409 namIfNow = ajFalse;
4410 }
4411 namUser("endif %B (block %u)\n", namIfNow, /* FIXME teststr, */ namIfBlock);
4412 ajStrDel(&teststr);
4413 namParseType = 0;
4414 namListParseOK = ajTrue;
4415 }
4416 else if(namParseType == TYPE_ELSE)
4417 {
4418 namIfNow = !namIfNow;
4419 namUser("else %B (block %u)\n", namIfNow, namIfBlock);
4420 namParseType = 0;
4421 namListParseOK = ajTrue;
4422 }
4423
4424 if(saveifblock)
4425 {
4426 if(namParseType == TYPE_IF || namParseType == TYPE_IFDEF )
4427 {
4428 ajNamResolve(&value);
4429
4430 namUser("if: '%S'\n", value);
4431
4432 if(!namIfList)
4433 namIfList = ajListNew();
4434
4435 if(namIfNow)
4436 ajListPush(namIfList, (void*) &namTrue);
4437 else
4438 ajListPush(namIfList, (void*) &namFalse);
4439
4440 ++namIfBlock;
4441
4442 if(namParseType == TYPE_IF)
4443 {
4444 ajNamGetValueS(value, &teststr);
4445 namUser("if '%S' '%S'\n", value, teststr);
4446 if(!ajStrToBool(teststr, &namIfNow))
4447 namIfNow = ajFalse;
4448 }
4449 else
4450 {
4451 namUser("ifdef '%S'\n", value);
4452 if(ajNamGetValueS(value, &teststr))
4453 namIfNow = ajTrue;
4454 else
4455 namIfNow = ajFalse;
4456 }
4457
4458 namUser("if value '%S' '%S' %B (block %u)\n",
4459 value, teststr, namIfNow, namIfBlock);
4460 namParseType = 0;
4461 ajStrDel(&teststr);
4462 namListParseOK = ajTrue;
4463 ajStrDel(&value);
4464 }
4465 saveifblock = ajFalse;
4466 }
4467
4468 else if(saveit)
4469 {
4470 if(!namIfNow)
4471 {
4472 namUser("skipping type %d name '%S' value '%S' line:%d\n",
4473 namParseType, name, value, namLine);
4474 ajStrDel(&name);
4475 saveTable = NULL;
4476
4477 namSvrAttrtableFree(&svattr);
4478 namDbAttrtableFree(&dbattr);
4479 namRsAttrtableFree(&rsattr);
4480 }
4481 else
4482 {
4483 namUser("saving type %d name '%S' value '%S' line:%d\n",
4484 namParseType, name, value, namLine);
4485 AJNEW0(fnew);
4486 tabname = ajCharNewS(name);
4487 fnew->name = name;
4488 name = NULL;
4489 fnew->value = value;
4490 value = NULL;
4491 fnew->file = ajStrNewRef(saveshortname);
4492
4493 if(namParseType == TYPE_SVR)
4494 {
4495 fnew->data = (AjPTable) svattr;
4496 saveTable = namSvrMasterTable;
4497 svattr = NULL;
4498 }
4499 else if(namParseType == TYPE_DB)
4500 {
4501 fnew->data = (AjPTable) dbattr;
4502 saveTable = namDbMasterTable;
4503 dbattr = NULL;
4504 }
4505 else if(namParseType == TYPE_RESOURCE)
4506 {
4507 fnew->data = (AjPTable) rsattr;
4508 saveTable = namResMasterTable;
4509 rsattr = NULL;
4510 }
4511 else if(namParseType == TYPE_ENV)
4512 {
4513 fnew->data = NULL;
4514 saveTable = namVarMasterTable;
4515 }
4516 else if(namParseType == TYPE_ALIAS)
4517 {
4518 fnew->data = NULL;
4519 saveTable = namAliasMasterTable;
4520 }
4521 else
4522 {
4523 fnew->data = NULL;
4524 }
4525
4526 /* Validate the master table entry */
4527
4528 if(namDoValid)
4529 namValid(fnew, namParseType);
4530
4531 /*
4532 ** Add new one to table
4533 ** be very careful that everything in the table
4534 ** is not about to be deallocated - so do not use "name" here
4535 */
4536
4537 entry = ajTablePut(saveTable, tabname, fnew);
4538 namUser("store entry '%s' '%S' (%S)\n",
4539 tabname, fnew->name, fnew->file);
4540 if(entry)
4541 {
4542 /* it existed so over wrote previous table entry
4543 ** Only a namUser message - redefining EMBOSSRC in
4544 ** QA testing can give too many warnings
4545 */
4546 namUser("namTypes: [%d] '%s'\n",
4547 namParseType, namTypes[namParseType]);
4548 namUser("shortname: '%S'\n",
4549 shortname);
4550 namUser("entry: '%S' in file '%S'\n",
4551 entry->name, entry->file);
4552 namUser("%S: replaced %s %S definition from %S\n",
4553 shortname,
4554 namTypes[namParseType],
4555 entry->name,
4556 entry->file);
4557 namEntryDelete(&entry, namParseType); /* previous entry */
4558 }
4559 }
4560
4561 saveit = ajFalse;
4562 namParseType = 0;
4563 saveTable = NULL;
4564 }
4565
4566 ajStrDel(&curword);
4567 }
4568
4569 if(namParseType)
4570 {
4571 /* test: badset.rc baddb.rc */
4572 namError("Unexpected end of file in %s definition",
4573 namTypes[namParseType]);
4574 namParseType = 0;
4575 }
4576
4577 if(ajListGetLength(listcount)) /* cleanup the wordcount list */
4578 {
4579 namUser("** remaining wordcount items: %lu\n",
4580 ajListGetLength(listcount));
4581
4582 while(ajListGetLength(listcount))
4583 {
4584 ajListPop(listcount, (void**) &iword);
4585 AJFREE(iword);
4586 }
4587 }
4588
4589 if(value)
4590 namUser("++ namListParse value %x '%S'", value, value);
4591
4592 ajStrDel(&saveword);
4593 ajStrDel(&saveshortname);
4594 ajTablestrFree(&Ifiles);
4595
4596 return;
4597 }
4598
4599
4600
4601
4602 /* @func ajNamIsDbname ********************************************************
4603 **
4604 ** Returns true if the name is a valid database (or server) name.
4605 **
4606 ** Database names must start with a letter, and have 1 or more letters,
4607 ** numbers or underscores. No other characters are permitted.
4608 **
4609 ** @param [r] name [const AjPStr] character string to find in getenv list
4610 ** @return [AjBool] True if name was defined.
4611 **
4612 ** @release 3.0.0
4613 ** @@
4614 **
4615 ******************************************************************************/
4616
ajNamIsDbname(const AjPStr name)4617 AjBool ajNamIsDbname(const AjPStr name)
4618 {
4619 const char* cp = ajStrGetPtr(name);
4620
4621 if (!*cp)
4622 return ajFalse;
4623
4624 if (!isalpha((int)*cp++))
4625 return ajFalse;
4626
4627 if (!*cp)
4628 return ajFalse;
4629
4630 while (*cp)
4631 {
4632 if(!isalnum((int)*cp) && (*cp != '_'))
4633 return ajFalse;
4634
4635 cp++;
4636 }
4637
4638 return ajTrue;
4639 }
4640
4641
4642
4643
4644 /* @func ajNamGetenvC *********************************************************
4645 **
4646 ** Looks for name as an environment variable.
4647 ** the AjPStr for this in "value". If not found returns value as NULL;
4648 **
4649 ** @param [r] name [const char*] character string to find in getenv list
4650 ** @param [w] value [AjPStr*] String for the value.
4651 ** @return [AjBool] True if name was defined.
4652 **
4653 ** @release 2.9.0
4654 ** @@
4655 **
4656 ******************************************************************************/
4657
ajNamGetenvC(const char * name,AjPStr * value)4658 AjBool ajNamGetenvC(const char* name,
4659 AjPStr* value)
4660 {
4661 char *envval;
4662
4663 envval = getenv(name);
4664
4665 if(envval)
4666 {
4667 ajStrAssignC(value, envval);
4668
4669 return ajTrue;
4670 }
4671
4672 ajStrDel(value);
4673
4674 return ajFalse;
4675 }
4676
4677
4678
4679
4680 /* @func ajNamGetenvS *********************************************************
4681 **
4682 ** Looks for name as an environment variable.
4683 ** the AjPStr for this in "value". If not found returns NULL;
4684 **
4685 ** @param [r] name [const AjPStr] character string to find in getenv list
4686 ** @param [w] value [AjPStr*] String for the value.
4687 ** @return [AjBool] True if name was defined.
4688 **
4689 ** @release 6.1.0
4690 ** @@
4691 **
4692 ******************************************************************************/
4693
ajNamGetenvS(const AjPStr name,AjPStr * value)4694 AjBool ajNamGetenvS(const AjPStr name,
4695 AjPStr* value)
4696 {
4697 return ajNamGetenvC(ajStrGetPtr(name), value);
4698 }
4699
4700
4701
4702
4703 /* @func ajNamGetAliasC *******************************************************
4704 **
4705 ** Looks for name as an alias in the hash table and if found returns
4706 ** the AjPStr for this in "value". If not found returns NULL;
4707 **
4708 ** @param [r] name [const char*] character string find in hash table.
4709 ** @param [w] value [AjPStr*] Str for the value.
4710 ** @return [AjBool] True if name was defined.
4711 **
4712 ** @release 6.4.0
4713 ** @@
4714 **
4715 ******************************************************************************/
4716
ajNamGetAliasC(const char * name,AjPStr * value)4717 AjBool ajNamGetAliasC(const char* name, AjPStr* value)
4718 {
4719 NamPEntry fnew = NULL;
4720
4721 fnew = ajTableFetchmodC(namAliasMasterTable, name);
4722
4723 if(fnew)
4724 {
4725 ajDebug("Found alias '%s' value '%S' (%S)\n",
4726 name, fnew->value, fnew->file);
4727 ajStrAssignS(value, fnew->value);
4728
4729 return ajTrue;
4730 }
4731
4732 return ajFalse;
4733 }
4734
4735
4736
4737
4738 /* @func ajNamGetAliasS *******************************************************
4739 **
4740 ** Looks for name as an alias in the hash table and if found returns
4741 ** the AjPStr for this in "value". If not found returns NULL;
4742 **
4743 ** @param [r] namestr [const AjPStr] character string find in hash table.
4744 ** @param [w] value [AjPStr*] Str for the value.
4745 ** @return [AjBool] True if name was defined.
4746 **
4747 ** @release 6.4.0
4748 ** @@
4749 **
4750 ******************************************************************************/
4751
ajNamGetAliasS(const AjPStr namestr,AjPStr * value)4752 AjBool ajNamGetAliasS(const AjPStr namestr, AjPStr* value)
4753 {
4754 NamPEntry fnew = NULL;
4755
4756 fnew = ajTableFetchmodS(namAliasMasterTable, namestr);
4757
4758 if(fnew)
4759 {
4760 ajDebug("Found alias '%S' value '%S' (%S)\n",
4761 namestr, fnew->value, fnew->file);
4762 ajStrAssignS(value, fnew->value);
4763
4764 return ajTrue;
4765 }
4766
4767 return ajFalse;
4768 }
4769
4770
4771
4772
4773 /* @func ajNamGetValueC *******************************************************
4774 **
4775 ** Looks for name as an (upper case) environment variable,
4776 ** and then as-is in the hash table and if found returns
4777 ** the AjPStr for this in "value". If not found returns NULL;
4778 **
4779 ** @param [r] name [const char*] character string find in hash table.
4780 ** @param [w] value [AjPStr*] Str for the value.
4781 ** @return [AjBool] True if name was defined.
4782 **
4783 ** @release 1.0.0
4784 ** @@
4785 **
4786 ******************************************************************************/
4787
ajNamGetValueC(const char * name,AjPStr * value)4788 AjBool ajNamGetValueC(const char* name, AjPStr* value)
4789 {
4790 NamPEntry fnew = NULL;
4791 AjBool hadPrefix = ajFalse;
4792 AjBool ret = ajFalse;
4793
4794 ajDebug("ajNamGetValueC '%s'\n", name);
4795
4796 if(ajCharPrefixCaseS(name, namPrefixStr)) /* may already have the prefix */
4797 {
4798 ajStrAssignC(&namValNameTmp, name);
4799 hadPrefix = ajTrue;
4800 }
4801 else
4802 {
4803 ajStrAssignS(&namValNameTmp, namPrefixStr);
4804 ajStrAppendC(&namValNameTmp, name);
4805 }
4806
4807 /* upper case for ENV, otherwise don't care */
4808 ajStrFmtUpper(&namValNameTmp);
4809
4810 ajDebug("ajNamGetValueC search for '%S': ", namValNameTmp);
4811
4812 /* first test for an ENV variable */
4813
4814 ret = ajNamGetenvS(namValNameTmp, value);
4815
4816 if(ret)
4817 {
4818 ajDebug("Found environment variable value '%S'\n", *value);
4819 return ajTrue;
4820 }
4821
4822 /* then test the table definitions - with the prefix */
4823
4824 fnew = ajTableFetchmodS(namVarMasterTable, namValNameTmp);
4825
4826 if(fnew)
4827 {
4828 ajDebug("Found %S prefix set variable '%S' value '%S' (%S)\n",
4829 namPrefixStr, namValNameTmp, fnew->value, fnew->file);
4830 ajStrAssignS(value, fnew->value);
4831
4832 return ajTrue;
4833 }
4834
4835 if(!hadPrefix)
4836 {
4837
4838 /* then test the table definitions - as originally specified */
4839
4840 fnew = ajTableFetchmodC(namVarMasterTable, name);
4841
4842 if(fnew)
4843 {
4844 ajDebug("Found %S noprefix set variable '%s' value '%S' (%S)\n",
4845 namPrefixStr, name, fnew->value, fnew->file);
4846 ajStrAssignS(value, fnew->value);
4847
4848 return ajTrue;
4849 }
4850 }
4851
4852 if(ajStrMatchC(namValNameTmp, "EMBOSS_INSTALLDIRECTORY"))
4853 {
4854 ajStrAssignS(value, ajNamValueInstalldir());
4855 ajDebug("Found builtin variable '%S' value '%S'\n",
4856 namValNameTmp, *value);
4857 return ajTrue;
4858 }
4859
4860 if(ajStrMatchC(namValNameTmp, "EMBOSS_ROOTDIRECTORY"))
4861 {
4862 ajStrAssignS(value, ajNamValueRootdir());
4863 ajDebug("Found builtin variable '%S' value '%S'\n",
4864 namValNameTmp, *value);
4865 return ajTrue;
4866 }
4867
4868 if(ajStrMatchC(namValNameTmp, "EMBOSS_BASEDIRECTORY"))
4869 {
4870 ajStrAssignS(value, ajNamValueBasedir());
4871 ajDebug("Found builtin variable '%S' value '%S'\n",
4872 namValNameTmp, *value);
4873 return ajTrue;
4874 }
4875
4876 ajDebug("%S not found\n", namValNameTmp);
4877
4878 return ajFalse;
4879 }
4880
4881
4882
4883
4884 /* @func ajNamGetValueS *******************************************************
4885 **
4886 ** Looks for name as an (upper case) environment variable,
4887 ** and then as-is in the hash table and if found returns
4888 ** the AjPStr for this in "value". If not found returns NULL;
4889 **
4890 ** @param [r] name [const AjPStr] character string find in hash table.
4891 ** @param [w] value [AjPStr*] String for the value.
4892 ** @return [AjBool] True if name was defined.
4893 **
4894 ** @release 6.1.0
4895 ** @@
4896 **
4897 ******************************************************************************/
4898
ajNamGetValueS(const AjPStr name,AjPStr * value)4899 AjBool ajNamGetValueS(const AjPStr name, AjPStr* value)
4900 {
4901 return ajNamGetValueC(ajStrGetPtr(name), value);
4902 }
4903
4904
4905
4906
4907 /* @func ajNamServer **********************************************************
4908 **
4909 ** Looks for name in the server hash table and if found returns
4910 ** the attribute for this. If not found returns NULL;
4911 **
4912 ** @param [r] name [const AjPStr] character string find in hash table.
4913 ** @return [AjBool] true if server name is valid.
4914 ** @error NULL if name not found in the table
4915 **
4916 ** @release 6.4.0
4917 ** @@
4918 **
4919 ******************************************************************************/
4920
ajNamServer(const AjPStr name)4921 AjBool ajNamServer(const AjPStr name)
4922 {
4923 const NamPEntry fnew = NULL;
4924
4925 /* ajDebug("ajNamServer '%S'\n", name); */
4926
4927 fnew = ajTableFetchS(namSvrMasterTable, name);
4928
4929 if(fnew)
4930 {
4931 /* ajDebug(" '%S' found\n", name); */
4932 return ajTrue;
4933 }
4934
4935 /* ajDebug(" '%S' not found\n", name); */
4936 return ajFalse;
4937 }
4938
4939
4940
4941
4942 /* @func ajNamDatabase ********************************************************
4943 **
4944 ** Looks for name in the database hash table and if found returns
4945 ** true.
4946 **
4947 ** @param [r] name [const AjPStr] character string find in hash table.
4948 ** @return [AjBool] true if database name is valid.
4949 ** @error NULL if name not found in the table
4950 **
4951 ** @release 1.0.0
4952 ** @@
4953 **
4954 ******************************************************************************/
4955
ajNamDatabase(const AjPStr name)4956 AjBool ajNamDatabase(const AjPStr name)
4957 {
4958 const NamPEntry fnew = NULL;
4959
4960 /* ajDebug("ajNamDatabase '%S'\n", name); */
4961
4962 fnew = ajTableFetchS(namDbMasterTable, name);
4963
4964 if(fnew)
4965 {
4966 /* ajDebug(" '%S' found\n", name); */
4967 return ajTrue;
4968 }
4969
4970 /* ajDebug(" '%S' not found\n", name); */
4971 return ajFalse;
4972 }
4973
4974
4975
4976
4977 /* @func ajNamAliasDatabase ***************************************************
4978 **
4979 ** Looks for name in the database hash table and the database alias hash
4980 ** table and if found returns the true name for this. If not found
4981 ** returns false and leaves the original name unchanged
4982 **
4983 ** @param [u] Pname [AjPStr*] character string to find in hash table.
4984 ** @return [AjBool] true if database name is valid.
4985 **
4986 ** @release 6.4.0
4987 ** @@
4988 **
4989 ******************************************************************************/
4990
ajNamAliasDatabase(AjPStr * Pname)4991 AjBool ajNamAliasDatabase(AjPStr *Pname)
4992 {
4993 const NamPEntry fnew = NULL;
4994 AjPStr alias = NULL;
4995 const AjPStr tryname = *Pname;
4996
4997 /* ajDebug("ajNamAliasDatabase '%S'\n", *Pname); */
4998
4999 fnew = ajTableFetchS(namDbMasterTable, *Pname);
5000
5001 if(fnew)
5002 {
5003 /* ajDebug(" '%S' found\n", *Pname); */
5004 return ajTrue;
5005 }
5006
5007 while(ajNamGetAliasS(tryname, &alias))
5008 {
5009 fnew = ajTableFetchS(namDbMasterTable, alias);
5010 if(fnew)
5011 {
5012 ajStrAssignS(Pname, alias);
5013 /*ajDebug(" '%S' found as '%S'\n", name, alias);*/
5014 ajStrDel(&alias);
5015 return ajTrue;
5016 }
5017 tryname = alias;
5018 }
5019
5020 ajStrDel(&alias);
5021 /* ajDebug(" '%S' not found\n", name); */
5022 return ajFalse;
5023 }
5024
5025
5026
5027
5028 /* @func ajNamDatabaseServer **************************************************
5029 **
5030 ** Looks for a database name for a specific server.
5031 ** Reads the server cache file to find the database.
5032 **
5033 ** @param [r] name [const AjPStr] Database name to find for server
5034 ** @param [r] server [const AjPStr] Server name
5035 ** @return [AjBool] true if database name is valid.
5036 ** @error NULL if name not found in the table
5037 **
5038 ** @release 6.4.0
5039 ** @@
5040 **
5041 ******************************************************************************/
5042
ajNamDatabaseServer(const AjPStr name,const AjPStr server)5043 AjBool ajNamDatabaseServer(const AjPStr name, const AjPStr server)
5044 {
5045 AjBool ret = ajTrue;
5046 const NamPEntry svdata = NULL;
5047 const NamPEntry dbdata = NULL;
5048 const NamPEntry sdbdata = NULL;
5049 AjPTable svrtable;
5050 AjPTable dbtable;
5051 const AjPStr svrval = NULL;
5052 AjPStr cachefile = NULL;
5053
5054 ajDebug("ajNamDatabaseServer '%S' for server '%S'\n",
5055 name, server);
5056
5057 svdata = ajTableFetchS(namSvrMasterTable, server);
5058
5059 if(!svdata)
5060 {
5061 ajErr("Server '%S' not found, unable to search for database '%S'",
5062 server, name);
5063 return ajFalse;
5064 }
5065
5066 dbdata = ajTableFetchS(namSvrDatabaseTable,server);
5067
5068 if(!dbdata)
5069 {
5070
5071 /* pick up the cache file name for this server */
5072 svrtable = (AjPTable) svdata->data;
5073 svrval = ajTableFetchmodC(svrtable, "cachefile");
5074
5075 if(ajStrGetLen(svrval))
5076 cachefile = ajStrNewS(svrval);
5077 else
5078 {
5079 cachefile = ajStrNewC("server.");
5080 ajStrAppendS(&cachefile, server);
5081 }
5082
5083 namSvrCacheRead(server, cachefile);
5084 dbdata = ajTableFetchS(namSvrDatabaseTable, server);
5085
5086 ajStrDel(&cachefile);
5087 }
5088
5089 if(!dbdata)
5090 {
5091 ajWarn("Server '%S' has no databases", server);
5092 return ajFalse;
5093 }
5094
5095 dbtable = (AjPTable) dbdata->data;
5096 sdbdata = ajTableFetchS(dbtable, name);
5097
5098 if(!sdbdata)
5099 {
5100 ajWarn("Server '%S' has no database '%S'", server, name);
5101 return ajFalse;
5102 }
5103
5104 ajDebug("Found database '%S' on server '%S'\n", name, server);
5105
5106 /* ajDebug(" '%S' not found\n", name); */
5107 return ret;
5108 }
5109
5110
5111
5112
5113 /* @func ajNamAliasServer *****************************************************
5114 **
5115 ** Looks for a database name for a specific server.
5116 ** Reads the server cache file to find the database.
5117 **
5118 ** @param [u] Pname [AjPStr*] character string to find in hash table.
5119 ** @param [r] server [const AjPStr] Server name
5120 ** @return [AjBool] true if database name is valid.
5121 **
5122 ** @release 6.4.0
5123 ** @@
5124 **
5125 ******************************************************************************/
5126
ajNamAliasServer(AjPStr * Pname,const AjPStr server)5127 AjBool ajNamAliasServer(AjPStr *Pname, const AjPStr server)
5128 {
5129 const NamPEntry svdata = NULL;
5130 const NamPEntry dbdata = NULL;
5131 const NamPEntry sdbdata = NULL;
5132 const NamPEntry alidata = NULL;
5133 const NamPEntry salidata = NULL;
5134 AjPTable svrtable;
5135 AjPTable dbtable;
5136 AjPTable alitable;
5137 const AjPStr svrval = NULL;
5138 AjPStr cachefile = NULL;
5139 AjPStr alias = NULL;
5140 AjBool hasAlias = ajFalse;
5141
5142 ajDebug("ajNamAliasServer '%S' for server '%S'\n",
5143 *Pname, server);
5144
5145 svdata = ajTableFetchS(namSvrMasterTable, server);
5146
5147 if(!svdata)
5148 {
5149 ajErr("Server '%S' not found, unable to search for database '%S'",
5150 server, *Pname);
5151 return ajFalse;
5152 }
5153
5154 dbdata = ajTableFetchS(namSvrDatabaseTable,server);
5155 alidata = ajTableFetchS(namSvrAliasTable,server);
5156
5157 if(!dbdata)
5158 {
5159
5160 /* pick up the cache file name for this server */
5161 svrtable = (AjPTable) svdata->data;
5162 svrval = ajTableFetchmodC(svrtable, "cachefile");
5163
5164 if(ajStrGetLen(svrval))
5165 {
5166 cachefile = ajStrNewS(svrval);
5167 }
5168 else
5169 {
5170 cachefile = ajStrNewC("server.");
5171 ajStrAppendS(&cachefile, server);
5172 }
5173
5174 namSvrCacheRead(server, cachefile);
5175 dbdata = ajTableFetchS(namSvrDatabaseTable, server);
5176 alidata = ajTableFetchS(namSvrAliasTable, server);
5177
5178 ajStrDel(&cachefile);
5179 }
5180
5181 if(!dbdata)
5182 {
5183 ajWarn("Server '%S' has no databases", server);
5184 return ajFalse;
5185 }
5186
5187 ajStrAssignS(&alias, *Pname);
5188
5189 alitable = (AjPTable) alidata->data;
5190 salidata = ajTableFetchS(alitable, alias);
5191
5192 while(salidata)
5193 {
5194 hasAlias = ajTrue;
5195 ajStrAssignS(&alias,salidata->value);
5196 salidata = ajTableFetchS(alitable, alias);
5197 }
5198
5199 dbtable = (AjPTable) dbdata->data;
5200 sdbdata = ajTableFetchS(dbtable, alias);
5201 if(!sdbdata)
5202 {
5203 if(hasAlias)
5204 ajWarn("Server '%S' has no database '%S' (alias '%S')",
5205 server, *Pname, alias);
5206 else
5207 ajWarn("Server '%S' has no database '%S'", server, *Pname);
5208
5209 ajStrDel(&alias);
5210 return ajFalse;
5211 }
5212
5213 ajDebug("Found database '%S' (alias '%S') on server '%S'\n",
5214 *Pname, alias, server);
5215
5216 ajStrAssignS(Pname, alias);
5217
5218 ajStrDel(&alias);
5219
5220 return ajTrue;
5221 }
5222
5223
5224
5225
5226 /* @funcstatic namSvrCacheParse ***********************************************
5227 **
5228 ** Parses a database cachefile for a server
5229 **
5230 ** @param [u] cachefile [AjPFile] Cache file
5231 ** @param [u] dbtable [AjPTable] Database table for server
5232 ** @param [u] alitable [AjPTable] Alias table for server
5233 ** @return [AjBool] True on success
5234 **
5235 **
5236 ** @release 6.4.0
5237 ******************************************************************************/
5238
namSvrCacheParse(AjPFile cachefile,AjPTable dbtable,AjPTable alitable)5239 static AjBool namSvrCacheParse(AjPFile cachefile, AjPTable dbtable,
5240 AjPTable alitable)
5241 {
5242 AjBool ret = ajTrue;
5243 AjPStr rdline = NULL;
5244 AjPStr word = NULL;
5245 const char *ptr;
5246 ajint i = 0;
5247 ajint len;
5248 char quote = '\0';
5249 AjPList listwords;
5250 AjPList listcount;
5251 AjPStr wordptr;
5252 ajint iline = 0;
5253 ajint *k = NULL;
5254
5255 ajDebug("namSvrCacheParse '%F'\n", cachefile);
5256
5257 ajFmtPrintS(&namFileName, "%F",cachefile);
5258
5259 listwords = ajListstrNew();
5260 listcount = ajListNew();
5261 word = ajStrNewRes(128);
5262
5263 /* Read in the settings. */
5264 while(ajReadlineTrim(cachefile, &rdline))
5265 {
5266 iline++;
5267 AJNEW0(k);
5268 *k = (ajuint) ajListGetLength(listwords);
5269 ajListPushAppend(listcount, k);
5270
5271 if(!ajStrCutCommentsStart(&rdline))
5272 continue;
5273
5274 len = ajStrGetLen(rdline);
5275
5276 /* now create a linked list of the "words" */
5277 if(len)
5278 {
5279 ptr = ajStrGetPtr(rdline);
5280 i = 0;
5281
5282 while(*ptr && i < len)
5283 {
5284 if(*ptr == ' ' || *ptr == '\t')
5285 {
5286 if(ajStrGetLen(word))
5287 {
5288 wordptr = ajStrNewS(word);
5289 ajListstrPushAppend(listwords, wordptr);
5290 ajStrAssignClear(&word);
5291 }
5292
5293 i++;
5294 ptr++;
5295 continue;
5296 }
5297 else if(*ptr == '\'' || *ptr == '\"')
5298 {
5299 ajStrAppendK(&word,*ptr);
5300
5301 if(quote)
5302 {
5303 if(quote == *ptr)
5304 quote = '\0';
5305 }
5306 else
5307 quote = *ptr;
5308 }
5309 else if(!quote && ajStrGetLen(word) && *ptr == ']')
5310 {
5311 wordptr = ajStrNewS(word);
5312 ajListstrPushAppend(listwords, wordptr);
5313 ajStrAssignClear(&word);
5314 wordptr = ajStrNewC("]");
5315 ajListstrPushAppend(listwords, wordptr);
5316 ajStrAssignClear(&word);
5317 }
5318 else
5319 ajStrAppendK(&word,*ptr);
5320
5321 i++;
5322 ptr++;
5323 }
5324
5325 if(ajStrGetLen(word))
5326 {
5327 wordptr = ajStrNewS(word);
5328 ajListstrPushAppend(listwords, wordptr);
5329 ajStrAssignClear(&word);
5330 }
5331
5332 }
5333 }
5334
5335 ajStrDel(&rdline);
5336
5337 AJNEW0(k);
5338 *k = (ajuint) ajListGetLength(listwords);
5339 ajListPushAppend(listcount, k);
5340
5341 if(!namSvrCacheParseList(listwords, listcount, cachefile,
5342 dbtable, alitable))
5343 {
5344 ajErr("%F: Unexpected end of file in %S at line %d\n",
5345 cachefile, iline); /* FIXME */
5346 ret = ajFalse;
5347 }
5348
5349 ajListFree(&listwords);
5350 ajListFree(&listcount);
5351 ajStrDel(&word);
5352
5353 return ret;
5354 }
5355
5356
5357
5358
5359 /* @funcstatic namSvrCacheParseList *******************************************
5360 **
5361 ** Parse the text in a list of tokens read from the server cache file.
5362 ** Derive server database definitions. Store all these in the server's
5363 ** internal table.
5364 **
5365 ** @param [u] listwords [AjPList] String list of word tokens to parse
5366 ** @param [u] listcount [AjPList] List of word counts per line for
5367 ** generating error messages
5368 ** @param [u] cachefile [AjPFile] Input file only for name in messages
5369 ** @param [u] dbtable [AjPTable] Database table for server
5370 ** @param [u] alitable [AjPTable] Alias table for server
5371 ** @return [AjBool] True on success
5372 **
5373 ** @release 6.4.0
5374 ** @@
5375 ******************************************************************************/
5376
namSvrCacheParseList(AjPList listwords,AjPList listcount,AjPFile cachefile,AjPTable dbtable,AjPTable alitable)5377 static AjBool namSvrCacheParseList(AjPList listwords, AjPList listcount,
5378 AjPFile cachefile,
5379 AjPTable dbtable, AjPTable alitable)
5380 {
5381 static char* tabname = NULL;
5382 static AjPStr name = NULL;
5383 static AjPStr value = NULL;
5384 static char quoteopen = '\0';
5385 static char quoteclose = '\0';
5386 static AjPTable dbattr = NULL;
5387 static ajint db_input = -1;
5388 AjPTable saveTable = NULL;
5389
5390 NamPEntry fnew = NULL;
5391 NamPEntry entry = NULL;
5392
5393 AjPStr includefn = NULL;
5394 AjPFile iinf = NULL;
5395 AjPStr key = NULL;
5396 AjPStr val = NULL;
5397 AjPStr oldval = NULL;
5398 static AjPTable Ifiles = NULL;
5399 AjPStr curword = NULL;
5400
5401 ajint wordcount = 0;
5402 ajint linecount = 0;
5403 ajint lineword = 0;
5404 ajint *iword = NULL;
5405 AjBool namstatus;
5406 AjPStr saveshortname = NULL;
5407 AjPStr saveword = NULL;
5408
5409 AjBool dbsave = ajFalse;
5410 AjBool saveit = ajFalse;
5411
5412 ajFmtPrintS(&saveshortname, "%F", cachefile);
5413 quoteopen = '\0';
5414 quoteclose = '\0';
5415
5416 namLine = 1;
5417
5418 while(ajListstrPop(listwords, &curword))
5419 {
5420 while(ajListGetLength(listcount) && (lineword < wordcount))
5421 {
5422 namUser("ajListPop %d < %d list %Lu\n",
5423 lineword, wordcount, ajListGetLength(listcount));
5424 ajListPop(listcount, (void**) &iword);
5425 lineword = *iword;
5426 linecount++;
5427 namLine = linecount-1;
5428 AJFREE(iword);
5429 }
5430
5431 wordcount++;
5432
5433 if(!namParseType)
5434 {
5435 namNoColon(&curword);
5436 ajStrFmtLower(&curword);
5437
5438 if(ajCharPrefixS("dbname",curword))
5439 namParseType = TYPE_DB;
5440 if(ajCharPrefixS("alias",curword))
5441 namParseType = TYPE_ALIAS;
5442 else if(ajCharPrefixS("include",curword))
5443 namParseType = TYPE_IFILE;
5444
5445 if(!namParseType) /* test: badtype.rc */
5446 namError("Invalid definition type '%S'", curword);
5447 }
5448 else if(quoteopen && ajStrMatchC(curword, "]"))
5449 { /* test; dbnoquote.rc */
5450 namError("']' found, unclosed quotes in '%S'", value);
5451 quoteopen = '\0';
5452 namParseType = 0;
5453 }
5454 else if(quoteopen)
5455 {
5456 /*
5457 ** quote is open, so append word until close quote is found,
5458 ** and set the appropriate save flag
5459 */
5460 namUser("<%c>..<%c> quote processing\n", quoteopen, quoteclose);
5461 ajStrAppendC(&value," ");
5462 ajStrAppendS(&value,curword);
5463
5464 /* close quote here ?? */
5465 if(ajStrGetCharLast(curword) == quoteclose)
5466 {
5467 namUser("close quotes\n");
5468 ajStrCutEnd(&value, 1);
5469 quoteopen = quoteclose = '\0';
5470
5471 if(namParseType == TYPE_DB)
5472 dbsave = ajTrue;
5473 if(namParseType == TYPE_ALIAS)
5474 dbsave = ajTrue;
5475 }
5476 }
5477 else if(namParseType == TYPE_ALIAS)
5478 {
5479 namUser("CACHE ALIAS saveit: %B name: '%S' value '%S' "
5480 "quoteopen: '%c'\n",
5481 saveit, name, value, quoteopen);
5482 if(name && value)
5483 saveit= ajTrue;
5484 else if(name)
5485 {
5486 /* if name already got then it must be the value */
5487 if(ajStrGetCharFirst(curword) == '\'')
5488 quoteopen = quoteclose = '\'';
5489 else if(ajStrGetCharFirst(curword) == '\"')
5490 quoteopen = quoteclose = '\"';
5491
5492 ajStrAssignS(&value, curword);
5493
5494 if(quoteopen)
5495 {
5496 /* trim the opening quote */
5497 ajStrCutStart(&value, 1);
5498
5499 if(!ajStrGetLen(value))
5500 ajErr("Bare quote %c found in namListParse",
5501 quoteopen);
5502 }
5503 else
5504 saveit = ajTrue;
5505
5506 if(ajStrGetCharLast(curword) == quoteclose)
5507 {
5508 /* end of quote on same word */
5509 quoteopen = quoteclose = '\0';
5510 saveit= ajTrue;
5511 /* remove quote at the end */
5512 ajStrCutEnd(&value, 1);
5513 }
5514
5515 if(saveit)
5516 ajNamResolve(&value);
5517 namUser("save alias value '%S'\n", value);
5518 }
5519 else
5520 {
5521 ajStrAssignS(&name, curword);
5522 namUser("save alias name '%S'\n", name);
5523 }
5524 }
5525 else if(namParseType == TYPE_DB)
5526 {
5527 if(ajStrMatchC(curword, "[")) /* [ therefore new database */
5528 dbattr = ajTablestrNew(100); /* new db obj */
5529 else if(ajStrMatchC(curword, "]")) /* ] therefore end of db */
5530 saveit = ajTrue;
5531 else if(name)
5532 {
5533 if(db_input >= 0)
5534 {
5535 /* So if keyword type has been set */
5536 if(ajStrGetCharFirst(curword) == '\'')
5537 {
5538 /* is there a quote? If so expect the */
5539 /* same at the end. No ()[] etc here*/
5540 quoteopen = quoteclose = '\'';
5541 }
5542 else if(ajStrGetCharFirst(curword) == '\"')
5543 quoteopen = quoteclose = '\"';
5544
5545 ajStrAssignS(&value, curword);
5546
5547 if(quoteopen)
5548 {
5549 ajStrCutStart(&value, 1); /* trim opening quote */
5550
5551 if(!ajStrGetLen(value))
5552 ajErr("Bare quote %c found in namListParse",
5553 quoteopen);
5554 }
5555 else
5556 dbsave = ajTrue; /* we are done - simple word */
5557
5558 if(ajStrGetCharLast(curword) == quoteclose)
5559 {
5560 quoteopen = quoteclose = '\0';
5561 ajStrCutEnd(&value,1); /* trim closing quote */
5562 dbsave = ajTrue;
5563 }
5564
5565 if(!quoteopen) /* if we just reset it above */
5566 dbsave = ajTrue;
5567
5568 if(dbsave)
5569 ajNamResolve(&value);
5570 }
5571 else if(ajStrGetCharLast(curword) == ':')
5572 {
5573 /* if last character is : then its a keyword */
5574 ajStrFmtLower(&curword); /* make it lower case */
5575 namNoColon(&curword);
5576 db_input = namDbAttrS(curword);
5577
5578 if(db_input < 0)
5579 ajWarn("%F: bad attribute '%S' for database '%S'",
5580 cachefile, curword, name);
5581 }
5582 else
5583 {
5584 ajWarn("%F: unexpected token '%S' for database '%S'",
5585 cachefile, curword, name);
5586 }
5587 }
5588 else
5589 {
5590 ajStrAssignS(&name, curword);
5591
5592 if(!ajNamIsDbname(name))
5593 ajErr("Invalid database name '%S'", name);
5594
5595 namUser("saving db name '%S'\n", name);
5596 }
5597 }
5598
5599
5600 else if(namParseType == TYPE_IFILE)
5601 {
5602 if(!Ifiles)
5603 Ifiles = ajTablestrNew(NAM_INCLUDE_ESTIMATE);
5604
5605 namParseType = 0;
5606
5607 ajStrAssignS(&saveword, curword);
5608
5609 ajNamResolve(&curword);
5610
5611 if(ajTableFetchS(Ifiles,curword)) /* test: includeagain.rc */
5612 {
5613 if(ajStrMatchS(curword, saveword))
5614 namError("%S already read ... skipping", curword);
5615 else
5616 namError("%S (%S) already read ... skipping",
5617 saveword, curword);
5618 }
5619 else
5620 {
5621 includefn = ajStrNew();
5622 ajStrAssignS(&includefn,curword);
5623
5624 if(namFileOrig)
5625 ajStrAppendC(&namFileOrig,", ");
5626
5627 ajStrAppendS(&namFileOrig,includefn);
5628
5629 key = ajStrNewS(includefn);
5630 val = ajStrNewS(includefn);
5631 oldval = ajTablePut(Ifiles,key,val);
5632 namUser("store file '%S' => '%S\n", key, val);
5633
5634 if(oldval)
5635 {
5636 ajWarn("duplicate include value for '%S' = '%S'",
5637 key, oldval);
5638 ajStrDel(&key);
5639 ajStrDel(&oldval);
5640 }
5641
5642 /* test: badinclude.rc */
5643 if(!(iinf = ajFileNewInNameS(includefn)))
5644 {
5645 if(ajStrMatchS(includefn, saveword))
5646 namError("Failed to open include file '%S'",
5647 includefn);
5648 else
5649 namError("Failed to open include file '%S' (%S)",
5650 saveword, includefn);
5651 ajStrAppendC(&namFileOrig,"(Failed)");
5652 }
5653 else
5654 {
5655 ajStrAppendC(&namFileOrig,"(OK)");
5656 /* replaces namFile */
5657 ajStrAssignS(&name, includefn);
5658 ajFilenameTrimPath(&name);
5659 namstatus = namProcessFile(iinf, name);
5660 ajFmtPrintS(&namFileName, "%F",
5661 cachefile);/* reset saved name */
5662 namLine = linecount-1;
5663
5664 if(!namstatus) /* test: badsummary.rc */
5665 {
5666 if(ajStrMatchS(includefn, saveword))
5667 namError("Error(s) found in included file %F",
5668 iinf);
5669 else
5670 namError("Error(s) found in included file %S (%F)",
5671 saveword, iinf);
5672 }
5673
5674
5675 ajFileClose(&iinf);
5676 }
5677
5678 ajStrDel(&includefn);
5679 }
5680
5681 namListParseOK = ajTrue;
5682 }
5683
5684
5685 if(dbsave)
5686 {
5687 /* Save the keyword value */
5688 key = ajStrNewC(namDbAttrs[db_input].Name);
5689 namDbtablePutAttrS(dbattr, &key, &value);
5690
5691 db_input =-1;
5692 dbsave = ajFalse;
5693 }
5694
5695 if(saveit)
5696 {
5697 namUser("saving type %d name '%S' value '%S' line:%d\n",
5698 namParseType, name, value, namLine);
5699 AJNEW0(fnew);
5700 tabname = ajCharNewS(name);
5701 fnew->name = name;
5702 name = NULL;
5703 fnew->value = value;
5704 value = NULL;
5705 fnew->file = ajStrNewRef(saveshortname);
5706
5707 if(namParseType == TYPE_DB)
5708 {
5709 fnew->data = (AjPTable) dbattr;
5710 dbattr = NULL;
5711 saveTable = dbtable;
5712 }
5713 else if(namParseType == TYPE_ALIAS)
5714 {
5715 fnew->data = NULL;
5716 saveTable = alitable;
5717 }
5718 else
5719 {
5720 fnew->data = NULL;
5721 }
5722 entry = ajTablePut(saveTable, tabname, fnew);
5723 namUser("store entry '%s' '%S' (%S)\n",
5724 tabname, fnew->name, fnew->file);
5725
5726 if(entry)
5727 {
5728 /* it existed so over wrote previous table entry
5729 ** Only a namUser message - redefining EMBOSSRC in
5730 ** QA testing can give too many warnings
5731 */
5732 ajErr("%F: replaced %s %S definition from %S\n",
5733 cachefile,
5734 namTypes[namParseType],
5735 entry->name,
5736 entry->file);
5737 namEntryDelete(&entry, namParseType); /* previous entry */
5738 }
5739
5740 saveit = ajFalse;
5741 namParseType = 0;
5742 }
5743 ajStrDel(&curword);
5744 }
5745
5746 if(namParseType)
5747 {
5748 /* test: badset.rc baddb.rc */
5749 namError("Unexpected end of file in %s definition",
5750 namTypes[namParseType]);
5751 namParseType = 0;
5752 }
5753
5754 if(ajListGetLength(listcount)) /* cleanup the wordcount list */
5755 {
5756 namUser("** remaining wordcount items: %Lu\n",
5757 ajListGetLength(listcount));
5758
5759 while(ajListGetLength(listcount))
5760 {
5761 ajListPop(listcount, (void**) &iword);
5762 AJFREE(iword);
5763 }
5764 }
5765
5766 if(value)
5767 namUser("++ namListParse value %x '%S'", value, value);
5768
5769 ajStrDel(&saveword);
5770 ajStrDel(&saveshortname);
5771 ajTablestrFree(&Ifiles);
5772
5773 return ajTrue;
5774 }
5775
5776
5777
5778
5779 /* @func ajNamSvrCount ********************************************************
5780 **
5781 ** Reads the database cachefile for a server and counts the number of databases
5782 **
5783 ** Searches emboss_standard and the user directory ~/.embossdata/
5784 ** testing the file data in each file found and parsing the most recent file.
5785 **
5786 ** cache files should all start with a comment line
5787 ** containing the file name and the creation date.
5788 **
5789 ** @param [r] server [const AjPStr] Server name
5790 ** @return [ajuint] Number of databases
5791 **
5792 **
5793 ** @release 6.4.0
5794 ******************************************************************************/
5795
ajNamSvrCount(const AjPStr server)5796 ajuint ajNamSvrCount(const AjPStr server)
5797 {
5798 const NamPEntry svdata = NULL;
5799 const NamPEntry dbdata = NULL;
5800 AjPTable svrtable;
5801 AjPTable dbtable;
5802 const AjPStr svrcache = NULL;
5803 AjPStr cachefile = NULL;
5804
5805 dbdata = ajTableFetchS(namSvrDatabaseTable, server);
5806
5807 if(!dbdata)
5808 {
5809 svdata = ajTableFetchS(namSvrMasterTable, server);
5810
5811 if(!svdata)
5812 {
5813 ajErr("Server '%S' not found, unable to count databases",
5814 server);
5815 return 0;
5816 }
5817
5818 svrtable = (AjPTable) svdata->data;
5819 svrcache = ajTableFetchC(svrtable, "cachefile");
5820
5821 if(ajStrGetLen(svrcache))
5822 cachefile = ajStrNewS(svrcache);
5823 else
5824 {
5825 cachefile = ajStrNewC("server.");
5826 ajStrAppendS(&cachefile, server);
5827 }
5828
5829 namSvrCacheRead(server, cachefile);
5830 dbdata = ajTableFetchS(namSvrDatabaseTable, server);
5831
5832 if(!dbdata)
5833 {
5834 ajDebug("ajNamSvrCount: server '%S' has no databases\n", server);
5835 ajStrDel(&cachefile);
5836 return 0;
5837 }
5838 }
5839
5840 dbtable = (AjPTable) dbdata->data;
5841
5842 ajStrDel(&cachefile);
5843 return (ajuint) ajTableGetLength(dbtable);
5844 }
5845
5846
5847
5848
5849 /* @func ajNamSvrListFindAliases **********************************************
5850 **
5851 ** Reads the cachefile for a server and lists the aliases for a database.
5852 **
5853 ** Searches emboss_standard and the user directory ~/.embossdata/
5854 ** testing the file data in each file found and parsing the most recent file.
5855 **
5856 ** cache files should all start with a comment line
5857 ** containing the file name and the creation date.
5858 **
5859 ** @param [r] server [const AjPStr] Server name
5860 ** @param [r] dbname [const AjPStr] Database name
5861 ** @param [w] dbnames [AjPList] Str List of names to be populated
5862 ** @return [void]
5863 **
5864 **
5865 ** @release 6.6.0
5866 ******************************************************************************/
5867
ajNamSvrListFindAliases(const AjPStr server,const AjPStr dbname,AjPList dbnames)5868 void ajNamSvrListFindAliases(const AjPStr server, const AjPStr dbname,
5869 AjPList dbnames)
5870 {
5871 void **valarray = NULL;
5872 register ajint i = 0;
5873 AjPStr testname = ajStrNewS(dbname);
5874
5875 const NamPEntry svdata = NULL;
5876 const NamPEntry dbdata = NULL;
5877 NamPEntry fnew = NULL;
5878 AjPTable svrtable;
5879 AjPTable dbtable;
5880 const AjPStr svrcache = NULL;
5881 AjPStr cachefile = NULL;
5882
5883 /*
5884 ** TODO: Should server files be read by a separate function?
5885 ** This function is largely a copy of ajNamSvrCount and
5886 ** ajNamListListDatabases so that server files are read by both functions.
5887 */
5888
5889 ajStrFmtLower(&testname);
5890 dbdata = ajTableFetchS(namSvrAliasTable, server);
5891
5892 if(!dbdata)
5893 {
5894 svdata = ajTableFetchS(namSvrMasterTable, server);
5895
5896 if(!svdata)
5897 {
5898 ajErr("Server '%S' not found, unable to count databases",
5899 server);
5900 return;
5901 }
5902
5903 svrtable = (AjPTable) svdata->data;
5904 svrcache = ajTableFetchC(svrtable, "cachefile");
5905
5906 if(ajStrGetLen(svrcache))
5907 cachefile = ajStrNewS(svrcache);
5908 else
5909 {
5910 cachefile = ajStrNewC("server.");
5911 ajStrAppendS(&cachefile, server);
5912 }
5913
5914 namSvrCacheRead(server, cachefile);
5915 dbdata = ajTableFetchS(namSvrAliasTable, server);
5916
5917 ajStrDel(&cachefile);
5918
5919 if(!dbdata)
5920 {
5921 ajWarn("Server '%S' has no databases", server);
5922 return;
5923 }
5924 }
5925
5926 dbtable = (AjPTable) dbdata->data;
5927
5928 ajTableToarrayValues(dbtable, &valarray);
5929 ajDebug("ajNamSvrListFindAliases\n");
5930
5931 for(i = 0; valarray[i]; i++)
5932 {
5933 fnew = (NamPEntry) valarray[i];
5934
5935 if(!ajStrMatchS(testname, fnew->value))
5936 continue;
5937
5938 ajDebug("ALIAS: %S\n", fnew->name);
5939 ajListstrPushAppend(dbnames, fnew->name);
5940 }
5941
5942 ajListSort(dbnames, ajStrVcmp);
5943
5944 ajStrDel(&testname);
5945 AJFREE(valarray);
5946
5947 return;
5948 }
5949
5950
5951
5952
5953 /* @func ajNamSvrListListAliases **********************************************
5954 **
5955 ** Reads the database cachefile for a server and lists the aliases.
5956 **
5957 ** Searches emboss_standard and the user directory ~/.embossdata/
5958 ** testing the file data in each file found and parsing the most recent file.
5959 **
5960 ** cache files should all start with a comment line
5961 ** containing the file name and the creation date.
5962 **
5963 ** @param [r] server [const AjPStr] Server name
5964 ** @param [w] dbnames [AjPList] Str List of names to be populated
5965 ** @return [void]
5966 **
5967 **
5968 ** @release 6.6.0
5969 ******************************************************************************/
5970
ajNamSvrListListAliases(const AjPStr server,AjPList dbnames)5971 void ajNamSvrListListAliases(const AjPStr server, AjPList dbnames)
5972 {
5973 void **valarray = NULL;
5974 register ajint i = 0;
5975
5976 const NamPEntry svdata = NULL;
5977 const NamPEntry dbdata = NULL;
5978 NamPEntry fnew = NULL;
5979 AjPTable svrtable;
5980 AjPTable dbtable;
5981 const AjPStr svrcache = NULL;
5982 AjPStr cachefile = NULL;
5983
5984 /*
5985 ** TODO: Should server files be read by a separate function?
5986 ** This function is largely a copy of ajNamSvrCount and
5987 ** ajNamListListDatabases so that server files are read by both functions.
5988 */
5989
5990 dbdata = ajTableFetchS(namSvrAliasTable, server);
5991
5992 if(!dbdata)
5993 {
5994 svdata = ajTableFetchS(namSvrMasterTable, server);
5995
5996 if(!svdata)
5997 {
5998 ajErr("Server '%S' not found, unable to count databases",
5999 server);
6000 return;
6001 }
6002
6003 svrtable = (AjPTable) svdata->data;
6004 svrcache = ajTableFetchC(svrtable, "cachefile");
6005
6006 if(ajStrGetLen(svrcache))
6007 cachefile = ajStrNewS(svrcache);
6008 else
6009 {
6010 cachefile = ajStrNewC("server.");
6011 ajStrAppendS(&cachefile, server);
6012 }
6013
6014 namSvrCacheRead(server, cachefile);
6015 dbdata = ajTableFetchS(namSvrAliasTable, server);
6016
6017 ajStrDel(&cachefile);
6018
6019 if(!dbdata)
6020 {
6021 ajWarn("Server '%S' has no databases", server);
6022 return;
6023 }
6024 }
6025
6026 dbtable = (AjPTable) dbdata->data;
6027
6028 ajTableToarrayValues(dbtable, &valarray);
6029 ajDebug("ajNamSvrListListAliases\n");
6030
6031 for(i = 0; valarray[i]; i++)
6032 {
6033 fnew = (NamPEntry) valarray[i];
6034 ajDebug("ALIAS: %S\n", fnew->name);
6035 ajListstrPushAppend(dbnames, fnew->name);
6036 }
6037
6038 ajListSort(dbnames, ajStrVcmp);
6039
6040 AJFREE(valarray);
6041
6042 return;
6043 }
6044
6045
6046
6047
6048 /* @func ajNamSvrListListDatabases ********************************************
6049 **
6050 ** Reads the database cachefile for a server and lists the databases.
6051 **
6052 ** Searches emboss_standard and the user directory ~/.embossdata/
6053 ** testing the file data in each file found and parsing the most recent file.
6054 **
6055 ** cache files should all start with a comment line
6056 ** containing the file name and the creation date.
6057 **
6058 ** @param [r] server [const AjPStr] Server name
6059 ** @param [w] dbnames [AjPList] Str List of names to be populated
6060 ** @return [void]
6061 **
6062 **
6063 ** @release 6.4.0
6064 ******************************************************************************/
6065
ajNamSvrListListDatabases(const AjPStr server,AjPList dbnames)6066 void ajNamSvrListListDatabases(const AjPStr server, AjPList dbnames)
6067 {
6068 void **valarray = NULL;
6069 register ajint i = 0;
6070
6071 const NamPEntry svdata = NULL;
6072 const NamPEntry dbdata = NULL;
6073 NamPEntry fnew = NULL;
6074 AjPTable svrtable;
6075 AjPTable dbtable;
6076 const AjPStr svrcache = NULL;
6077 AjPStr cachefile = NULL;
6078
6079 /*
6080 ** TODO: Should server files be read by a separate function?
6081 ** This function is largely a copy of ajNamSvrCount and
6082 ** ajNamListListDatabases so that server files are read by both functions.
6083 */
6084
6085 dbdata = ajTableFetchS(namSvrDatabaseTable, server);
6086
6087 if(!dbdata)
6088 {
6089 svdata = ajTableFetchS(namSvrMasterTable, server);
6090
6091 if(!svdata)
6092 {
6093 ajErr("Server '%S' not found, unable to count databases",
6094 server);
6095 return;
6096 }
6097
6098 svrtable = (AjPTable) svdata->data;
6099 svrcache = ajTableFetchC(svrtable, "cachefile");
6100
6101 if(ajStrGetLen(svrcache))
6102 cachefile = ajStrNewS(svrcache);
6103 else
6104 {
6105 cachefile = ajStrNewC("server.");
6106 ajStrAppendS(&cachefile, server);
6107 }
6108
6109 namSvrCacheRead(server, cachefile);
6110 dbdata = ajTableFetchS(namSvrDatabaseTable, server);
6111
6112 ajStrDel(&cachefile);
6113
6114 if(!dbdata)
6115 {
6116 ajWarn("Server '%S' has no databases", server);
6117 return;
6118 }
6119 }
6120
6121 dbtable = (AjPTable) dbdata->data;
6122
6123 ajTableToarrayValues(dbtable, &valarray);
6124 ajDebug("ajNamSvrListListDatabases\n");
6125
6126 for(i = 0; valarray[i]; i++)
6127 {
6128 fnew = (NamPEntry) valarray[i];
6129 ajDebug("DB: %S\n", fnew->name);
6130 ajListstrPushAppend(dbnames, fnew->name);
6131 }
6132
6133 ajListSort(dbnames, ajStrVcmp);
6134
6135 AJFREE(valarray);
6136
6137 return;
6138 }
6139
6140
6141
6142
6143 /* @funcstatic namSvrCacheOpen ************************************************
6144 **
6145 ** Opens the database cachefile for a server.
6146 **
6147 ** Searches emboss_standard and the user directory ~/.embossdata/
6148 ** testing the file data in each file found and opening the most recent file.
6149 **
6150 ** cache files must all start with a comment line
6151 ** containing the file name and the creation date.
6152 **
6153 ** @param [r] cachename [const AjPStr] Cache file name
6154 ** @return [AjPFile] Filename of selected cache file
6155 **
6156 **
6157 ** @release 6.4.0
6158 ******************************************************************************/
6159
namSvrCacheOpen(const AjPStr cachename)6160 static AjPFile namSvrCacheOpen(const AjPStr cachename)
6161 {
6162 AjPFile ret = NULL;
6163 AjPFile userfile = NULL;
6164 AjPFile systemfile = NULL;
6165
6166 AjPStr readline = NULL;
6167 AjPStrTok handle = NULL;
6168 AjPStr token = NULL;
6169 AjPTime usertime = NULL;
6170 AjPTime systemtime = NULL;
6171
6172 systemfile = ajFileNewInNamePathS(cachename, namStandardDir);
6173 ajDebug("system file '%F' name: '%S' path: '%S'\n",
6174 systemfile, cachename, namStandardDir);
6175
6176 if(systemfile)
6177 {
6178 ajReadlineTrim(systemfile, &readline);
6179 ajStrTokenAssignC(&handle, readline, "# \t");
6180 ajStrTokenNextParse(handle, &token);
6181
6182 if(!ajStrMatchS(token, cachename))
6183 ajWarn("%F: Cache file name '%S' expected, '%S' found",
6184 systemfile, cachename, token);
6185
6186 ajStrTokenNextParseC(handle, "", &token); /* time */
6187 systemtime = ajTimeNew();
6188 ajTimeSetS(systemtime, token);
6189 }
6190
6191 userfile = ajFileNewInNamePathS(cachename, namUserDir);
6192 ajDebug("user file '%F' name: '%S' path: '%S'\n",
6193 userfile, cachename, namStandardDir);
6194
6195 if(userfile)
6196 {
6197 ajReadlineTrim(userfile, &readline);
6198 ajStrTokenAssignC(&handle, readline, "# \t");
6199 ajStrTokenNextParse(handle, &token);
6200
6201 if(!ajStrMatchS(token, cachename))
6202 ajWarn("%F: Cache file name '%S' expected, '%S' found",
6203 userfile, cachename, token);
6204
6205 ajStrTokenNextParseC(handle, "", &token); /* time */
6206 usertime = ajTimeNew();
6207 ajTimeSetS(usertime, token);
6208 }
6209
6210 if(userfile && (!systemfile || ajTimeDiff(systemtime, usertime) > 0.0))
6211 {
6212 ajFileClose(&systemfile);
6213 ret = userfile;
6214 ajDebug("user file '%F' %D selected\n", userfile, usertime);
6215 }
6216 else
6217 {
6218 ajFileClose(&userfile);
6219 ret = systemfile;
6220 ajDebug("system file '%F' %D selected\n", systemfile, systemtime);
6221 }
6222
6223 ajStrTokenDel(&handle);
6224 ajStrDel(&readline);
6225 ajStrDel(&token);
6226 ajTimeDel(&systemtime);
6227 ajTimeDel(&usertime);
6228
6229 return ret;
6230 }
6231
6232
6233
6234
6235 /* @funcstatic namSvrCacheRead ************************************************
6236 **
6237 ** Reads the database cachefile for a server
6238 **
6239 ** Searches emboss_standard and the user directory ~/.embossdata/
6240 ** testing the file data in each file found and parsing the most recent file.
6241 **
6242 ** cache files must all start with a comment line
6243 ** containing the file name and the creation date.
6244 **
6245 ** @param [r] server [const AjPStr] Server name
6246 ** @param [r] cachename [const AjPStr] Cache file name
6247 ** @return [AjBool] True on success
6248 **
6249 **
6250 ** @release 6.4.0
6251 ******************************************************************************/
6252
namSvrCacheRead(const AjPStr server,const AjPStr cachename)6253 static AjBool namSvrCacheRead(const AjPStr server, const AjPStr cachename)
6254 {
6255 AjPFile cachefile;
6256 AjPTable dbtable;
6257 AjPTable alitable;
6258 NamPEntry fnew = NULL;
6259
6260 cachefile = namSvrCacheOpen(cachename);
6261 if(!cachefile)
6262 return ajFalse;
6263
6264 dbtable = ajTablecharNewCase(30);
6265 alitable = ajTablecharNewCase(30);
6266
6267 namSvrCacheParse(cachefile, dbtable, alitable);
6268 ajFileClose(&cachefile);
6269
6270 AJNEW0(fnew);
6271 fnew->name = ajStrNewS(server);
6272 fnew->value = ajStrNewS(cachename);
6273 fnew->data = dbtable;
6274 ajTablePut(namSvrDatabaseTable, ajCharNewS(server), fnew);
6275 fnew = NULL;
6276
6277 AJNEW0(fnew);
6278 fnew->name = ajStrNewS(server);
6279 fnew->value = ajStrNewS(cachename);
6280 fnew->data = alitable;
6281 ajTablePut(namSvrAliasTable, ajCharNewS(server), fnew);
6282 fnew = NULL;
6283
6284
6285 return ajTrue;
6286 }
6287
6288
6289
6290
6291 /* @funcstatic namProcessFile *************************************************
6292 **
6293 ** Read the definitions file and append each token to the list.
6294 **
6295 ** @param [u] file [AjPFile] Input file object
6296 ** @param [r] shortname [const AjPStr] Definitions file short name
6297 ** @return [AjBool] ajTrue if no error were found
6298 **
6299 ** @release 1.0.0
6300 ** @@
6301 ******************************************************************************/
6302
namProcessFile(AjPFile file,const AjPStr shortname)6303 static AjBool namProcessFile(AjPFile file, const AjPStr shortname)
6304 {
6305 AjPStr rdline = NULL;
6306 AjPStr word = NULL;
6307 const char *ptr;
6308 ajint i = 0;
6309 ajint len;
6310 char quote = '\0';
6311 AjPList listwords;
6312 AjPList listcount;
6313 AjPStr wordptr;
6314 ajint iline = 0;
6315 ajint *k = NULL;
6316
6317 ajint preverrorcount = namErrorCount;
6318
6319 listwords = ajListstrNew();
6320 listcount = ajListNew();
6321 word = ajStrNewRes(128);
6322
6323 ajFmtPrintS(&namFileName, "%F", file);
6324 namUser("namProcessFile '%F'\n", file);
6325
6326 /* Read in the settings. */
6327 while(ajReadlineTrim(file, &rdline))
6328 {
6329 iline++;
6330 AJNEW0(k);
6331 *k = (ajuint) ajListGetLength(listwords);
6332 ajListPushAppend(listcount, k);
6333
6334 /* Ignore if the line is a comment */
6335 if(!ajStrCutCommentsStart(&rdline))
6336 continue;
6337
6338 /* namUser("%S\n",rdline); */
6339 len = ajStrGetLen(rdline);
6340
6341 /* now create a linked list of the "words" */
6342 if(len)
6343 {
6344 ptr = ajStrGetPtr(rdline);
6345 i = 0;
6346
6347 while(*ptr && i < len)
6348 {
6349 if(*ptr == ' ' || *ptr == '\t')
6350 {
6351 if(ajStrGetLen(word))
6352 {
6353 wordptr = ajStrNewS(word);
6354 ajListstrPushAppend(listwords, wordptr);
6355 ajStrAssignClear(&word);
6356 }
6357
6358 i++;
6359 ptr++;
6360 continue;
6361 }
6362 else if(*ptr == '\'' || *ptr == '\"')
6363 {
6364 ajStrAppendK(&word,*ptr);
6365
6366 if(quote)
6367 {
6368 if(quote == *ptr)
6369 quote = '\0';
6370 }
6371 else
6372 quote = *ptr;
6373 }
6374 else if(!quote && ajStrGetLen(word) && *ptr == ']')
6375 {
6376 wordptr = ajStrNewS(word);
6377 ajListstrPushAppend(listwords, wordptr);
6378 ajStrAssignClear(&word);
6379 wordptr = ajStrNewC("]");
6380 ajListstrPushAppend(listwords, wordptr);
6381 ajStrAssignClear(&word);
6382 }
6383 else
6384 ajStrAppendK(&word,*ptr);
6385 i++;ptr++;
6386 }
6387
6388 if(ajStrGetLen(word))
6389 {
6390 wordptr = ajStrNewS(word);
6391 ajListstrPushAppend(listwords, wordptr);
6392 ajStrAssignClear(&word);
6393 }
6394
6395 }
6396 }
6397
6398 ajStrDel(&rdline);
6399
6400 AJNEW0(k);
6401 *k = (ajuint) ajListGetLength(listwords);
6402 ajListPushAppend(listcount, k);
6403
6404 namListParseOK = ajTrue;
6405
6406 namUser("ready to parse\n");
6407 namListParse(listwords, listcount, file, shortname);
6408
6409 if(!namListParseOK)
6410 namUser("Unexpected end of file in %S at line %d\n",
6411 namRootStr, iline);
6412
6413 namUser("file read\n");
6414 ajListstrFreeData(&listwords); /* Delete the linked list structure */
6415 namUser("wordlist free\n");
6416 ajListFree(&listcount); /* Delete the linked list structure */
6417 namUser("countlist free\n");
6418
6419 namDebugVariables();
6420 namDebugAliases();
6421 ajStrDel(&word);
6422
6423 namUser("namProcessFile done '%F'\n", file);
6424
6425 if(namErrorCount > preverrorcount)
6426 return ajFalse;
6427
6428 return ajTrue;
6429 }
6430
6431
6432
6433
6434 /* @func ajNamInit ************************************************************
6435 **
6436 ** Initialise the variable and database definitions. Find the definition
6437 ** files and read them.
6438 **
6439 ** @param [r] prefix [const char*] Default prefix for all file
6440 ** and variable names.
6441 ** @return [void]
6442 **
6443 ** @release 1.0.0
6444 ** @@
6445 ******************************************************************************/
6446
ajNamInit(const char * prefix)6447 void ajNamInit(const char* prefix)
6448 {
6449 const char *prefixRoot;
6450 char *prefixHomedir = NULL;
6451 AjPFile prefixRootFile = NULL;
6452 AjPStr prefixRootStr = NULL;
6453 AjPStr prefixStr = NULL;
6454 AjPStr prefixCap = NULL;
6455 AjPStr debugStr = NULL;
6456 AjPStr debugVal = NULL;
6457 AjPStr homercVal = NULL;
6458 AjPStr basename = NULL;
6459 AjBool root_defined;
6460 AjBool is_windows = ajFalse;
6461 NamPEntry entryAuto = NULL;
6462
6463 /*
6464 ** The Windows socket interface must be initialised before any
6465 ** socket calls are made elsewhere in the AJAX library.
6466 ** This must only be done once so here is as good a place
6467 ** as any to do it.
6468 ** Set the winsock version to 1.1
6469 **
6470 ** Also note that EMBOSS_ROOT must be set for ajNamInit to
6471 ** work with Windows. This will be done by the Windows
6472 ** installer but developers must set it manually e,g,
6473 ** set EMBOSS_ROOT C:\emboss\win32
6474 */
6475 #ifdef WIN32
6476 WSADATA wsaData;
6477 AjPStr tmpstr = NULL;
6478 #endif
6479
6480 if(namVarMasterTable &&
6481 namAliasMasterTable &&
6482 namSvrMasterTable &&
6483 namDbMasterTable &&
6484 namResMasterTable)
6485 return;
6486
6487 #ifdef HAVE_MCHECK
6488 /*
6489 ** mcheck turns on checking of all malloc/calloc/realloc/free calls
6490 **
6491 ** it *must* be called before any other malloc by the main program
6492 **
6493 ** ajMemCheck reports on status. If called via ajMemProbe (AJMPROBE)
6494 ** it can also report the source file line it was invoked from
6495 **
6496 ** This is all specific to glibc and must be turned on with ./configure
6497 */
6498 if(mcheck(ajMemCheck))
6499 ajWarn("ajNamInit called after first malloc - ajMemCheck ignored");
6500 #endif /* ! HAVE_MCHECK */
6501
6502 #ifdef WIN32
6503 WSAStartup(MAKEWORD(1, 1), &wsaData);
6504 is_windows = ajTrue;
6505 #endif
6506
6507
6508 /*
6509 ** static namPrefixStr is the prefix for all variable names
6510 */
6511
6512 ajStrAssignC(&namPrefixStr, prefix);
6513
6514 ajStrAppendC(&namPrefixStr, "_");
6515
6516 ajClockReset();
6517 ajTimeReset();
6518
6519 /* create new tables to hold the values */
6520
6521 namVarMasterTable = ajTablecharNewCase(100);
6522 namAliasMasterTable = ajTablecharNewCase(100);
6523 namSvrMasterTable = ajTablecharNewCase(100);
6524 namDbMasterTable = ajTablecharNewCase(100);
6525 namResMasterTable = ajTablecharNewCase(100);
6526 namSvrDatabaseTable = ajTablecharNewCase(100);
6527 namSvrAliasTable = ajTablecharNewCase(100);
6528
6529 #ifdef HAVE_AXIS2C
6530 AJNEW0(entryAuto);
6531 entryAuto->name = ajStrNewC("emboss_axis2c");
6532 entryAuto->value = ajStrNewC("1");
6533 entryAuto->file = ajStrNewC("auto");
6534 ajTablePut(namVarMasterTable, ajCharNewC("emboss_axis2c"),
6535 entryAuto);
6536 entryAuto = NULL;
6537 #endif
6538
6539 #if defined(HAVE_MYSQL) || defined(HAVE_POSTGRESQL)
6540 AJNEW0(entryAuto);
6541 entryAuto->name = ajStrNewC("emboss_sql");
6542 entryAuto->value = ajStrNewC("1");
6543 entryAuto->file = ajStrNewC("auto");
6544 ajTablePut(namVarMasterTable, ajCharNewC("emboss_sql"),
6545 entryAuto);
6546 entryAuto = NULL;
6547
6548 #ifdef HAVE_MYSQL
6549 AJNEW0(entryAuto);
6550 entryAuto->name = ajStrNewC("emboss_mysql");
6551 entryAuto->value = ajStrNewC("1");
6552 entryAuto->file = ajStrNewC("auto");
6553 ajTablePut(namVarMasterTable, ajCharNewC("emboss_mysql"),
6554 entryAuto);
6555 entryAuto = NULL;
6556 #endif
6557 #ifdef HAVE_POSTGRESQL
6558 AJNEW0(entryAuto);
6559 entryAuto->name = ajStrNewC("emboss_postgresql");
6560 entryAuto->value = ajStrNewC("1");
6561 entryAuto->file = ajStrNewC("auto");
6562 ajTablePut(namVarMasterTable, ajCharNewC("emboss_postgresql"),
6563 entryAuto);
6564 entryAuto = NULL;
6565 #endif
6566 #endif
6567
6568 /*
6569 ** for each type of file read it and save the values
6570 ** Start at system level then go to user
6571 */
6572
6573 /*
6574 ** local prefixRoot is the root directory
6575 ** it is the value of (PREFIX)_ROOT (if set) or namFixedRoot
6576 */
6577
6578 ajStrAssignC(&debugStr, prefix);
6579
6580 ajStrAppendC(&debugStr, "_namdebug");
6581 ajStrFmtUpper(&debugStr);
6582
6583 if(ajNamGetenvS(debugStr, &debugVal))
6584 ajStrToBool(debugVal, &namDoDebug);
6585
6586 ajStrAssignC(&debugStr, prefix);
6587
6588 ajStrAppendC(&debugStr, "_namvalid");
6589 ajStrFmtUpper(&debugStr);
6590
6591 if(ajNamGetenvS(debugStr, &debugVal))
6592 ajStrToBool(debugVal, &namDoValid);
6593
6594 ajStrDel(&debugStr);
6595 ajStrDel(&debugVal);
6596
6597 ajStrAssignC(&prefixStr, prefix);
6598
6599 ajStrAppendC(&prefixStr, "_ROOT");
6600 ajStrFmtUpper(&prefixStr);
6601
6602 ajStrAppendC(&prefixCap, prefix);
6603 ajStrFmtUpper(&prefixCap);
6604
6605 root_defined = ajNamGetenvS(prefixStr, &prefixRootStr);
6606
6607 if(!root_defined && is_windows)
6608 ajDie("EMBOSS_ROOT must be defined for Windows");
6609
6610 if(root_defined)
6611 {
6612 prefixRoot = ajStrGetPtr(prefixRootStr);
6613
6614 #ifdef WIN32
6615 /* namInstallRoot undefined for Windows ... use required EMBOSS_ROOT */
6616
6617 ajStrAssignS(&tmpstr, prefixRootStr);
6618 ajStrAppendC(&tmpstr, "\\apps\\Release");
6619
6620 if(ajFilenameExistsDir(tmpstr))
6621 strcpy(namInstallRoot, ajStrGetPtr(tmpstr));
6622 else
6623 strcpy(namInstallRoot,prefixRoot);
6624
6625 ajStrDel(&tmpstr);
6626 #endif
6627 }
6628 else
6629 prefixRoot = namFixedRoot;
6630
6631 /* namFixedBaseStr is the directory above the source root */
6632
6633 ajStrAssignC(&namFixedRootStr, prefixRoot);
6634 ajStrAssignS(&namFixedBaseStr, namFixedRootStr);
6635 #ifndef WIN32
6636 ajDirnameUp(&namFixedBaseStr);
6637 #endif
6638
6639 ajStrAssignC(&namFixedPackageStr, namPackage);
6640 ajStrAssignC(&namFixedSystemStr, namSystem);
6641 ajStrAssignC(&namFixedVersionStr, namVersion);
6642 if(ajStrGetLen(namFixedVersionStr) < 7)
6643 ajStrAppendC(&namFixedVersionStr, ".0");
6644
6645 ajStrAssignC(&namFixedInstallStr, namInstallRoot);
6646
6647 if(is_windows)
6648 {
6649 ajFmtPrintS(&namStandardDir, "%s",
6650 namInstallRoot);
6651 }
6652 else
6653 {
6654 ajFmtPrintS(&namStandardDir, "%s%sshare%s%S",
6655 namInstallRoot, SLASH_STRING, SLASH_STRING, prefixCap);
6656 }
6657 ajFmtPrintS(&namStandardFilename, "%S%s%s.standard",
6658 namStandardDir, SLASH_STRING, prefix);
6659 prefixRootFile = ajFileNewInNameS(namStandardFilename);
6660 ajStrAssignC(&basename, "standard");
6661
6662 if(!prefixRootFile)
6663 {
6664 /* try original directory */
6665 ajStrAssignC(&namStandardDir, prefixRoot);
6666 ajFmtPrintS(&namStandardFilename, "%s%s%s.standard", prefixRoot,
6667 SLASH_STRING,prefix);
6668
6669 prefixRootFile = ajFileNewInNameS(namStandardFilename);
6670 }
6671
6672 if(prefixRootFile)
6673 {
6674 AJNEW0(entryAuto);
6675 entryAuto->name = ajStrNewC("emboss_standard");
6676 entryAuto->value = ajStrNewS(namStandardDir);
6677 entryAuto->file = ajStrNewRef(namStandardFilename);
6678 ajTablePut(namVarMasterTable, ajCharNewC("emboss_standard"),
6679 entryAuto);
6680 entryAuto = NULL;
6681
6682 ajStrAppendC(&namFileOrig, "(OK)");
6683 namProcessFile(prefixRootFile, basename);
6684 ajFileClose(&prefixRootFile);
6685
6686 if(namFileOrig)
6687 ajStrAppendC(&namFileOrig, ", ");
6688
6689 ajStrAppendS(&namFileOrig, namStandardFilename);
6690 }
6691 else
6692 ajStrAppendC(&namFileOrig, "(failed)");
6693
6694 /*
6695 ** EMBOSS is distributed with an emboss.standard file
6696 ** Looks for this file and set EMBOSS_STANDARD variable to its directory
6697 */
6698
6699 /*
6700 ** look for the site's default file in the install directory as
6701 <install-prefix>/share/PREFIX/emboss.default
6702 **
6703 */
6704
6705 ajFmtPrintS(&namRootStr, "%s%sshare%s%S%s%s.default",
6706 namInstallRoot, SLASH_STRING, SLASH_STRING,
6707 prefixCap, SLASH_STRING, prefix);
6708 prefixRootFile = ajFileNewInNameS(namRootStr);
6709 ajStrAssignC(&basename, "global");
6710
6711 /* look for $(PREFIX)_ROOT/../emboss.default */
6712
6713 if(!prefixRootFile)
6714 {
6715 /* try original directory */
6716 ajFmtPrintS(&namRootStr, "%s%s%s.default", prefixRoot,
6717 SLASH_STRING,prefix);
6718
6719 prefixRootFile = ajFileNewInNameS(namRootStr);
6720 ajStrAssignC(&basename, "source");
6721 }
6722
6723 if(namFileOrig)
6724 ajStrAppendC(&namFileOrig, ", ");
6725
6726 ajStrAppendS(&namFileOrig, namRootStr);
6727
6728 if(prefixRootFile)
6729 {
6730 ajStrAppendC(&namFileOrig, "(OK)");
6731 namProcessFile(prefixRootFile, basename);
6732 ajFileClose(&prefixRootFile);
6733 }
6734 else
6735 ajStrAppendC(&namFileOrig, "(failed)");
6736
6737
6738
6739 /* look for .embossrc in an arbitrary directory */
6740
6741 prefixRoot= getenv("EMBOSSRC");
6742
6743 if(prefixRoot)
6744 {
6745 ajStrAssignC(&namRootStr, prefixRoot);
6746 ajStrAppendC(&namRootStr, SLASH_STRING);
6747 ajStrAppendC(&namRootStr, ".");
6748 ajStrAppendC(&namRootStr, prefix);
6749 ajStrAppendC(&namRootStr, "rc");
6750
6751 if(namFileOrig)
6752 ajStrAppendC(&namFileOrig, ", ");
6753
6754 ajStrAppendS(&namFileOrig, namRootStr);
6755
6756 prefixRootFile = ajFileNewInNameS(namRootStr);
6757
6758 if(prefixRootFile)
6759 {
6760 ajStrAssignC(&basename, "special");
6761 ajStrAppendC(&namFileOrig, "(OK)");
6762 namProcessFile(prefixRootFile, basename);
6763 ajFileClose(&prefixRootFile);
6764 }
6765 else
6766 ajStrAppendC(&namFileOrig, "(failed)");
6767 }
6768
6769
6770 /*
6771 ** look for $HOME/.embossrc
6772 **
6773 ** Note that this will not work with Windows as there is
6774 ** no concept of HOME
6775 */
6776
6777 prefixHomedir = ajSysGetHomedir();
6778
6779 ajStrAssignC(&namUserDir, prefixHomedir);
6780 ajStrAppendC(&namUserDir, SLASH_STRING);
6781 ajStrAppendC(&namUserDir, ".embossdata");
6782 ajStrAppendC(&namUserDir, SLASH_STRING);
6783
6784 ajStrAssignC(&prefixStr, prefix);
6785 ajStrAppendC(&prefixStr, "_RCHOME");
6786 ajStrFmtUpper(&prefixStr);
6787
6788 if(ajNamGetenvS(prefixStr, &homercVal))
6789 ajStrToBool(homercVal, &namDoHomeRc);
6790
6791 ajStrDel(&homercVal);
6792
6793 if(namDoHomeRc && prefixHomedir)
6794 {
6795 ajStrAssignC(&namRootStr, prefixHomedir);
6796 ajStrAppendC(&namRootStr, SLASH_STRING);
6797 ajStrAppendC(&namRootStr, ".");
6798 ajStrAppendC(&namRootStr, prefix);
6799 ajStrAppendC(&namRootStr, "rc");
6800
6801 if(namFileOrig)
6802 ajStrAppendC(&namFileOrig, ", ");
6803
6804 ajStrAppendS(&namFileOrig, namRootStr);
6805
6806 ajStrAssignC(&basename, "user");
6807 prefixRootFile = ajFileNewInNameS(namRootStr);
6808
6809 if(prefixRootFile)
6810 {
6811 ajStrAppendC(&namFileOrig, "(OK)");
6812 namProcessFile(prefixRootFile, basename);
6813 ajFileClose(&prefixRootFile);
6814 }
6815 else
6816 ajStrAppendC(&namFileOrig, "(failed)");
6817 }
6818
6819 namUser("Files processed: %S\n", namFileOrig);
6820
6821 ajCharDel(&prefixHomedir);
6822 ajStrDel(&prefixRootStr);
6823 ajStrDel(&basename);
6824 ajStrDel(&prefixStr);
6825 ajStrDel(&prefixCap);
6826
6827 if(!namFixedSystemStr)
6828 namFixedSystemStr = ajStrNewC(namSystem);
6829
6830 if(!namFixedVersionStr)
6831 {
6832 namFixedVersionStr = ajStrNewC(namVersion);
6833 if(ajStrGetLen(namFixedVersionStr) < 7)
6834 ajStrAppendC(&namFixedVersionStr, ".0");
6835 }
6836
6837 if(namErrorCount) /* test: badsummary.rc */
6838 ajDie("Error(s) in configuration files");
6839
6840 return;
6841 }
6842
6843
6844
6845
6846 /* @funcstatic namNoColon *****************************************************
6847 **
6848 ** Remove any trailing colon ':' in the input string.
6849 **
6850 ** @param [u] thys [AjPStr*] String.
6851 ** @return [void]
6852 **
6853 ** @release 1.0.0
6854 ** @@
6855 ******************************************************************************/
6856
namNoColon(AjPStr * thys)6857 static void namNoColon(AjPStr* thys)
6858 {
6859 if(ajStrGetCharLast(*thys) == ':')
6860 ajStrCutEnd(thys, 1);
6861
6862 return;
6863 }
6864
6865
6866
6867
6868 /* @funcstatic namDbAttrC *****************************************************
6869 **
6870 ** Return the index for a database attribute name.
6871 **
6872 ** @param [r] str [const char*] Attribute name.
6873 ** @return [ajint] Index in namDbAttrs, or -1 on failure.
6874 **
6875 ** @release 1.0.0
6876 ** @@
6877 ******************************************************************************/
6878
namDbAttrC(const char * str)6879 static ajint namDbAttrC(const char* str)
6880 {
6881 ajint i = 0;
6882 ajint j = 0;
6883 ajint ifound = 0;
6884
6885 ajStrAssignC(&namCmpStr, str);
6886 ajStrFmtLower(&namCmpStr);
6887
6888 for(i=0; namDbAttrs[i].Name; i++)
6889 {
6890 if(ajStrMatchC(namCmpStr, namDbAttrs[i].Name))
6891 return i;
6892
6893 if(ajCharPrefixS(namDbAttrs[i].Name, namCmpStr))
6894 {
6895 ifound++;
6896 j = i;
6897 }
6898 }
6899
6900 if(ifound == 1)
6901 return j;
6902
6903 return -1;
6904 }
6905
6906
6907
6908
6909 /* @funcstatic namDbAttrS *****************************************************
6910 **
6911 ** Return the index for a database attribute name.
6912 **
6913 ** @param [r] thys [const AjPStr] Attribute name.
6914 ** @return [ajint] Index in namDbAttrs, or -1 on failure.
6915 **
6916 ** @release 6.4.0
6917 ** @@
6918 ******************************************************************************/
6919
namDbAttrS(const AjPStr thys)6920 static ajint namDbAttrS(const AjPStr thys)
6921 {
6922 return namDbAttrC(ajStrGetPtr(thys));
6923 }
6924
6925
6926
6927
6928 /* @funcstatic namSvrAttrC ****************************************************
6929 **
6930 ** Return the index for a server attribute name.
6931 **
6932 ** @param [r] str [const char*] Attribute name.
6933 ** @return [ajint] Index in namSvrAttrs, or -1 on failure.
6934 **
6935 ** @release 6.4.0
6936 ** @@
6937 ******************************************************************************/
6938
namSvrAttrC(const char * str)6939 static ajint namSvrAttrC(const char* str)
6940 {
6941 ajint i = 0;
6942 ajint j = 0;
6943 ajint ifound = 0;
6944
6945 ajStrAssignC(&namCmpStr, str);
6946 ajStrFmtLower(&namCmpStr);
6947
6948 for(i=0; namSvrAttrs[i].Name; i++)
6949 {
6950 if(ajStrMatchC(namCmpStr, namSvrAttrs[i].Name))
6951 return i;
6952
6953 if(ajCharPrefixS(namSvrAttrs[i].Name, namCmpStr))
6954 {
6955 ifound++;
6956 j = i;
6957 }
6958 }
6959
6960 if(ifound == 1)
6961 return j;
6962
6963 return -1;
6964 }
6965
6966
6967
6968
6969 /* @funcstatic namSvrAttrS ****************************************************
6970 **
6971 ** Return the index for a server attribute name.
6972 **
6973 ** @param [r] thys [const AjPStr] Attribute name.
6974 ** @return [ajint] Index in namSvrAttrs, or -1 on failure.
6975 **
6976 ** @release 6.4.0
6977 ** @@
6978 ******************************************************************************/
6979
namSvrAttrS(const AjPStr thys)6980 static ajint namSvrAttrS(const AjPStr thys)
6981 {
6982 return namSvrAttrC(ajStrGetPtr(thys));
6983 }
6984
6985
6986
6987
6988 /* @funcstatic namRsAttrC *****************************************************
6989 **
6990 ** Return the index for a resource attribute name.
6991 **
6992 ** @param [r] str [const char*] Attribute name.
6993 ** @return [ajint] Index in namRsAttrs, or -1 on failure.
6994 **
6995 ** @release 2.7.0
6996 ** @@
6997 ******************************************************************************/
6998
namRsAttrC(const char * str)6999 static ajint namRsAttrC(const char* str)
7000 {
7001 ajint i = 0;
7002 ajint j = 0;
7003 ajint ifound = 0;
7004
7005 ajStrAssignC(&namCmpStr, str);
7006 ajStrFmtLower(&namCmpStr);
7007
7008
7009 for(i=0; namRsAttrs[i].Name; i++)
7010 {
7011 if(ajStrMatchC(namCmpStr, namRsAttrs[i].Name))
7012 return i;
7013
7014 if(ajCharPrefixS(namRsAttrs[i].Name, namCmpStr))
7015 {
7016 ifound++;
7017 j = i;
7018 }
7019 }
7020
7021 if(ifound == 1)
7022 return j;
7023
7024 return -1;
7025 }
7026
7027
7028
7029
7030 /* @funcstatic namRsAttrS *****************************************************
7031 **
7032 ** Return the index for a resource attribute name.
7033 **
7034 ** @param [r] thys [const AjPStr] Attribute name.
7035 ** @return [ajint] Index in namRsAttrs, or -1 on failure.
7036 **
7037 ** @release 6.4.0
7038 ** @@
7039 ******************************************************************************/
7040
namRsAttrS(const AjPStr thys)7041 static ajint namRsAttrS(const AjPStr thys)
7042 {
7043 return namRsAttrC(ajStrGetPtr(thys));
7044 }
7045
7046
7047
7048
7049 /* @funcstatic namRsAttrFieldC ************************************************
7050 **
7051 ** Return the validity of a resource attribute name using a known field prefix
7052 **
7053 ** @param [r] rstable [const AjPTable] Resource table
7054 ** @param [r] str [const char*] Attribute name.
7055 ** @return [AjBool] Attribute name matches a defined field and property
7056 **
7057 ** @release 6.4.0
7058 ** @@
7059 ******************************************************************************/
7060
namRsAttrFieldC(const AjPTable rstable,const char * str)7061 static AjBool namRsAttrFieldC(const AjPTable rstable, const char* str)
7062 {
7063 AjBool ret = ajFalse;
7064 AjPStr prefix = NULL;
7065 const AjPStr fields = NULL;
7066 AjPStrTok handle = NULL;
7067 AjPStr field = NULL;
7068 const AjPStr type = NULL;
7069 const AjPList fdlist = NULL;
7070 AjIList iter = NULL;
7071 const NamPAttr attr = NULL;
7072
7073 type = ajTableFetchmodC(rstable, "type");
7074
7075 if(!ajStrMatchC(type, "Index"))
7076 return ajFalse;
7077
7078 if(ajCharSuffixC(str, "len"))
7079 ajStrAssignSubC(&prefix, str, 0, -4);
7080 else if(ajCharSuffixC(str, "seccachesize"))
7081 ajStrAssignSubC(&prefix, str, 0, -13);
7082 else if(ajCharSuffixC(str, "cachesize"))
7083 ajStrAssignSubC(&prefix, str, 0, -10);
7084 else if(ajCharSuffixC(str, "secpagesize"))
7085 ajStrAssignSubC(&prefix, str, 0, -12);
7086 else if(ajCharSuffixC(str, "pagesize"))
7087 ajStrAssignSubC(&prefix, str, 0, -9);
7088 else
7089 return ajFalse;
7090
7091 if(ajStrGetLen(prefix))
7092 {
7093 fields = ajTableFetchmodC(rstable, "fields");
7094
7095 if(fields)
7096 {
7097 handle = ajStrTokenNewC(fields, " ,;");
7098
7099 while(ajStrTokenNextParse(handle, &field))
7100 if(ajStrMatchS(prefix, field))
7101 ret = ajTrue;
7102 }
7103 else
7104 {
7105 fdlist = ajTableFetchC(rstable, "field");
7106
7107 if(fdlist)
7108 {
7109 iter = ajListIterNewread(fdlist);
7110
7111 while(!ajListIterDone(iter))
7112 {
7113 fields = ajListIterGet(iter);
7114 ajStrTokenAssignC(&handle, fields, " ,;");
7115
7116 while(ajStrTokenNextParse(handle, &field))
7117 {
7118 if(ajStrMatchC(field, "!"))
7119 break;
7120
7121 if(ajStrMatchS(prefix, field))
7122 ret = ajTrue;
7123 }
7124 }
7125
7126 ajListIterDel(&iter);
7127 }
7128 else
7129 {
7130 attr = ajTableFetchC(namResAttrTable, "fields");
7131 handle = ajStrTokenNewcharC(attr->Defval, " ,;");
7132
7133 while(ajStrTokenNextParse(handle, &field))
7134 if(ajStrMatchS(prefix, field))
7135 ret = ajTrue;
7136 }
7137 }
7138
7139 ajStrTokenDel(&handle);
7140 ajStrDel(&field);
7141 }
7142
7143 ajStrDel(&prefix);
7144
7145 return ret;
7146 }
7147
7148
7149
7150
7151 /* @funcstatic namRsAttrFieldS ************************************************
7152 **
7153 ** Return the validity of a resource attribute name using a known field prefix
7154 **
7155 ** @param [r] rstable [const AjPTable] Resource table
7156 ** @param [r] str [const AjPStr] Attribute name.
7157 ** @return [AjBool] Attribute name matches a defined field and property
7158 **
7159 ** @release 6.4.0
7160 ** @@
7161 ******************************************************************************/
7162
namRsAttrFieldS(const AjPTable rstable,const AjPStr str)7163 static AjBool namRsAttrFieldS(const AjPTable rstable, const AjPStr str)
7164 {
7165 AjBool ret = ajFalse;
7166 AjPStr prefix = NULL;
7167 const AjPStr fields = NULL;
7168 AjPStrTok handle = NULL;
7169 AjPStr field = NULL;
7170 const AjPStr type = NULL;
7171 AjPList fdlist = NULL;
7172 AjIList iter = NULL;
7173 const NamPAttr attr = NULL;
7174
7175 type = ajTableFetchC(rstable, "type");
7176
7177 if(!ajStrMatchC(type, "Index"))
7178 return ajFalse;
7179
7180 if(ajStrSuffixC(str, "len"))
7181 ajStrAssignSubS(&prefix, str, 0, -4);
7182 else if(ajStrSuffixC(str, "seccachesize"))
7183 ajStrAssignSubS(&prefix, str, 0, -13);
7184 else if(ajStrSuffixC(str, "cachesize"))
7185 ajStrAssignSubS(&prefix, str, 0, -10);
7186 else if(ajStrSuffixC(str, "secpagesize"))
7187 ajStrAssignSubS(&prefix, str, 0, -12);
7188 else if(ajStrSuffixC(str, "pagesize"))
7189 ajStrAssignSubS(&prefix, str, 0, -9);
7190 else
7191 return ajFalse;
7192
7193 if(ajStrGetLen(prefix))
7194 {
7195 fields = ajTableFetchC(rstable, "fields");
7196
7197 if(fields)
7198 {
7199 handle = ajStrTokenNewC(fields, " ,;");
7200
7201 while(ajStrTokenNextParse(handle, &field))
7202 if(ajStrMatchS(prefix, field))
7203 ret = ajTrue;
7204 }
7205 else
7206 {
7207 fdlist = ajTableFetchmodC(rstable, "field");
7208
7209 if(fdlist)
7210 {
7211 iter = ajListIterNewread(fdlist);
7212
7213 while(!ajListIterDone(iter))
7214 {
7215 fields = ajListIterGet(iter);
7216 ajStrTokenAssignC(&handle, fields, " ,;");
7217
7218 while(ajStrTokenNextParse(handle, &field))
7219 {
7220 if(ajStrMatchC(field, "!"))
7221 break;
7222
7223 if(ajStrMatchS(prefix, field))
7224 ret = ajTrue;
7225 }
7226 }
7227
7228 ajListIterDel(&iter);
7229 }
7230 else
7231 {
7232 attr = ajTableFetchC(namResAttrTable, "fields");
7233
7234 if(attr)
7235 {
7236 handle = ajStrTokenNewcharC(attr->Defval, " ,;");
7237
7238 while(ajStrTokenNextParse(handle, &field))
7239 if(ajStrMatchS(prefix, field))
7240 ret = ajTrue;
7241 }
7242
7243 }
7244
7245 }
7246
7247
7248
7249 ajStrTokenDel(&handle);
7250 ajStrDel(&field);
7251 }
7252
7253 ajStrDel(&prefix);
7254
7255 return ret;
7256 }
7257
7258
7259
7260
7261 /* @func ajNamExit ************************************************************
7262 **
7263 ** Delete the initialisation values in the table.
7264 ** @return [void]
7265 **
7266 ** @release 1.0.0
7267 ** @@
7268 ******************************************************************************/
7269
ajNamExit(void)7270 void ajNamExit(void)
7271 {
7272 namListMasterDelete(namVarMasterTable, TYPE_ENV); /* Delete elements */
7273 ajTableFree(&namVarMasterTable); /* free table and database structures */
7274 namListMasterDelete(namAliasMasterTable, TYPE_ALIAS); /* Delete elements */
7275 ajTableFree(&namAliasMasterTable); /* free table and database structures */
7276 namListMasterDelete(namSvrMasterTable, TYPE_SVR); /* Delete elements */
7277 ajTableFree(&namSvrMasterTable); /* free table and database structures */
7278 namListMasterDelete(namDbMasterTable, TYPE_DB); /* Delete elements */
7279 ajTableFree(&namDbMasterTable); /* free table and database structures */
7280 namListMasterDelete(namResMasterTable, TYPE_RESOURCE);/* Delete elements */
7281 ajTableFree(&namResMasterTable); /* free table and database structures */
7282 namListMasterDelete(namSvrDatabaseTable, TYPE_SVRDB);/* Delete elements */
7283 ajTableFree(&namSvrDatabaseTable); /* free table and database structures */
7284 namListMasterDelete(namSvrAliasTable, TYPE_SVRALI);/* Delete elements */
7285 ajTableFree(&namSvrAliasTable); /* free table and database structures */
7286
7287 ajTablestrFreeKey(&namDbTypeTable); /* free table and strings */
7288
7289 ajTablestrFree(&namSvrAttrTable); /* free table and strings */
7290 ajTablestrFree(&namDbAttrTable); /* free table and strings */
7291 ajTablestrFree(&namResAttrTable); /* free table and strings */
7292
7293 ajStrDel(&namFixedBaseStr); /* allocated in ajNamInit */
7294 ajStrDel(&namFixedRootStr); /* allocated in ajNamInit */
7295 ajStrDel(&namFixedInstallStr); /* allocated in ajNamInit */
7296 ajStrDel(&namFixedPackageStr); /* allocated in ajNamInit */
7297 ajStrDel(&namFixedSystemStr); /* allocated in ajNamInit */
7298 ajStrDel(&namFixedVersionStr); /* allocated in ajNamInit */
7299 ajStrDel(&namPrefixStr); /* allocated in ajNamInit */
7300 ajStrDel(&namFileOrig); /* allocated in ajNamInit */
7301 ajStrDel(&namRootStr); /* allocated in ajNamInit */
7302
7303 ajStrDel(&namFileName); /* allocated in ajNamProcessFile */
7304 ajStrDel(&namValNameTmp);
7305 ajStrDel(&namCmpStr);
7306 ajStrDel(&namStandardDir);
7307 ajStrDel(&namStandardFilename);
7308 ajStrDel(&namUserDir);
7309 ajStrDel(&namUserFilename);
7310
7311 ajRegFree(&namNameExp);
7312 ajRegFree(&namVarExp);
7313
7314 ajListFree(&namIfList);
7315
7316 ajDebug("ajNamExit done\n");
7317
7318 return;
7319 }
7320
7321
7322
7323
7324 /* @func ajNamSvrTest *********************************************************
7325 **
7326 ** Looks for a server name in the known definitions.
7327 **
7328 ** @param [r] svrname [const AjPStr] Server name.
7329 ** @return [AjBool] ajTrue on success.
7330 **
7331 ** @release 6.4.0
7332 ** @@
7333 ******************************************************************************/
7334
ajNamSvrTest(const AjPStr svrname)7335 AjBool ajNamSvrTest(const AjPStr svrname)
7336 {
7337 const NamPEntry data;
7338
7339 data = ajTableFetchS(namSvrMasterTable, svrname);
7340
7341 if(!data)
7342 return ajFalse;
7343
7344 return ajTrue;
7345 }
7346
7347
7348
7349
7350 /* @func ajNamSvrGetUrl *******************************************************
7351 **
7352 ** Gets the URL definition for a server definition.
7353 **
7354 ** @param [r] svrname [const AjPStr] Server name.
7355 ** @param [w] url [AjPStr*] URL returned.
7356 ** @return [AjBool] ajTrue if success.
7357 **
7358 ** @release 6.4.0
7359 ** @@
7360 ******************************************************************************/
7361
ajNamSvrGetUrl(const AjPStr svrname,AjPStr * url)7362 AjBool ajNamSvrGetUrl(const AjPStr svrname, AjPStr* url)
7363 {
7364
7365 const NamPEntry data;
7366 AjPTable svrtable;
7367 const AjPStr svrval = NULL;
7368
7369 data = ajTableFetchS(namSvrMasterTable, svrname);
7370
7371 if(!data)
7372 ajFatal("%S is not a known server", svrname);
7373
7374 svrtable = (AjPTable) data->data;
7375
7376 svrval = ajTableFetchC(svrtable, "url");
7377
7378 if(ajStrGetLen(svrval))
7379 {
7380 ajStrAssignS(url, svrval);
7381
7382 return ajTrue;
7383 }
7384
7385 return ajFalse;
7386 }
7387
7388
7389
7390
7391 /* @func ajNamQueryGetDatatypeC ***********************************************
7392 **
7393 ** Gets the datatype matching a query, and updates the datatype in the query
7394 **
7395 ** @param [r] qry [const AjPQuery] Database query
7396 ** @return [const char*] Database type
7397 **
7398 ** @release 6.4.0
7399 ** @@
7400 ******************************************************************************/
7401
ajNamQueryGetDatatypeC(const AjPQuery qry)7402 const char* ajNamQueryGetDatatypeC(const AjPQuery qry)
7403 {
7404 ajuint i;
7405 const char* ret = NULL;
7406
7407 if(ajStrGetLen(qry->DbType))
7408 return MAJSTRGETPTR(qry->DbType);
7409
7410 for(i=0; namDbTypes[i].Name; i++)
7411 if(namDbTypes[i].DataType == qry->DataType)
7412 ret = namDbTypes[i].Name;
7413
7414 return ret;
7415 }
7416
7417
7418
7419
7420 /* @func ajNamQueryGetUrl *****************************************************
7421 **
7422 ** Gets the URL definition for a server definition.
7423 **
7424 ** @param [r] qry [const AjPQuery] Database query
7425 ** @return [const AjPStr] URL value
7426 **
7427 ** @release 6.4.0
7428 ** @@
7429 ******************************************************************************/
7430
ajNamQueryGetUrl(const AjPQuery qry)7431 const AjPStr ajNamQueryGetUrl(const AjPQuery qry)
7432 {
7433 const AjPStr ret = NULL;
7434 const AjPStr svrval = NULL;
7435 const AjPTable dbtable;
7436
7437 dbtable = namQuerySvrdata(qry);
7438
7439 svrval = ajTableFetchC(dbtable, "url");
7440
7441 if(svrval)
7442 ret = svrval;
7443
7444 dbtable = namQueryDbdata(qry);
7445
7446 svrval = ajTableFetchC(dbtable, "url");
7447
7448 if(svrval)
7449 ret = svrval;
7450
7451 return ret;
7452 }
7453
7454
7455
7456
7457 /* @funcstatic namQuerySvrdata ************************************************
7458 **
7459 ** Gets the URL definition for a server definition.
7460 **
7461 ** @param [r] qry [const AjPQuery] Query.
7462 ** @return [const AjPTable] DatabaseServer attributes table
7463 **
7464 ** @release 6.4.0
7465 ** @@
7466 ******************************************************************************/
7467
namQuerySvrdata(const AjPQuery qry)7468 static const AjPTable namQuerySvrdata(const AjPQuery qry)
7469 {
7470 const NamPEntry data;
7471
7472 if(!ajStrGetLen(qry->SvrName))
7473 return NULL;
7474
7475 data = ajTableFetchS(namSvrMasterTable, qry->SvrName);
7476
7477 if(!data)
7478 ajFatal("%S is not a known server", qry->SvrName);
7479
7480 return (const AjPTable) data->data;
7481
7482 }
7483
7484
7485
7486
7487 /* @funcstatic namQueryDbdata *************************************************
7488 **
7489 ** Gets the data table for a query database.
7490 **
7491 ** @param [r] qry [const AjPQuery] Database query
7492 ** @return [const AjPTable] Database attributes table
7493 **
7494 ** @release 6.4.0
7495 ** @@
7496 ******************************************************************************/
7497
namQueryDbdata(const AjPQuery qry)7498 static const AjPTable namQueryDbdata(const AjPQuery qry)
7499 {
7500 const NamPEntry data;
7501 const NamPEntry sdata;
7502 const AjPTable sdbtable;
7503
7504 if(ajStrGetLen(qry->SvrName))
7505 {
7506 sdata = ajTableFetchS(namSvrDatabaseTable, qry->SvrName);
7507 sdbtable = (const AjPTable) sdata->data;
7508 data = ajTableFetchS(sdbtable, qry->DbName);
7509
7510 if(!data)
7511 ajFatal("%S is not a known database for server %S",
7512 qry->DbName, qry->SvrName);
7513 }
7514 else
7515 {
7516 data = ajTableFetchS(namDbMasterTable, qry->DbName);
7517
7518 if(!data)
7519 ajFatal("%S is not a known database", qry->DbName);
7520 }
7521
7522 return (const AjPTable) data->data;
7523 }
7524
7525
7526
7527
7528 /* @func ajNamSvrGetDbalias ***************************************************
7529 **
7530 ** Gets alias names for a server's database.
7531 **
7532 ** @param [r] svrname [const AjPStr] Server name.
7533 ** @param [w] dbalias [AjPStr*] Alias returned.
7534 ** @return [AjBool] ajTrue if success.
7535 **
7536 ** @release 6.4.0
7537 ** @@
7538 ******************************************************************************/
7539
ajNamSvrGetDbalias(const AjPStr svrname,AjPStr * dbalias)7540 AjBool ajNamSvrGetDbalias(const AjPStr svrname, AjPStr* dbalias)
7541 {
7542 const NamPEntry data;
7543 const AjPTable svrtable;
7544 const AjPStr svrval = NULL;
7545
7546 data = ajTableFetchS(namSvrMasterTable, svrname);
7547
7548 if(!data)
7549 ajFatal("%S is not a known server", svrname);
7550
7551 svrtable = (AjPTable) data->data;
7552
7553 svrval = ajTableFetchC(svrtable, "dbalias");
7554
7555 if(ajStrGetLen(svrval))
7556 ajStrAssignS(dbalias, svrval);
7557 else
7558 {
7559 ajStrAssignS(dbalias, svrname);
7560 ajStrFmtLower(dbalias);
7561 }
7562
7563 return ajTrue;
7564 }
7565
7566
7567
7568
7569 /* @func ajNamSvrData *********************************************************
7570 **
7571 ** Given a query with server name, database name and search fields,
7572 ** fill in the common fields. The query fields are set later.
7573 **
7574 ** This part of the database definition is required (specifically
7575 ** the "fields" definition) for setting the query details.
7576 **
7577 ** See also ajNamSvrQuery, which calls this function if the common
7578 ** query data is not yet set.
7579 **
7580 ** @param [u] qry [AjPQuery] Query structure with at least
7581 ** dbname filled in
7582 ** @param [r] argc [ajuint] Number of additional attribute name/value pairs
7583 ** @param [v] [...] Variable length argument list
7584 ** @return [AjBool] ajTrue if success.
7585 **
7586 ** @release 6.4.0
7587 ** @@
7588 ******************************************************************************/
7589
ajNamSvrData(AjPQuery qry,ajuint argc,...)7590 AjBool ajNamSvrData(AjPQuery qry, ajuint argc, ...)
7591 {
7592
7593 const NamPEntry data;
7594 const NamPEntry dbdata;
7595
7596 const AjPTable svrtable;
7597 const AjPTable sdbtable;
7598 const AjPTable dbtable;
7599 AjPStrTok handle = NULL;
7600 AjPStr liststr = NULL;
7601 AjPStr token = NULL;
7602 ajuint i;
7603 const char* varAttrName;
7604 AjPStr* varAttrValue;
7605 va_list ap;
7606 const NamPType namtype;
7607 AjBool ok = ajTrue;
7608 AjEDataType testDataType = AJDATATYPE_UNKNOWN;
7609 AjPStr saveType = NULL;
7610 AjBool donecaseid = ajFalse;
7611 AjBool donehasacc = ajFalse;
7612 AjBool caseid = ajFalse;
7613 AjBool hasacc = ajFalse;
7614
7615 if(qry->SetServer)
7616 return ajTrue;
7617
7618 qry->SetServer = ajTrue;
7619
7620 data = ajTableFetchS(namSvrMasterTable, qry->SvrName);
7621
7622 if(!data)
7623 ajFatal("server %S unknown", qry->SvrName);
7624
7625 svrtable = (const AjPTable) data->data;
7626
7627 /* general defaults */
7628
7629 namSvrSetAttrStrC(svrtable, "type", &liststr);
7630 ajStrTokenAssignC(&handle, liststr, " ,;");
7631 ajStrAssignC(&qry->DbType, "");
7632
7633 ajDebug("Server type: '%S'\n", liststr);
7634
7635 while(ajStrTokenNextParse(handle, &token))
7636 {
7637 if(!ajStrSuffixCaseC(token,"features"))
7638 {
7639 if(ajStrPrefixCaseC(token, "n"))
7640 ajStrAssignC(&token, "Nucleotide");
7641 else if(ajStrPrefixCaseC(token, "p"))
7642 ajStrAssignC(&token, "Protein");
7643 }
7644
7645 namtype = ajTableFetchS(namDbTypeTable, token);
7646
7647 ajDebug("testing type '%S' namtype: '%s' \n",
7648 token, namtype->Name);
7649
7650 if(!namtype)
7651 {
7652 ajErr("Server %S type '%S' unknown", qry->SvrName, token);
7653 continue;
7654 }
7655
7656 ajDebug("test server type '%S' qry datatype %u nam "
7657 "datatype %u unk %u\n",
7658 token, qry->DataType, namtype->DataType, AJDATATYPE_UNKNOWN);
7659
7660 if(qry->DataType == AJDATATYPE_UNKNOWN) /* take first available */
7661 {
7662 if(testDataType == AJDATATYPE_UNKNOWN ||
7663 namtype->DataType == AJDATATYPE_TEXT)
7664 {
7665 testDataType = namtype->DataType;
7666 ajStrAssignS(&saveType, token);
7667 ajDebug("Save type %d '%S'\n", testDataType, saveType);
7668 }
7669 }
7670
7671 if(namtype->DataType == qry->DataType)
7672 {
7673 ajStrAssignS(&qry->DbType, token);
7674 break;
7675 }
7676 }
7677
7678 if(ajStrGetLen(qry->Formatstr))
7679 {
7680 if(ajStrGetLen(qry->DbType) &&
7681 !ajStrMatchC(qry->DbType, "unknown") &&
7682 !namInformatTest(qry->Formatstr, qry->DbType))
7683 {
7684 ajErr("Query format '%S' does not support datatype '%S'",
7685 qry->Formatstr, qry->DbType);
7686 ajStrDel(&saveType);
7687 return ajFalse;
7688 }
7689 }
7690 else
7691 {
7692 if(namSvrSetAttrStrC(svrtable, "format", &liststr))
7693 {
7694 ok = ajFalse;
7695 ajStrTokenAssignC(&handle, liststr, " ,;");
7696
7697 while(ajStrTokenNextParse(handle, &token))
7698 {
7699 if(namInformatTest(token, qry->DbType))
7700 {
7701 ok = ajTrue;
7702 ajStrAssignS(&qry->Formatstr, token);
7703 }
7704 if(saveType && namInformatTest(token, saveType))
7705 {
7706 ok = ajTrue;
7707 ajStrAssignS(&qry->Formatstr, token);
7708 }
7709 }
7710
7711 if(!ok)
7712 {
7713 ajErr("Server %S format(s) '%S' do not support "
7714 "datatype '%S'",
7715 qry->SvrName, liststr, qry->DbType);
7716 ajStrDel(&saveType);
7717 return ajFalse;
7718 }
7719 }
7720 }
7721
7722 namSvrSetAttrStrC(svrtable, "method", &qry->Method);
7723 namSvrSetAttrStrC(svrtable, "indexdirectory", &qry->IndexDir);
7724 namSvrSetAttrStrC(svrtable, "indexdirectory", &qry->Directory);
7725 namSvrSetAttrStrC(svrtable, "field", &qry->DbFields);
7726 namSvrSetAttrStrC(svrtable, "url", &qry->DbUrl);
7727 namSvrSetAttrStrC(svrtable, "proxy", &qry->DbProxy);
7728 namSvrSetAttrStrC(svrtable, "httpversion", &qry->DbHttpVer);
7729 namSvrSetAttrStrC(svrtable, "serverversion", &qry->ServerVer);
7730 if(namSvrSetAttrBoolC(svrtable, "caseidmatch", &caseid))
7731 {
7732 donecaseid = ajTrue;
7733 qry->CaseId = caseid;
7734 }
7735 if(namSvrSetAttrBoolC(svrtable, "hasaccession", &hasacc))
7736 {
7737 donehasacc = ajTrue;
7738 qry->HasAcc = hasacc;
7739 }
7740
7741 #ifdef WIN32
7742 ajStrExchangeKK(&qry->Directory, '/', '\\');
7743 if(ajStrPrefixC(qry->Directory, ".\\"))
7744 ajStrCutStart(&qry->Directory, 2);
7745 ajStrExchangeKK(&qry->IndexDir, '/', '\\');
7746 if(ajStrPrefixC(qry->IndexDir, ".\\"))
7747 ajStrCutStart(&qry->IndexDir, 2);
7748 #endif
7749
7750 if(argc)
7751 {
7752 va_start(ap, argc);
7753
7754 for(i=0; i < argc; i++)
7755 {
7756 varAttrName = va_arg(ap, const char*);
7757 varAttrValue = va_arg(ap, AjPStr*);
7758 namSvrSetAttrStrC(svrtable, varAttrName, varAttrValue);
7759 }
7760
7761 va_end(ap);
7762 }
7763
7764 ajDebug("ajNamSvrQuery SvrName '%S'\n", qry->SvrName);
7765 ajDebug(" DbName '%S'\n", qry->DbName);
7766 ajDebug(" DbType '%S'\n", qry->DbType);
7767 ajDebug(" Method '%S'\n", qry->Method);
7768 ajDebug(" Formatstr '%S'\n", qry->Formatstr);
7769 ajDebug(" IndexDir '%S'\n", qry->IndexDir);
7770 ajDebug(" Directory '%S'\n", qry->Directory);
7771
7772 if(ajStrGetLen(qry->DbName))
7773 {
7774 data = ajTableFetchS(namSvrDatabaseTable, qry->SvrName);
7775
7776 if(!data)
7777 {
7778 ajWarn("server %S has no databases", qry->SvrName);
7779 ajStrDel(&saveType);
7780 return ajFalse;
7781 }
7782
7783 sdbtable = (const AjPTable) data->data;
7784 dbdata = ajTableFetchS(sdbtable, qry->DbName);
7785
7786 if(!dbdata)
7787 ajFatal("server %S has no database %S", qry->SvrName, qry->DbName);
7788
7789 dbtable = (const AjPTable) dbdata->data;
7790
7791 /* general defaults */
7792
7793 if(namDbSetAttrStrC(dbtable, "type", &liststr))
7794 {
7795 ajDebug("db type '%S'\n", liststr);
7796
7797 ajStrTokenAssignC(&handle, liststr, " ,;");
7798 ajStrAssignC(&qry->DbType, "");
7799
7800 while(ajStrTokenNextParse(handle, &token))
7801 {
7802 if(!ajStrSuffixCaseC(token,"features"))
7803 {
7804 if(ajStrPrefixCaseC(token, "n"))
7805 ajStrAssignC(&token, "Nucleotide");
7806 else if(ajStrPrefixCaseC(token, "p"))
7807 ajStrAssignC(&token, "Protein");
7808 }
7809
7810 ajDebug("test token '%S' list '%S'\n", token, liststr);
7811
7812 namtype = ajTableFetchS(namDbTypeTable, token);
7813
7814 if(!namtype)
7815 {
7816 ajErr("Database %S type '%S' unknown", qry->DbName, token);
7817 continue;
7818 }
7819
7820 ajDebug("qry->DataType %u namtype->DataType %u type '%s'\n",
7821 qry->DataType, namtype->DataType, namtype->Name);
7822
7823 if(qry->DataType == AJDATATYPE_UNKNOWN) /* take first type */
7824 {
7825 if(testDataType == AJDATATYPE_UNKNOWN ||
7826 namtype->DataType == AJDATATYPE_TEXT)
7827 {
7828 testDataType = namtype->DataType;
7829 ajStrAssignS(&saveType, token);
7830 ajDebug("Save type %d '%S'\n", testDataType, saveType);
7831 }
7832 }
7833
7834 if(namtype->DataType == qry->DataType)
7835 {
7836 ajStrAssignS(&qry->DbType, token);
7837 break;
7838 }
7839 }
7840
7841 }
7842
7843 if(qry->DataType == AJDATATYPE_UNKNOWN)
7844 {
7845 qry->DataType = testDataType;
7846 ajStrAssignS(&qry->DbType, saveType);
7847 }
7848
7849 if(!ajStrGetLen(qry->DbType))
7850 {
7851 ajErr("Server %S database '%S' type(s) '%S' "
7852 "no match to query type '%s'",
7853 qry->SvrName, qry->DbName,
7854 liststr, ajQueryGetDatatype(qry));
7855 ajStrDel(&saveType);
7856 return ajFalse;
7857 }
7858
7859 if(ajStrGetLen(qry->Formatstr))
7860 {
7861 if(ajStrGetLen(qry->DbType) &&
7862 !ajStrMatchC(qry->DbType, "unknown") &&
7863 !namInformatTest(qry->Formatstr, qry->DbType))
7864 {
7865 ajErr("Query format '%S' does not support datatype '%S'",
7866 qry->Formatstr, qry->DbType);
7867 ajStrDel(&saveType);
7868 return ajFalse;
7869 }
7870 }
7871 else if (ajStrGetLen(qry->DbType))
7872 {
7873 if(namDbSetAttrStrC(dbtable, "format", &liststr))
7874 {
7875 ok = ajFalse;
7876 ajStrTokenAssignC(&handle, liststr, " ,;");
7877
7878 while(ajStrTokenNextParse(handle, &token))
7879 {
7880 if(namInformatTest(token, qry->DbType))
7881 {
7882 ok = ajTrue;
7883 ajStrAssignS(&qry->Formatstr, token);
7884 break;
7885 }
7886 }
7887
7888 if(!ok)
7889 {
7890 ajErr("Server %S database %S format(s) '%S' "
7891 "do not support datatype '%S'",
7892 qry->SvrName, qry->DbName, liststr, qry->DbType);
7893 ajStrDel(&saveType);
7894 return ajFalse;
7895 }
7896 }
7897 }
7898
7899 namDbSetAttrStrC(dbtable, "method", &qry->Method);
7900 namDbSetAttrStrC(dbtable, "app", &qry->Application);
7901 namDbSetAttrStrC(dbtable, "directory", &qry->IndexDir);
7902 namDbSetAttrStrC(dbtable, "indexdirectory", &qry->IndexDir);
7903 namDbSetAttrStrC(dbtable, "indexdirectory", &qry->Directory);
7904 namDbSetAttrStrC(dbtable, "directory", &qry->Directory);
7905 namDbSetAttrStrC(dbtable, "namespace", &qry->Namespace);
7906 namDbSetAttrStrC(dbtable, "organisms", &qry->Organisms);
7907 namDbSetAttrStrC(dbtable, "exclude", &qry->Exclude);
7908 namDbSetAttrStrC(dbtable, "filename", &qry->Filename);
7909 if(!namDbSetAttrStrC(dbtable, "field", &qry->DbFields))
7910 namDbSetAttrStrC(dbtable, "fields", &qry->DbFields);
7911 namDbSetAttrStrC(dbtable, "url", &qry->DbUrl);
7912 namDbSetAttrStrC(dbtable, "proxy", &qry->DbProxy);
7913 namDbSetAttrStrC(dbtable, "httpversion", &qry->DbHttpVer);
7914 namDbSetAttrStrC(dbtable, "serverversion", &qry->ServerVer);
7915 if(namDbSetAttrBoolC(dbtable, "caseidmatch", &caseid))
7916 {
7917 donecaseid = ajTrue;
7918 qry->CaseId = caseid;
7919 }
7920 if(namDbSetAttrBoolC(dbtable, "hasaccession", &hasacc))
7921 {
7922 donehasacc = ajTrue;
7923 qry->HasAcc = hasacc;
7924 }
7925
7926 namDbSetAttrStrC(dbtable, "identifier", &qry->DbIdentifier);
7927 namDbSetAttrStrC(dbtable, "accession", &qry->DbAccession);
7928 namDbSetAttrStrC(dbtable, "filters", &qry->DbFilter);
7929 namDbSetAttrStrC(dbtable, "return", &qry->DbReturn);
7930
7931 if(!donecaseid)
7932 qry->CaseId = caseid;
7933 if(!donehasacc)
7934 qry->HasAcc = hasacc;
7935
7936 #ifdef WIN32
7937 ajStrExchangeKK(&qry->Directory, '/', '\\');
7938 if(ajStrPrefixC(qry->Directory, ".\\"))
7939 ajStrCutStart(&qry->Directory, 2);
7940 ajStrExchangeKK(&qry->IndexDir, '/', '\\');
7941 if(ajStrPrefixC(qry->IndexDir, ".\\"))
7942 ajStrCutStart(&qry->IndexDir, 2);
7943 #endif
7944
7945 if(argc)
7946 {
7947 va_start(ap, argc);
7948
7949 for(i=0; i < argc; i++)
7950 {
7951 varAttrName = va_arg(ap, const char*);
7952 varAttrValue = va_arg(ap, AjPStr*);
7953 namDbSetAttrStrC(dbtable, varAttrName, varAttrValue);
7954 }
7955
7956 va_end(ap);
7957 }
7958 }
7959
7960 ajDebug("ajNamSvrData '%S:%S' method:%S type:%S format:%S\n",
7961 qry->SvrName, qry->DbName, qry->Method, qry->DbType,
7962 qry->Formatstr);
7963
7964 ajStrDel(&liststr);
7965 ajStrDel(&token);
7966
7967 ajStrTokenDel(&handle);
7968 ajStrDel(&saveType);
7969
7970 return ajTrue;
7971 }
7972
7973
7974
7975
7976 /* @func ajNamSvrQuery ********************************************************
7977 **
7978 ** Given a query with server name and search fields,
7979 ** fill in the access method and some common fields according
7980 ** to the query level.
7981 **
7982 ** @param [u] qry [AjPQuery] Query structure with at least
7983 ** svrname filled in
7984 ** @return [AjBool] ajTrue if success.
7985 **
7986 ** @release 6.4.0
7987 ** @@
7988 ******************************************************************************/
7989
ajNamSvrQuery(AjPQuery qry)7990 AjBool ajNamSvrQuery(AjPQuery qry)
7991 {
7992 const NamPEntry data;
7993 const AjPTable svrtable;
7994
7995 data = ajTableFetchS(namSvrMasterTable, qry->SvrName);
7996
7997 if(!data)
7998 ajFatal("server %S unknown", qry->SvrName);
7999
8000 svrtable = (const AjPTable) data->data;
8001
8002 if(!ajStrGetLen(qry->DbType))
8003 ajNamSvrData(qry, 0);
8004
8005 if((qry->QueryType == AJQUERY_ALL) ||
8006 ((qry->QueryType == AJQUERY_UNKNOWN) && !ajQueryIsSet(qry)))
8007 {
8008 /* must have a method for all entries */
8009 namSvrSetAttrStrC(svrtable, "methodall", &qry->Method);
8010 namSvrSetAttrStrC(svrtable, "formatall", &qry->Formatstr);
8011 namSvrSetAttrStrC(svrtable, "appall", &qry->Application);
8012 qry->QueryType = AJQUERY_ALL;
8013 }
8014 else /* must be able to query the database */
8015 {
8016 namSvrSetAttrStrC(svrtable, "methodquery", &qry->Method);
8017 namSvrSetAttrStrC(svrtable, "formatquery", &qry->Formatstr);
8018 namSvrSetAttrStrC(svrtable, "appquery", &qry->Application);
8019
8020 if((qry->QueryType != AJQUERY_QUERY) &&
8021 !ajQuerySetWild(qry)) /* ID - single entry may be available */
8022 {
8023 namSvrSetAttrStrC(svrtable, "methodentry", &qry->Method);
8024 namSvrSetAttrStrC(svrtable, "formatentry", &qry->Formatstr);
8025 namSvrSetAttrStrC(svrtable, "appentry", &qry->Application);
8026 qry->QueryType = AJQUERY_ENTRY;
8027 }
8028 else
8029 qry->QueryType = AJQUERY_QUERY;
8030 }
8031
8032
8033 if(!ajStrGetLen(qry->Method))
8034 {
8035 ajErr("No access method for server '%S'",
8036 qry->SvrName);
8037
8038 return ajFalse;
8039 }
8040
8041 return ajTrue;
8042 }
8043
8044
8045
8046
8047 /* @funcstatic namSvrSetAttrStrC **********************************************
8048 **
8049 ** Sets a named string attribute value from an attribute list.
8050 **
8051 ** @param [r] svrtable [const AjPTable] Attribute definitions table.
8052 ** @param [r] attrib [const char*] Attribute name.
8053 ** @param [w] qrystr [AjPStr*] Returned attribute value.
8054 ** @return [AjBool] ajTrue on success.
8055 **
8056 ** @release 6.4.0
8057 ** @@
8058 ******************************************************************************/
8059
namSvrSetAttrStrC(const AjPTable svrtable,const char * attrib,AjPStr * qrystr)8060 static AjBool namSvrSetAttrStrC(const AjPTable svrtable, const char* attrib,
8061 AjPStr* qrystr)
8062 {
8063 const void* svrval = NULL;
8064 const AjPStr strval = NULL;
8065 const NamPAttr attr = NULL;
8066 const AjPList fdlist = NULL;
8067 AjIList iter = NULL;
8068 AjPStrTok handle = NULL;
8069 AjPStr word = NULL;
8070
8071 attr = ajTableFetchC(namSvrAttrTable, attrib);
8072
8073 if(!attr)
8074 ajFatal("unknown attribute '%s' requested", attrib);
8075
8076 svrval = ajTableFetchC(svrtable, attrib);
8077
8078 if(svrval)
8079 {
8080 switch(attr->Type)
8081 {
8082 case ATTR_LIST:
8083 ajStrAssignC(qrystr, "");
8084 fdlist = (const AjPList) svrval;
8085 iter = ajListIterNewread(fdlist);
8086
8087 while(!ajListIterDone(iter))
8088 {
8089 strval = ajListIterGet(iter);
8090 ajStrTokenAssignC(&handle, strval, " ");
8091
8092 while(ajStrTokenNextParse(handle, &word))
8093 {
8094 if(ajStrMatchC(word, "!"))
8095 break;
8096
8097 if(ajStrGetLen(*qrystr))
8098 ajStrAppendK(qrystr, ' ');
8099
8100 ajStrAppendS(qrystr, word);
8101 }
8102 }
8103
8104 ajStrTokenDel(&handle);
8105 ajStrDel(&word);
8106 ajListIterDel(&iter);
8107 break;
8108
8109 default:
8110 if(!ajStrGetLen((const AjPStr) svrval))
8111 return ajFalse;
8112
8113 ajStrAssignS(qrystr, (const AjPStr) svrval);
8114 break;
8115 }
8116 }
8117 else
8118 {
8119 if(!strlen(attr->Defval))
8120 return ajFalse;
8121
8122 ajStrAssignC(qrystr, attr->Defval);
8123 }
8124
8125 namVarResolve(qrystr);
8126
8127 return ajTrue;
8128 }
8129
8130
8131
8132
8133 /* @funcstatic namSvrSetAttrBoolC *********************************************
8134 **
8135 ** Sets a named boolean attribute value from an attribute list.
8136 **
8137 ** @param [r] svrtable [const AjPTable] Attribute definitions table
8138 ** @param [r] attrib [const char*] Attribute name.
8139 ** @param [w] qrybool [AjBool*] Returned attribute value.
8140 ** @return [AjBool] ajTrue on success.
8141 **
8142 ** @release 6.4.0
8143 ** @@
8144 ******************************************************************************/
8145
namSvrSetAttrBoolC(const AjPTable svrtable,const char * attrib,AjBool * qrybool)8146 static AjBool namSvrSetAttrBoolC(const AjPTable svrtable, const char* attrib,
8147 AjBool* qrybool)
8148 {
8149 AjBool ret = ajTrue;
8150 AjPStr tmpstr = NULL;
8151 const AjPStr svrval = NULL;
8152 const char* txtval = NULL;
8153 const NamPAttr attrval = NULL;
8154
8155 svrval = ajTableFetchC(svrtable, attrib);
8156
8157 if(svrval)
8158 txtval = ajStrGetPtr(svrval);
8159 else
8160 {
8161 attrval = ajTableFetchC(namSvrAttrTable, attrib);
8162
8163 if(!attrval)
8164 ajFatal("unknown attribute '%s' requested", attrib);
8165
8166 txtval = attrval->Defval;
8167 }
8168
8169 if(ajStrGetLen(svrval))
8170 {
8171 ajStrAssignS(&tmpstr, svrval);
8172 ret = ajTrue;
8173 }
8174 else
8175 {
8176 ajStrAssignC(&tmpstr, txtval);
8177 ret = ajFalse;
8178 }
8179
8180 /* ajDebug("namSvrSetAttr('%S')\n", *qrystr); */
8181
8182 namVarResolve(&tmpstr);
8183 ajStrToBool(tmpstr, qrybool);
8184 ajStrDel(&tmpstr);
8185
8186 return ret;
8187 }
8188
8189
8190
8191
8192 /* @func ajNamDbTest **********************************************************
8193 **
8194 ** Looks for a database name in the known definitions.
8195 **
8196 ** @param [r] dbname [const AjPStr] Database name.
8197 ** @return [AjBool] ajTrue on success.
8198 **
8199 ** @release 1.0.0
8200 ** @@
8201 ******************************************************************************/
8202
ajNamDbTest(const AjPStr dbname)8203 AjBool ajNamDbTest(const AjPStr dbname)
8204 {
8205 const NamPEntry data;
8206
8207 data = ajTableFetchS(namDbMasterTable, dbname);
8208
8209 if(!data)
8210 return ajFalse;
8211
8212 return ajTrue;
8213 }
8214
8215
8216
8217
8218 /* @func ajNamDbGetType *******************************************************
8219 **
8220 ** Gets the enumerated type for a database definition.
8221 **
8222 ** @param [r] dbname [const AjPStr] Database name.
8223 ** @param [w] itype [ajuint*] Database enumerated type
8224 ** @return [AjBool] ajTrue if success.
8225 **
8226 ** @release 6.4.0
8227 ** @@
8228 ******************************************************************************/
8229
ajNamDbGetType(const AjPStr dbname,ajuint * itype)8230 AjBool ajNamDbGetType(const AjPStr dbname, ajuint *itype)
8231 {
8232 AjBool ret = ajFalse;
8233 const NamPEntry data;
8234 const AjPTable dbtable;
8235 const AjPStr dbval = NULL;
8236 AjPStrTok handle = NULL;
8237 AjPStr token = NULL;
8238 const NamPType namtype;
8239
8240 data = ajTableFetchS(namDbMasterTable, dbname);
8241
8242 if(!data)
8243 ajFatal("%S is not a known database", dbname);
8244
8245 dbtable = (const AjPTable) data->data;
8246
8247 dbval = ajTableFetchC(dbtable, "type");
8248 ajStrTokenAssignC(&handle, dbval, " ,;");
8249
8250 while(ajStrTokenNextParse(handle, &token))
8251 {
8252 if(!ajStrSuffixCaseC(token,"features"))
8253 {
8254 if(ajStrPrefixCaseC(token, "n"))
8255 ajStrAssignC(&token, "Nucleotide");
8256 else if(ajStrPrefixCaseC(token, "p"))
8257 ajStrAssignC(&token, "Protein");
8258 }
8259
8260 namtype = ajTableFetchS(namDbTypeTable, token);
8261 ajDebug("testing type '%S' namtype: '%s' \n",
8262 token, namtype->Name);
8263
8264 *itype = namtype->DataType;
8265 ret = ajTrue;
8266 break;
8267 }
8268
8269 ajStrTokenDel(&handle);
8270 ajStrDel(&token);
8271
8272 return ret;
8273 }
8274
8275
8276
8277
8278 /* @func ajNamDbGetUrl ********************************************************
8279 **
8280 ** Gets the URL definition for a database definition.
8281 **
8282 ** @param [r] dbname [const AjPStr] Database name.
8283 ** @param [w] url [AjPStr*] URL returned.
8284 ** @return [AjBool] ajTrue if success.
8285 **
8286 ** @release 1.0.0
8287 ** @@
8288 ******************************************************************************/
8289
ajNamDbGetUrl(const AjPStr dbname,AjPStr * url)8290 AjBool ajNamDbGetUrl(const AjPStr dbname, AjPStr* url)
8291 {
8292
8293 const NamPEntry data;
8294 const AjPTable dbtable;
8295 const AjPStr dbval = NULL;
8296
8297 data = ajTableFetchS(namDbMasterTable, dbname);
8298
8299 if(!data)
8300 ajFatal("%S is not a known database", dbname);
8301
8302 dbtable = (const AjPTable) data->data;
8303
8304 dbval = ajTableFetchC(dbtable, "url");
8305
8306 if(ajStrGetLen(dbval))
8307 {
8308 ajStrAssignS(url, dbval);
8309
8310 return ajTrue;
8311 }
8312
8313 if(ajStrGetLen(*url))
8314 return ajTrue;
8315
8316 return ajFalse;
8317 }
8318
8319
8320
8321
8322 /* @func ajNamDbGetDbalias ****************************************************
8323 **
8324 ** Gets an alias name for a database.
8325 **
8326 ** @param [r] dbname [const AjPStr] Database name.
8327 ** @param [w] dbalias [AjPStr*] Alias returned.
8328 ** @return [AjBool] ajTrue if success.
8329 **
8330 ** @release 1.0.0
8331 ** @@
8332 ******************************************************************************/
8333
ajNamDbGetDbalias(const AjPStr dbname,AjPStr * dbalias)8334 AjBool ajNamDbGetDbalias(const AjPStr dbname, AjPStr* dbalias)
8335 {
8336
8337 const NamPEntry data;
8338 const AjPTable dbtable;
8339 const AjPStr dbval = NULL;
8340
8341 data = ajTableFetchS(namDbMasterTable, dbname);
8342
8343 if(!data)
8344 ajFatal("%S is not a known database", dbname);
8345
8346 dbtable = (const AjPTable) data->data;
8347
8348 dbval = ajTableFetchC(dbtable, "dbalias");
8349
8350 if(ajStrGetLen(dbval))
8351 ajStrAssignS(dbalias, dbval);
8352 else
8353 {
8354 ajStrAssignS(dbalias, dbname);
8355 ajStrFmtLower(dbalias);
8356 }
8357
8358 return ajTrue;
8359 }
8360
8361
8362
8363
8364 /* @func ajNamDbGetDbaliasTest ***********************************************
8365 **
8366 ** Gets an alias name for a database,
8367 ** no fatal error if the database name is not found
8368 **
8369 ** @param [r] dbname [const AjPStr] Database name.
8370 ** @param [w] dbalias [AjPStr*] Alias returned.
8371 ** @return [AjBool] ajTrue if success.
8372 **
8373 ** @release 1.0.0
8374 ** @@
8375 ******************************************************************************/
8376
ajNamDbGetDbaliasTest(const AjPStr dbname,AjPStr * dbalias)8377 AjBool ajNamDbGetDbaliasTest(const AjPStr dbname, AjPStr* dbalias)
8378 {
8379
8380 const NamPEntry data;
8381 const AjPTable dbtable;
8382 const AjPStr dbval = NULL;
8383
8384 data = ajTableFetchS(namDbMasterTable, dbname);
8385
8386 if(!data)
8387 return ajFalse;
8388
8389 dbtable = (const AjPTable) data->data;
8390
8391 dbval = ajTableFetchC(dbtable, "dbalias");
8392
8393 if(ajStrGetLen(dbval))
8394 ajStrAssignS(dbalias, dbval);
8395 else
8396 {
8397 ajStrAssignS(dbalias, dbname);
8398 ajStrFmtLower(dbalias);
8399 }
8400
8401 return ajTrue;
8402 }
8403
8404
8405
8406
8407 /* @func ajNamDbGetIndexdir ***************************************************
8408 **
8409 ** Gets the index directory for a database.
8410 **
8411 ** @param [r] dbname [const AjPStr] Database name.
8412 ** @param [w] indexdir [AjPStr*] Directory path returned.
8413 ** @return [AjBool] ajTrue if success.
8414 **
8415 ** @release 6.4.0
8416 ** @@
8417 ******************************************************************************/
8418
ajNamDbGetIndexdir(const AjPStr dbname,AjPStr * indexdir)8419 AjBool ajNamDbGetIndexdir(const AjPStr dbname, AjPStr* indexdir)
8420 {
8421
8422 const NamPEntry data;
8423 const AjPTable dbtable;
8424 const AjPStr dbval = NULL;
8425
8426 data = ajTableFetchS(namDbMasterTable, dbname);
8427
8428 if(!data)
8429 ajFatal("%S is not a known database", dbname);
8430
8431 dbtable = (const AjPTable) data->data;
8432
8433 dbval = ajTableFetchC(dbtable, "indexdirectory");
8434
8435 if(ajStrGetLen(dbval))
8436 {
8437 ajStrAssignS(indexdir, dbval);
8438 return ajTrue;
8439 }
8440
8441 dbval = ajTableFetchC(dbtable, "directory");
8442
8443 if(ajStrGetLen(dbval))
8444 {
8445 ajStrAssignS(indexdir, dbval);
8446 return ajTrue;
8447 }
8448
8449 return ajFalse;
8450 }
8451
8452
8453
8454
8455 /* @func ajNamQuerySetDbalias *************************************************
8456 **
8457 ** Sets an alias name for a database query.
8458 **
8459 ** @param [u] qry [AjPQuery] Database query.
8460 ** @return [AjBool] ajTrue if success.
8461 **
8462 ** @release 6.4.0
8463 ** @@
8464 ******************************************************************************/
8465
ajNamQuerySetDbalias(AjPQuery qry)8466 AjBool ajNamQuerySetDbalias(AjPQuery qry)
8467 {
8468 const NamPEntry data;
8469 const NamPEntry sdata;
8470 const AjPTable dbtable;
8471 const AjPTable sdbtable;
8472 const AjPStr dbval = NULL;
8473
8474 if(ajStrGetLen(qry->SvrName))
8475 {
8476 if(!ajStrGetLen(qry->DbType))
8477 ajNamSvrData(qry, 0);
8478
8479 ajNamSvrQuery(qry);
8480 sdata = ajTableFetchS(namSvrDatabaseTable, qry->SvrName);
8481 sdbtable = (const AjPTable) sdata->data;
8482 data = ajTableFetchS(sdbtable, qry->DbName);
8483
8484 if(!data)
8485 ajFatal("%S is not a known database for server %S",
8486 qry->DbName, qry->SvrName);
8487 }
8488 else
8489 {
8490 data = ajTableFetchS(namDbMasterTable, qry->DbName);
8491
8492 if(!data)
8493 ajFatal("%S is not a known database", qry->DbName);
8494 }
8495
8496 dbtable = (const AjPTable) data->data;
8497
8498 dbval = ajTableFetchC(dbtable, "dbalias");
8499
8500 if(ajStrGetLen(dbval))
8501 ajStrAssignS(&qry->DbAlias, dbval);
8502 else
8503 {
8504 ajStrAssignS(&qry->DbAlias, qry->DbName);
8505 ajStrFmtLower(&qry->DbAlias);
8506 }
8507
8508 return ajTrue;
8509 }
8510
8511
8512
8513
8514 /* @func ajNamDbData **********************************************************
8515 **
8516 ** Given a query with database name and search fields,
8517 ** fill in the common fields. The query fields are set later.
8518 **
8519 ** This part of the database definition is required (specifically
8520 ** the "fields" definition) for setting the query details.
8521 **
8522 ** See also ajNamDbQuery, which calls this function if the common
8523 ** query data is not yet set.
8524 **
8525 ** @param [u] qry [AjPQuery] Query structure with at least
8526 ** dbname filled in
8527 ** @param [r] argc [ajuint] Number of additional attribute name/value pairs
8528 ** @param [v] [...] Variable length argument list
8529 ** @return [AjBool] ajTrue if success.
8530 **
8531 ** @release 2.4.0
8532 ** @@
8533 ******************************************************************************/
8534
ajNamDbData(AjPQuery qry,ajuint argc,...)8535 AjBool ajNamDbData(AjPQuery qry, ajuint argc, ...)
8536 {
8537 const NamPEntry data;
8538 const AjPTable dbtable;
8539 AjPStrTok handle = NULL;
8540 AjPStr liststr = NULL;
8541 AjPStr token = NULL;
8542 ajuint i;
8543 const char* varAttrName;
8544 AjPStr* varAttrValue;
8545 va_list ap;
8546 const NamPType namtype;
8547 AjBool ok = ajTrue;
8548
8549 if(qry->SetDatabase)
8550 return ajTrue;
8551
8552 qry->SetDatabase = ajTrue;
8553
8554 data = ajTableFetchS(namDbMasterTable, qry->DbName);
8555
8556 if(!data)
8557 {
8558 ajDebug("ajNamDbData: database %S unknown\n", qry->DbName);
8559 return ajFalse;
8560 }
8561
8562 dbtable = (const AjPTable) data->data;
8563
8564 /* general defaults */
8565
8566 if(namDbSetAttrStrC(dbtable, "type", &liststr))
8567 {
8568 ajStrTokenAssignC(&handle, liststr, " ,;");
8569 ajStrAssignC(&qry->DbType, "");
8570
8571 while(ajStrTokenNextParse(handle, &token))
8572 {
8573 if(ajStrMatchCaseC(token, "n"))
8574 ajStrAssignC(&token, "Nucleotide");
8575 else if(ajStrMatchCaseC(token, "p"))
8576 ajStrAssignC(&token, "Protein");
8577 else if(ajStrMatchCaseC(token, "prot"))
8578 ajStrAssignC(&token, "Protein");
8579
8580 namtype = ajTableFetchS(namDbTypeTable, token);
8581
8582 if(!namtype)
8583 {
8584 ajErr("Database %S type '%S' unknown", qry->DbName, token);
8585 continue;
8586 }
8587
8588 if(qry->DataType == AJDATATYPE_UNKNOWN) /* take first available */
8589 qry->DataType = namtype->DataType;
8590
8591 if(namtype->DataType == qry->DataType)
8592 {
8593 ajStrAssignS(&qry->DbType, token);
8594 break;
8595 }
8596 }
8597
8598 if(!ajStrGetLen(qry->DbType))
8599 {
8600 ajErr("Database %S type(s) '%S' do not match query type '%s'",
8601 qry->DbName, liststr, ajQueryGetDatatype(qry));
8602 return ajFalse;
8603 }
8604 }
8605
8606 if(ajStrGetLen(qry->Formatstr))
8607 {
8608 if(!namInformatTest(qry->Formatstr, qry->DbType))
8609 {
8610 ajErr("Query format '%S' does not support datatype '%S'",
8611 qry->Formatstr, qry->DbType);
8612 return ajFalse;
8613 }
8614 }
8615 else
8616 {
8617 if(namDbSetAttrStrC(dbtable, "format", &liststr))
8618 {
8619 ok = ajFalse;
8620 ajStrTokenAssignC(&handle, liststr, " ,;");
8621
8622 while(ajStrTokenNextParse(handle, &token))
8623 {
8624 if(namInformatTest(token, qry->DbType))
8625 {
8626 ok = ajTrue;
8627 ajStrAssignS(&qry->Formatstr, token);
8628 }
8629 }
8630
8631 if(!ok)
8632 {
8633 ajErr("Database %S format(s) '%S' do not support "
8634 "datatype '%S'",
8635 qry->DbName, liststr, qry->DbType);
8636 return ajFalse;
8637 }
8638 }
8639 }
8640
8641 ajStrDel(&liststr);
8642 ajStrDel(&token);
8643 ajStrTokenDel(&handle);
8644
8645 namDbSetAttrStrC(dbtable, "method", &qry->Method);
8646 namDbSetAttrStrC(dbtable, "app", &qry->Application);
8647 namDbSetAttrStrC(dbtable, "directory", &qry->IndexDir);
8648 namDbSetAttrStrC(dbtable, "indexdirectory", &qry->IndexDir);
8649 namDbSetAttrStrC(dbtable, "indexdirectory", &qry->Directory);
8650 namDbSetAttrStrC(dbtable, "directory", &qry->Directory);
8651 namDbSetAttrStrC(dbtable, "namespace", &qry->Namespace);
8652 namDbSetAttrStrC(dbtable, "organisms", &qry->Organisms);
8653 namDbSetAttrStrC(dbtable, "exclude", &qry->Exclude);
8654 namDbSetAttrStrC(dbtable, "filename", &qry->Filename);
8655
8656 if(!namDbSetAttrStrC(dbtable, "field", &qry->DbFields))
8657 namDbSetAttrStrC(dbtable, "fields", &qry->DbFields);
8658
8659 namDbSetAttrStrC(dbtable, "url", &qry->DbUrl);
8660 namDbSetAttrStrC(dbtable, "proxy", &qry->DbProxy);
8661 namDbSetAttrStrC(dbtable, "httpversion", &qry->DbHttpVer);
8662 namDbSetAttrStrC(dbtable, "serverversion", &qry->ServerVer);
8663 namDbSetAttrBoolC(dbtable, "caseidmatch", &qry->CaseId);
8664 namDbSetAttrBoolC(dbtable, "hasaccession", &qry->HasAcc);
8665
8666 namDbSetAttrStrC(dbtable, "identifier", &qry->DbIdentifier);
8667 namDbSetAttrStrC(dbtable, "accession", &qry->DbAccession);
8668 namDbSetAttrStrC(dbtable, "filters", &qry->DbFilter);
8669 namDbSetAttrStrC(dbtable, "return", &qry->DbReturn);
8670
8671 #ifdef WIN32
8672 ajStrExchangeKK(&qry->Directory, '/', '\\');
8673 if(ajStrPrefixC(qry->Directory, ".\\"))
8674 ajStrCutStart(&qry->Directory, 2);
8675 ajStrExchangeKK(&qry->IndexDir, '/', '\\');
8676 if(ajStrPrefixC(qry->IndexDir, ".\\"))
8677 ajStrCutStart(&qry->IndexDir, 2);
8678 #endif
8679
8680
8681 if(argc)
8682 {
8683 va_start(ap, argc);
8684
8685 for(i=0; i < argc; i++)
8686 {
8687 varAttrName = va_arg(ap, const char*);
8688 varAttrValue = va_arg(ap, AjPStr*);
8689 namDbSetAttrStrC(dbtable, varAttrName, varAttrValue);
8690 }
8691
8692 va_end(ap);
8693 }
8694
8695 return ajTrue;
8696 }
8697
8698
8699
8700
8701 /* @func ajNamDbQuery *********************************************************
8702 **
8703 ** Given a query with database name and search fields,
8704 ** fill in the access method and some common fields according
8705 ** to the query level.
8706 **
8707 ** @param [u] qry [AjPQuery] Query structure with at least
8708 ** dbname filled in
8709 ** @return [AjBool] ajTrue if success.
8710 **
8711 ** @release 1.0.0
8712 ** @@
8713 ******************************************************************************/
8714
ajNamDbQuery(AjPQuery qry)8715 AjBool ajNamDbQuery(AjPQuery qry)
8716 {
8717
8718 const NamPEntry data;
8719 const NamPEntry sdata;
8720
8721 const AjPTable sdbtable;
8722
8723 const AjPTable dbtable;
8724 const char* qlinks;
8725
8726 ajDebug("ajNamDbQuery SetQuery:%B QueryType:%d\n",
8727 qry->SetQuery, qry->QueryType);
8728
8729 if(qry->SetQuery)
8730 return ajTrue;
8731
8732 qry->SetQuery = ajTrue;
8733
8734 if(qry->InDrcat)
8735 return ajTrue;
8736
8737 if(ajStrGetLen(qry->SvrName))
8738 {
8739 if(ajStrGetLen(qry->DbType))
8740 ajNamSvrData(qry, 0);
8741
8742 ajNamSvrQuery(qry);
8743 sdata = ajTableFetchS(namSvrDatabaseTable, qry->SvrName);
8744 sdbtable = (const AjPTable) sdata->data;
8745 data = ajTableFetchS(sdbtable, qry->DbName);
8746 }
8747 else
8748 data = ajTableFetchS(namDbMasterTable, qry->DbName);
8749
8750 if(!data)
8751 ajFatal("database %S unknown", qry->DbName);
8752
8753 dbtable = (const AjPTable) data->data;
8754
8755 if(!ajStrGetLen(qry->DbType))
8756 {
8757 if(!ajNamDbData(qry, 0))
8758 return ajFalse;
8759 }
8760
8761 if((qry->QueryType == AJQUERY_ALL) ||
8762 ((qry->QueryType == AJQUERY_UNKNOWN) && !ajQueryIsSet(qry)))
8763 {
8764 /* must have a method for all entries */
8765 namDbSetAttrStrC(dbtable, "methodall", &qry->Method);
8766 namDbSetAttrStrC(dbtable, "formatall", &qry->Formatstr);
8767 namDbSetAttrStrC(dbtable, "appall", &qry->Application);
8768 qry->QueryType = AJQUERY_ALL;
8769 }
8770 else /* must be able to query the database */
8771 {
8772 namDbSetAttrStrC(dbtable, "methodquery", &qry->Method);
8773 namDbSetAttrStrC(dbtable, "formatquery", &qry->Formatstr);
8774 namDbSetAttrStrC(dbtable, "appquery", &qry->Application);
8775
8776 if((qry->QueryType != AJQUERY_QUERY) &&
8777 !ajQuerySetWild(qry)) /* ID - single entry may be available */
8778 {
8779 namDbSetAttrStrC(dbtable, "methodentry", &qry->Method);
8780 namDbSetAttrStrC(dbtable, "formatentry", &qry->Formatstr);
8781 namDbSetAttrStrC(dbtable, "appentry", &qry->Application);
8782 qry->QueryType = AJQUERY_ENTRY;
8783 }
8784 else
8785 qry->QueryType = AJQUERY_QUERY;
8786 }
8787
8788 namDbSetAttrStrC(dbtable, "return", &qry->DbReturn);
8789
8790
8791 if(!ajStrGetLen(qry->Formatstr))
8792 {
8793 ajErr("No format defined for database '%S'", qry->DbName);
8794
8795 return ajFalse;
8796 }
8797
8798 if(!ajStrGetLen(qry->Method))
8799 {
8800 ajErr("No access method for database '%S'", qry->DbName);
8801
8802 return ajFalse;
8803 }
8804
8805 qlinks = namMethod2Qlinks(qry->Method, qry->DataType);
8806
8807 if(!qlinks)
8808 {
8809 ajErr("Unknown access method '%S' for database '%S'",
8810 qry->Method, qry->DbName);
8811 return ajFalse;
8812 }
8813
8814 ajStrAssignC(&qry->Qlinks, qlinks);
8815
8816 return ajTrue;
8817 }
8818
8819
8820
8821
8822 /* @func ajNamFileQuery *******************************************************
8823 **
8824 ** Given a query with no database name and search fields, check
8825 ** datatype specific fields according to the query level.
8826 **
8827 ** @param [u] qry [AjPQuery] Query structure with no database name
8828 ** @return [AjBool] ajTrue if success.
8829 **
8830 ** @release 6.4.0
8831 ** @@
8832 ******************************************************************************/
8833
ajNamFileQuery(AjPQuery qry)8834 AjBool ajNamFileQuery(AjPQuery qry)
8835 {
8836 const char* fields = NULL;
8837 const char* qlinks = NULL;
8838
8839 if(qry->SetQuery)
8840 return ajTrue;
8841
8842 qry->SetQuery = ajTrue;
8843
8844 if(ajStrGetLen(qry->SvrName))
8845 ajFatal("ajNamFileQuery called with server '%S'", qry->SvrName);
8846 else if(ajStrGetLen(qry->DbName))
8847 ajFatal("ajNamFileQuery called with database '%S'", qry->DbName);
8848
8849 switch(qry->QueryType)
8850 {
8851 case AJQUERY_ALL:
8852 break;
8853
8854 case AJQUERY_QUERY:
8855 break;
8856
8857 case AJQUERY_ENTRY:
8858 break;
8859
8860 case AJQUERY_UNKNOWN:
8861 default:
8862 break;
8863 }
8864
8865 /*
8866 if(!ajStrGetLen(qry->Formatstr))
8867 {
8868 ajErr("No format defined for file access query");
8869
8870 return ajFalse;
8871 }
8872 */
8873
8874 qlinks = namDatatype2Qlinks(qry->DataType);
8875
8876 if(qlinks)
8877 ajStrAssignC(&qry->Qlinks, qlinks);
8878 else
8879 {
8880 ajWarn("no query links defined for type; '%s'",
8881 namDbTypes[qry->DataType].Name);
8882 ajStrAssignC(&qry->Qlinks, "|");
8883 }
8884
8885 fields = namDatatype2Fields(qry->DataType);
8886
8887 if(fields)
8888 ajStrAssignC(&qry->DbFields, fields);
8889 else
8890 {
8891 ajWarn("no fields defined for type; '%s'",
8892 namDbTypes[qry->DataType].Name);
8893 ajStrAssignC(&qry->DbFields, "");
8894 }
8895
8896 return ajTrue;
8897 }
8898
8899
8900
8901
8902 /* @funcstatic namDbSetAttrStrC ***********************************************
8903 **
8904 ** Sets a named string attribute value from an attribute list.
8905 **
8906 ** @param [r] dbtable [const AjPTable] Attribute definitions table.
8907 ** @param [r] attrib [const char*] Attribute name.
8908 ** @param [w] qrystr [AjPStr*] Returned attribute value.
8909 ** @return [AjBool] ajTrue on success.
8910 **
8911 ** @release 6.4.0
8912 ** @@
8913 ******************************************************************************/
8914
namDbSetAttrStrC(const AjPTable dbtable,const char * attrib,AjPStr * qrystr)8915 static AjBool namDbSetAttrStrC(const AjPTable dbtable, const char* attrib,
8916 AjPStr* qrystr)
8917 {
8918 const void* dbval = NULL;
8919 const AjPStr strval = NULL;
8920 const NamPAttr attr = NULL;
8921 const AjPList fdlist = NULL;
8922 AjIList iter = NULL;
8923 AjPStrTok handle = NULL;
8924 AjPStr word = NULL;
8925 char delimchar = ' ';
8926
8927 attr = ajTableFetchC(namDbAttrTable, attrib);
8928
8929 if(!attr)
8930 ajFatal("unknown attribute '%s' requested", attrib);
8931
8932 dbval = ajTableFetchC(dbtable, attrib);
8933
8934 if(dbval)
8935 {
8936 switch(attr->Type)
8937 {
8938 case ATTR_LIST:
8939 ajStrAssignC(qrystr, "");
8940 fdlist = (const AjPList) dbval;
8941 iter = ajListIterNewread(fdlist);
8942
8943 while(!ajListIterDone(iter))
8944 {
8945 strval = ajListIterGet(iter);
8946 ajStrTokenAssignC(&handle, strval, " ");
8947
8948 while(ajStrTokenNextParse(handle, &word))
8949 {
8950 if(ajStrMatchC(word, "!"))
8951 break;
8952
8953 if(ajStrGetLen(*qrystr))
8954 {
8955 ajStrAppendK(qrystr, delimchar);
8956 delimchar = ' ';
8957 }
8958
8959 ajStrAppendS(qrystr, word);
8960 }
8961
8962 delimchar = ';';
8963 }
8964
8965 ajStrTokenDel(&handle);
8966 ajStrDel(&word);
8967 ajListIterDel(&iter);
8968 break;
8969
8970 default:
8971 if(!ajStrGetLen((const AjPStr) dbval))
8972 return ajFalse;
8973 ajStrAssignS(qrystr, (const AjPStr) dbval);
8974
8975 break;
8976 }
8977 }
8978 else
8979 {
8980 if(!strlen(attr->Defval))
8981 return ajFalse;
8982
8983 ajStrAssignC(qrystr, attr->Defval);
8984 }
8985
8986 namVarResolve(qrystr);
8987
8988 return ajTrue;
8989 }
8990
8991
8992
8993
8994 /* @funcstatic namDbSetAttrBoolC **********************************************
8995 **
8996 ** Sets a named boolean attribute value from an attribute list.
8997 **
8998 ** @param [r] dbtable [const AjPTable] Attribute definitions table
8999 ** @param [r] attrib [const char*] Attribute name.
9000 ** @param [w] qrybool [AjBool*] Returned attribute value.
9001 ** @return [AjBool] ajTrue on success.
9002 **
9003 ** @release 6.4.0
9004 ** @@
9005 ******************************************************************************/
9006
namDbSetAttrBoolC(const AjPTable dbtable,const char * attrib,AjBool * qrybool)9007 static AjBool namDbSetAttrBoolC(const AjPTable dbtable, const char* attrib,
9008 AjBool* qrybool)
9009 {
9010 AjBool ret = ajTrue;
9011 AjPStr tmpstr = NULL;
9012 const AjPStr dbval = NULL;
9013 const char* txtval = NULL;
9014 const NamPAttr attr = NULL;
9015
9016 dbval = ajTableFetchC(dbtable, attrib);
9017
9018 if(dbval)
9019 txtval = ajStrGetPtr(dbval);
9020 else
9021 {
9022 attr = ajTableFetchC(namDbAttrTable, attrib);
9023
9024 if(!attr)
9025 ajFatal("unknown attribute '%s' requested", attrib);
9026
9027 txtval = attr->Defval;
9028 }
9029
9030 if(!ajStrGetLen(dbval))
9031 {
9032 ajStrAssignC(&tmpstr, txtval);
9033 ret = ajFalse;
9034 }
9035 else
9036 {
9037 ajStrAssignS(&tmpstr, dbval);
9038 ret = ajTrue;
9039 }
9040
9041 /* ajDebug("namDbSetAttr('%S')\n", *qrystr); */
9042
9043 namVarResolve(&tmpstr);
9044 ajStrToBool(tmpstr, qrybool);
9045 ajStrDel(&tmpstr);
9046
9047 return ret;
9048 }
9049
9050
9051
9052
9053 /* @funcstatic namVarResolve **************************************************
9054 **
9055 ** Resolves any variable or function references in a string.
9056 **
9057 ** @param [u] var [AjPStr*] String value
9058 ** @return [AjBool] Always ajTrue so far
9059 **
9060 ** @release 1.0.0
9061 ** @@
9062 ******************************************************************************/
9063
namVarResolve(AjPStr * var)9064 static AjBool namVarResolve(AjPStr* var)
9065 {
9066
9067 AjPStr varname = NULL;
9068 AjPStr newvar = NULL;
9069 AjPStr restvar = NULL;
9070
9071 if(!namVarExp)
9072 namVarExp = ajRegCompC("^\\$([a-zA-Z0-9_.]+)");
9073
9074 while(ajRegExec(namVarExp, *var))
9075 {
9076 ajRegSubI(namVarExp, 1, &varname); /* variable name */
9077
9078 ajNamGetValueS(varname, &newvar);
9079
9080 ajDebug("namVarResolve '%S' = '%S'\n", varname, newvar);
9081
9082 if(ajRegPost(namVarExp, &restvar)) /* any more? */
9083 ajStrAppendS(&newvar, restvar);
9084
9085 ajStrAssignS(var, newvar);
9086 }
9087
9088 ajStrDel(&varname);
9089 ajStrDel(&newvar);
9090 ajStrDel(&restvar);
9091
9092 return ajFalse;
9093 }
9094
9095
9096
9097
9098 /* @funcstatic namUser ********************************************************
9099 **
9100 ** Formatted write as an error message.
9101 **
9102 ** @param [r] fmt [const char*] Format string
9103 ** @param [v] [...] Format arguments.
9104 ** @return [void]
9105 **
9106 ** @release 1.0.0
9107 ** @@
9108 ******************************************************************************/
9109
namUser(const char * fmt,...)9110 static void namUser(const char* fmt, ...)
9111 {
9112 va_list args;
9113
9114 if(!namDoDebug)
9115 return;
9116
9117 va_start(args, fmt);
9118 ajFmtVError(fmt, args);
9119 va_end(args);
9120
9121 return;
9122 }
9123
9124
9125
9126
9127 /* @funcstatic namError *******************************************************
9128 **
9129 ** Formatted write as an error message.
9130 **
9131 ** @param [r] fmt [const char*] Format string
9132 ** @param [v] [...] Format arguments.
9133 ** @return [void]
9134 **
9135 ** @release 2.7.0
9136 ** @@
9137 ******************************************************************************/
9138
namError(const char * fmt,...)9139 static void namError(const char* fmt, ...)
9140 {
9141 va_list args;
9142 AjPStr errstr = NULL;
9143
9144 namErrorCount++;
9145
9146 va_start(args, fmt);
9147 ajFmtVPrintS(&errstr, fmt, args);
9148 va_end(args);
9149
9150 ajErr("File %S line %d: %S", namFileName, namLine, errstr);
9151 ajStrDel(&errstr);
9152
9153 return;
9154 }
9155
9156
9157
9158
9159 /* @func ajNamValueInstalldir *************************************************
9160 **
9161 ** Returns the install directory root for all file searches
9162 ** (package level)
9163 **
9164 ** @return [const AjPStr] Install directory root
9165 **
9166 ** @release 6.0.0
9167 ** @@
9168 ******************************************************************************/
9169
ajNamValueInstalldir(void)9170 const AjPStr ajNamValueInstalldir(void)
9171 {
9172 return namFixedInstallStr;
9173 }
9174
9175
9176
9177
9178 /* @func ajNamValuePackage ****************************************************
9179 **
9180 ** Returns the package name for the library
9181 **
9182 ** @return [const AjPStr] Package name
9183 **
9184 ** @release 6.0.0
9185 ** @@
9186 ******************************************************************************/
9187
ajNamValuePackage(void)9188 const AjPStr ajNamValuePackage(void)
9189 {
9190 return namFixedPackageStr;
9191 }
9192
9193
9194
9195
9196 /* @func ajNamValueSystem *****************************************************
9197 **
9198 ** Returns the system information for the library
9199 **
9200 ** @return [const AjPStr] Version number
9201 **
9202 ** @release 6.2.0
9203 ** @@
9204 ******************************************************************************/
9205
ajNamValueSystem(void)9206 const AjPStr ajNamValueSystem(void)
9207 {
9208 return namFixedSystemStr;
9209 }
9210
9211
9212
9213
9214 /* @func ajNamValueVersion ****************************************************
9215 **
9216 ** Returns the version number for the library
9217 **
9218 ** @return [const AjPStr] Version number
9219 **
9220 ** @release 6.0.0
9221 ** @@
9222 ******************************************************************************/
9223
ajNamValueVersion(void)9224 const AjPStr ajNamValueVersion(void)
9225 {
9226 return namFixedVersionStr;
9227 }
9228
9229
9230
9231
9232 /* @func ajNamValueRootdir ****************************************************
9233 **
9234 ** Returns the directory for all file searches
9235 ** (package level)
9236 **
9237 ** @return [const AjPStr] Package level root directory
9238 **
9239 ** @release 6.0.0
9240 ** @@
9241 ******************************************************************************/
9242
ajNamValueRootdir(void)9243 const AjPStr ajNamValueRootdir(void)
9244 {
9245 return namFixedRootStr;
9246 }
9247
9248
9249
9250
9251 /* @func ajNamValueBasedir ****************************************************
9252 **
9253 ** Returns the base directory for all for all file searches
9254 ** (above package level).
9255 **
9256 ** @return [const AjPStr] Base directory
9257 **
9258 ** @release 6.0.0
9259 ******************************************************************************/
9260
ajNamValueBasedir(void)9261 const AjPStr ajNamValueBasedir(void)
9262 {
9263 return namFixedBaseStr;
9264 }
9265
9266
9267
9268
9269 /* @func ajNamResolve *********************************************************
9270 **
9271 ** Resolves a variable name if the input string starts with a dollar sign.
9272 **
9273 ** @param [w] name [AjPStr*] String
9274 ** @return [AjBool] ajTrue on success.
9275 **
9276 ** @release 1.0.0
9277 ** @@
9278 ******************************************************************************/
9279
ajNamResolve(AjPStr * name)9280 AjBool ajNamResolve(AjPStr* name)
9281 {
9282
9283 AjPStr varname = NULL;
9284 AjPStr varvalue = NULL;
9285 AjPStr restname = NULL;
9286 AjBool ret;
9287
9288 if(!namNameExp)
9289 namNameExp = ajRegCompC("^\\$([A-Za-z0-9_]+)");
9290
9291 namUser("ajNamResolve of '%S'\n", *name);
9292 ret = ajRegExec(namNameExp, *name);
9293
9294 if(ret)
9295 {
9296 ajRegSubI(namNameExp, 1, &varname);
9297 namUser("variable '%S' found\n", varname);
9298 ajRegPost(namNameExp, &restname);
9299 ret = ajNamGetValueS(varname, &varvalue);
9300
9301 if(ret)
9302 {
9303 ajStrAssignS(name, varvalue);
9304 ajStrAppendS(name, restname);
9305 namUser("converted to '%S'\n", *name);
9306 }
9307 else
9308 {
9309 namUser("Variable unknown '$%S'\n", varname);
9310 ajWarn("Variable unknown in '%S'", *name);
9311 ajStrAssignS(name, restname);
9312 }
9313
9314 ajStrDel(&varname);
9315 ajStrDel(&varvalue);
9316 ajStrDel(&restname);
9317 }
9318
9319 return ret;
9320 }
9321
9322
9323
9324
9325 /* @funcstatic namValid *******************************************************
9326 **
9327 ** Validation of a master table entry
9328 **
9329 ** @param [r] entry [const NamPEntry] Internal table entry
9330 ** @param [r] entrytype [ajint] Internal table entry type
9331 ** @return [AjBool] ajTrue on success
9332 **
9333 ** @release 2.7.0
9334 ** @@
9335 ******************************************************************************/
9336
namValid(const NamPEntry entry,ajint entrytype)9337 static AjBool namValid(const NamPEntry entry, ajint entrytype)
9338 {
9339 if(entrytype == TYPE_ENV)
9340 return namValidVariable(entry);
9341 else if(entrytype == TYPE_SVR)
9342 return namValidServer(entry);
9343 else if(entrytype == TYPE_DB)
9344 return namValidDatabase(entry);
9345 else if(entrytype == TYPE_RESOURCE)
9346 return namValidResource(entry);
9347 else if(entrytype == TYPE_ALIAS)
9348 return namValidAlias(entry);
9349
9350 /* fatal: cannot test - should not happen */
9351 namError("Unknown definition type number %d",
9352 entrytype);
9353
9354 return ajFalse;
9355 }
9356
9357
9358
9359
9360 /* @funcstatic namValidAlias **************************************************
9361 **
9362 ** Validation of a master table alias entry
9363 **
9364 ** @param [r] entry [const NamPEntry] Internal table entry
9365 ** @return [AjBool] ajTrue on success
9366 **
9367 ** @release 6.4.0
9368 ** @@
9369 ******************************************************************************/
9370
namValidAlias(const NamPEntry entry)9371 static AjBool namValidAlias(const NamPEntry entry)
9372 {
9373 AjPTable attrtable;
9374
9375 attrtable = (AjPTable) entry->data;
9376
9377 if(attrtable)
9378 { /* strange - should be nothing for aliases */
9379 namError("Alias '%S' has a list of attributes",
9380 entry->name);
9381
9382 return ajFalse;
9383 }
9384
9385 return ajTrue;
9386 }
9387
9388
9389
9390
9391 /* @funcstatic namValidServer *************************************************
9392 **
9393 ** Validation of a master table server entry
9394 **
9395 ** @param [r] entry [const NamPEntry] Internal table entry
9396 ** @return [AjBool] ajTrue on success
9397 **
9398 ** @release 6.4.0
9399 ** @@
9400 ******************************************************************************/
9401
namValidServer(const NamPEntry entry)9402 static AjBool namValidServer(const NamPEntry entry)
9403 {
9404 ajint iattr = 0;
9405 ajint j;
9406 ajint k;
9407 AjBool ok;
9408 AjBool oktype;
9409 AjPTable attrtable;
9410 AjBool hasmethod = ajFalse;
9411 AjBool hastype = ajFalse;
9412 AjPStr name = NULL;
9413 AjPStrTok handle = NULL;
9414 AjPStr token = NULL;
9415 const AjPStr value = NULL;
9416 const AjPStr dbtype = NULL;
9417
9418 attrtable = (AjPTable) entry->data;
9419
9420 if(!attrtable)
9421 { /* fatal - should be set for all servers */
9422 namError("Server '%S' has no list of valid attributes",
9423 entry->name);
9424 return ajFalse;
9425 }
9426
9427 dbtype = ajTableFetchC(attrtable, "type");
9428
9429 for(j=0; namSvrAttrs[j].Name; j++)
9430 {
9431 if(namSvrAttrs[j].Type != ATTR_STR)
9432 continue;
9433
9434 ajStrAssignC(&name, namSvrAttrs[j].Name);
9435 value = ajTableFetchS(attrtable, name);
9436
9437 if(value)
9438 {
9439 iattr++;
9440
9441 if(ajStrPrefixC(name, "format"))
9442 {
9443 if(!namInformatTest(value, dbtype))
9444 namError("Database '%S' %S: '%S' unknown",
9445 entry->name, name, value);
9446 }
9447
9448 if(ajStrPrefixC(name, "method"))
9449 {
9450 handle = NULL;
9451 token = ajStrNew();
9452 hasmethod=ajTrue;
9453
9454 ajStrTokenAssignC(&handle, dbtype, " ,;");
9455
9456 while(ajStrTokenNextParse(handle, &token))
9457 if(!namAccessTest(value, token))
9458 namError("Server '%S' %S: '%S' unknown",
9459 entry->name, name, value);
9460
9461 ajStrTokenDel(&handle);
9462 ajStrDel(&token);
9463 }
9464
9465 if(ajStrPrefixC(name, "type"))
9466 {
9467 hastype=ajTrue;
9468 oktype = ajFalse;
9469
9470 for(k=0; namDbTypes[k].Name; k++)
9471 if(ajStrFindAnyC(value, namDbTypes[k].Name) != -1)
9472 oktype = ajTrue;
9473
9474 if(!oktype)
9475 namError("Server '%S' %S: '%S' unknown",
9476 entry->name, name, value);
9477 }
9478 }
9479 }
9480
9481 ok = ajTrue;
9482
9483 if(!iattr)
9484 {
9485 namError("Server '%S' has no attributes", entry->name);
9486 ok = ajFalse;
9487 }
9488
9489 if(!hastype)
9490 {
9491 namError("Database '%S' has no type definition", entry->name);
9492 ok = ajFalse;
9493 }
9494
9495 if(!hasmethod)
9496 {
9497 namError("Database '%S' has no access method definition",
9498 entry->name);
9499 ok = ajFalse;
9500 }
9501
9502 ajStrDel(&name);
9503
9504 return ok;
9505 }
9506
9507
9508
9509
9510 /* @funcstatic namValidDatabase ***********************************************
9511 **
9512 ** Validation of a master table database entry
9513 **
9514 ** @param [r] entry [const NamPEntry] Internal table entry
9515 ** @return [AjBool] ajTrue on success
9516 **
9517 ** @release 2.7.0
9518 ** @@
9519 ******************************************************************************/
9520
namValidDatabase(const NamPEntry entry)9521 static AjBool namValidDatabase(const NamPEntry entry)
9522 {
9523 ajint iattr = 0;
9524 ajint j;
9525 ajint k;
9526 AjBool ok;
9527 AjBool oktype;
9528 AjPTable attrtable;
9529 AjBool hasformat = ajFalse;
9530 AjBool hasmethod = ajFalse;
9531 AjBool hastype = ajFalse;
9532 AjPStr name = NULL;
9533 AjPStr token = NULL;
9534 AjPStr typetoken = NULL;
9535 AjPStrTok handle = NULL;
9536 AjPStrTok typehandle = NULL;
9537 const AjPStr value = NULL;
9538 const AjPStr dbtype = NULL;
9539
9540 attrtable = (AjPTable) entry->data;
9541
9542 if(!attrtable)
9543 { /* fatal - should be set for all databases */
9544 namError("Database '%S' has no list of valid attributes",
9545 entry->name);
9546 return ajFalse;
9547 }
9548
9549 dbtype = ajTableFetchC(attrtable, "type");
9550
9551 for(j=0; namDbAttrs[j].Name; j++)
9552 {
9553 if(namDbAttrs[j].Type != ATTR_STR)
9554 continue;
9555
9556 ajStrAssignC(&name, namDbAttrs[j].Name);
9557 value = ajTableFetchS(attrtable, name);
9558
9559 if(value)
9560 {
9561 iattr++;
9562
9563 if(ajStrPrefixC(name, "format"))
9564 {
9565 hasformat=ajTrue;
9566
9567 ajStrTokenAssignC(&typehandle, dbtype, " ,;");
9568
9569 while(ajStrTokenNextParse(typehandle, &typetoken))
9570 {
9571 ok = ajFalse;
9572 ajStrTokenAssignC(&handle, value, " ,;");
9573 while(ajStrTokenNextParse(handle, &token))
9574 {
9575 if(namInformatTest(token, typetoken))
9576 ok = ajTrue;
9577 }
9578
9579 if(!ok) /* test: dbunknowns.rc */
9580 namError("Database '%S' %S: '%S' unknown for type '%S'",
9581 entry->name, name, value, typetoken);
9582 }
9583
9584 }
9585
9586 if(ajStrPrefixC(name, "method"))
9587 {
9588 hasmethod=ajTrue;
9589
9590 ajStrTokenAssignC(&typehandle, dbtype, " ,;");
9591
9592 while(ajStrTokenNextParse(typehandle, &typetoken))
9593 {
9594 ok = ajFalse;
9595 ajStrTokenAssignC(&handle, value, " ,;");
9596 while(ajStrTokenNextParse(handle, &token))
9597 {
9598 if(namAccessTest(value, typetoken))
9599 ok = ajTrue;
9600 }
9601
9602 if(!ok) /* test: dbunknowns.rc */
9603 namError("Database '%S' %S: '%S' unknown for type '%S'",
9604 entry->name, name, value, typetoken);
9605 }
9606 }
9607
9608 if(ajStrPrefixC(name, "type"))
9609 {
9610 hastype=ajTrue;
9611 oktype = ajFalse;
9612
9613 ajStrTokenAssignC(&typehandle, value, " ,;");
9614 while(ajStrTokenNextParse(typehandle, &typetoken))
9615 {
9616 for(k=0; namDbTypes[k].Name; k++)
9617 if(ajStrMatchCaseC(typetoken, namDbTypes[k].Name))
9618 oktype = ajTrue;
9619 }
9620
9621 if(!oktype) /* test: dbunknowns.rc */
9622 namError("Database '%S' %S: '%S' unknown",
9623 entry->name, name, value);
9624 }
9625 }
9626 }
9627
9628 ok = ajTrue;
9629
9630 if(!iattr)
9631 { /* test: dbempty.rc */
9632 namError("Database '%S' has no attributes", entry->name);
9633 ok = ajFalse;
9634 }
9635
9636 if(!hasformat) /* test: dbempty.rc */
9637 {
9638 namError("Database '%S' has no format definition", entry->name);
9639 ok = ajFalse;
9640 }
9641
9642 if(!hastype) /* test: dbempty.rc */
9643 {
9644 namError("Database '%S' has no type definition", entry->name);
9645 ok = ajFalse;
9646 }
9647
9648 if(!hasmethod) /* test: dbempty.rc */
9649 {
9650 namError("Database '%S' has no access method definition",
9651 entry->name);
9652 ok = ajFalse;
9653 }
9654
9655 ajStrDel(&name);
9656 ajStrTokenDel(&handle);
9657 ajStrTokenDel(&typehandle);
9658 ajStrDel(&token);
9659 ajStrDel(&typetoken);
9660
9661 return ok;
9662 }
9663
9664
9665
9666
9667 /* @funcstatic namValidResource ***********************************************
9668 **
9669 ** Validation of a master table resource entry
9670 **
9671 ** @param [r] entry [const NamPEntry] Internal table entry
9672 ** @return [AjBool] ajTrue on success
9673 **
9674 ** @release 2.7.0
9675 ** @@
9676 ******************************************************************************/
9677
namValidResource(const NamPEntry entry)9678 static AjBool namValidResource(const NamPEntry entry)
9679 {
9680 ajint iattr = 0;
9681 ajint j;
9682 AjPTable rstable;
9683 AjBool ok;
9684
9685 rstable = (AjPTable) entry->data;
9686
9687 if(!rstable)
9688 { /* fatal - should be set for all databases */
9689 namError("Resource '%S' has no list of valid attributes",
9690 entry->name);
9691 return ajFalse;
9692 }
9693
9694 for(j=0; namRsAttrs[j].Name; j++)
9695 if(ajTableFetchC(rstable, namRsAttrs[j].Name))
9696 iattr++;
9697
9698 ok = ajTrue;
9699
9700 if(!iattr)
9701 { /* test: dbempty.rc */
9702 namError("Resource '%S' has no attributes", entry->name);
9703 ok = ajFalse;
9704 }
9705
9706 return ok;
9707 }
9708
9709
9710
9711
9712 /* @funcstatic namValidVariable ***********************************************
9713 **
9714 ** Validation of a master table variable entry
9715 **
9716 ** @param [r] entry [const NamPEntry] Internal table entry
9717 ** @return [AjBool] ajTrue on success
9718 **
9719 ** @release 2.7.0
9720 ** @@
9721 ******************************************************************************/
9722
namValidVariable(const NamPEntry entry)9723 static AjBool namValidVariable(const NamPEntry entry)
9724 {
9725 AjPTable attrtable;
9726
9727 attrtable = (AjPTable) entry->data;
9728
9729 if(attrtable)
9730 { /* strange - should be nothing for variables */
9731 namError("Variable '%S' has a list of attributes",
9732 entry->name);
9733
9734 return ajFalse;
9735 }
9736
9737 return ajTrue;
9738 }
9739
9740
9741
9742
9743 /* @func ajNamSetControl ******************************************************
9744 **
9745 ** Sets special internal variables to reflect their presence.
9746 **
9747 ** Currently these are "namdebug, namvalid"
9748 **
9749 ** @param [r] optionName [const char*] option name
9750 ** @return [AjBool] ajTrue if option was recognised
9751 **
9752 ** @release 2.7.0
9753 ** @@
9754 ******************************************************************************/
9755
ajNamSetControl(const char * optionName)9756 AjBool ajNamSetControl(const char* optionName)
9757 {
9758
9759 if(!ajCharCmpCase(optionName, "namdebug"))
9760 {
9761 namDoDebug = ajTrue;
9762
9763 return ajTrue;
9764 }
9765
9766 if(!ajCharCmpCase(optionName, "namvalid"))
9767 {
9768 namDoValid = ajTrue;
9769
9770 return ajTrue;
9771 }
9772
9773 ajDie("Unknown ajNamSetControl control option '%s'", optionName);
9774
9775 return ajFalse;
9776 }
9777
9778
9779
9780
9781 /* @func ajNamRsAttrValueC ****************************************************
9782 **
9783 ** Return the value for a resource attribute
9784 **
9785 ** @param [r] name [const char *] resource name
9786 ** @param [r] attribute [const char *] resource attribute
9787 ** @param [w] value [AjPStr *] resource value
9788
9789 **
9790 ** @return [AjBool] true if found
9791 **
9792 ** @release 3.0.0
9793 ** @@
9794 ******************************************************************************/
9795
ajNamRsAttrValueC(const char * name,const char * attribute,AjPStr * value)9796 AjBool ajNamRsAttrValueC(const char *name, const char *attribute,
9797 AjPStr *value)
9798 {
9799 ajint j;
9800 const NamPEntry fnew = NULL;
9801 const AjPTable rstable;
9802 const AjPStr rsvalue;
9803
9804 ajDebug("ajNamRsAttrValueC '%s' '%s'\n", name, attribute);
9805
9806 fnew = ajTableFetchC(namResMasterTable, name);
9807
9808 if(!fnew)
9809 return ajFalse;
9810
9811 rstable = (const AjPTable) fnew->data;
9812 j = namRsAttrC(attribute);
9813
9814 if(j < 0)
9815 {
9816 if(namRsAttrFieldC(rstable, attribute))
9817 return ajFalse;
9818
9819 ajFatal("unknown attribute '%s' requested for resource '%s'",
9820 attribute, name);
9821 }
9822
9823 rsvalue = ajTableFetchC(rstable, attribute);
9824
9825 if(ajStrGetLen(rsvalue))
9826 {
9827 ajStrAssignS(value,rsvalue);
9828
9829 return ajTrue;
9830 }
9831
9832 return ajFalse;
9833 }
9834
9835
9836
9837
9838 /* @func ajNamRsAttrValueS ****************************************************
9839 **
9840 ** Return the value for a resource attribute
9841 **
9842 ** @param [r] name [const AjPStr] resource name
9843 ** @param [r] attribute [const AjPStr] resource attribute
9844 ** @param [w] value [AjPStr *] resource value
9845
9846 **
9847 ** @return [AjBool] true if found
9848 **
9849 ** @release 6.4.0
9850 ** @@
9851 ******************************************************************************/
9852
ajNamRsAttrValueS(const AjPStr name,const AjPStr attribute,AjPStr * value)9853 AjBool ajNamRsAttrValueS(const AjPStr name, const AjPStr attribute,
9854 AjPStr *value)
9855 {
9856 ajint j;
9857 const NamPEntry fnew = NULL;
9858 const AjPTable rstable;
9859 const AjPStr rsvalue;
9860
9861 ajDebug("ajNamRsAttrValueS '%S' '%S'\n", name, attribute);
9862
9863 fnew = ajTableFetchS(namResMasterTable, name);
9864
9865 if(!fnew)
9866 ajFatal("unknown resource '%S'",
9867 name);
9868
9869 j = namRsAttrS(attribute);
9870
9871 rstable = (const AjPTable) fnew->data;
9872 rsvalue = ajTableFetchS(rstable, attribute);
9873
9874 ajDebug("resource '%S' found file:%S attribute '%S' j:%d value: '%S'\n",
9875 name, fnew->file, attribute, j, rsvalue);
9876
9877 if(ajStrGetLen(rsvalue))
9878 {
9879 ajStrAssignS(value,rsvalue);
9880
9881 return ajTrue;
9882 }
9883
9884 if(j < 0)
9885 {
9886 if(namRsAttrFieldS(rstable, attribute))
9887 return ajFalse;
9888
9889 ajFatal("unknown attribute '%S' requested for resource '%S'",
9890 attribute, name);
9891 }
9892
9893 return ajFalse;
9894 }
9895
9896
9897
9898
9899 /* @func ajNamRsListValue *****************************************************
9900 **
9901 ** Return the value for a resource attribute of type 'list'
9902 **
9903 ** @param [r] name [const AjPStr] resource name
9904 ** @param [w] value [AjPStr *] resource value
9905 **
9906 ** @return [AjBool] true if found
9907 **
9908 ** @release 3.0.0
9909 ** @@
9910 ******************************************************************************/
9911
ajNamRsListValue(const AjPStr name,AjPStr * value)9912 AjBool ajNamRsListValue(const AjPStr name, AjPStr *value)
9913 {
9914 const NamPEntry fnew = NULL;
9915 const AjPTable rstable = NULL;
9916 const AjPStr rsvalue = NULL;
9917
9918 fnew = ajTableFetchS(namResMasterTable, name);
9919
9920 rstable = (const AjPTable) fnew->data;
9921 rsvalue = ajTableFetchC(rstable, "type");
9922
9923 if(!ajStrMatchCaseC(rsvalue, "list"))
9924 return ajFalse;
9925
9926 rsvalue = ajTableFetchC(rstable, "value");
9927
9928 if(ajStrGetLen(rsvalue))
9929 {
9930 ajStrAssignS(value,rsvalue);
9931
9932 return ajTrue;
9933 }
9934
9935 return ajFalse;
9936 }
9937
9938
9939
9940
9941 #ifdef AJ_COMPILE_DEPRECATED_BOOK
9942 #endif
9943
9944
9945
9946
9947 #ifdef AJ_COMPILE_DEPRECATED
9948 /* @obsolete ajNamGetenv
9949 ** @rename ajNamGetenvS
9950 */
ajNamGetenv(const AjPStr name,AjPStr * value)9951 __deprecated AjBool ajNamGetenv(const AjPStr name,
9952 AjPStr* value)
9953 {
9954 return ajNamGetenvS(name, value);
9955 }
9956
9957
9958
9959
9960 /* @obsolete ajNamGetValue
9961 ** @rename ajNamGetValusS
9962 */
9963
ajNamGetValue(const AjPStr name,AjPStr * value)9964 __deprecated AjBool ajNamGetValue(const AjPStr name, AjPStr* value)
9965 {
9966 return ajNamGetValueC(ajStrGetPtr(name), value);
9967 }
9968
9969
9970
9971
9972 /* @obsolete ajNamRootInstall
9973 ** @remove Use ajNamValueinstalldir
9974 */
ajNamRootInstall(AjPStr * root)9975 __deprecated AjBool ajNamRootInstall(AjPStr* root)
9976 {
9977 ajStrAssignS(root, namFixedInstallStr);
9978
9979 if(!ajStrGetLen(*root))
9980 return ajFalse;
9981
9982 return ajTrue;
9983 }
9984
9985
9986
9987
9988 /* @obsolete ajNamRootPack
9989 ** @remove Use ajNamValuePackage
9990 */
ajNamRootPack(AjPStr * root)9991 __deprecated AjBool ajNamRootPack(AjPStr* root)
9992 {
9993 ajStrAssignS(root, namFixedPackageStr);
9994
9995 if(!ajStrGetLen(*root))
9996 return ajFalse;
9997
9998 return ajTrue;
9999 }
10000
10001
10002
10003
10004 /* @obsolete ajNamRootVersion
10005 ** @remove Use ajNamValueVersion
10006 */
ajNamRootVersion(AjPStr * version)10007 __deprecated AjBool ajNamRootVersion(AjPStr* version)
10008 {
10009 ajStrAssignS(version, namFixedVersionStr);
10010
10011 return ajTrue;
10012 }
10013
10014
10015
10016
10017 /* @obsolete ajNamRoot
10018 ** @remove Use ajNamValueRootdir
10019 */
ajNamRoot(AjPStr * root)10020 __deprecated AjBool ajNamRoot(AjPStr* root)
10021 {
10022 ajStrAssignS(root, namFixedRootStr);
10023
10024 return ajTrue;
10025 }
10026
10027
10028
10029
10030 /* @obsolete ajNamRootBase
10031 ** @remove Use ajNamValueBasedir
10032 */
ajNamRootBase(AjPStr * rootbase)10033 __deprecated AjBool ajNamRootBase(AjPStr* rootbase)
10034 {
10035 ajStrAssignS(rootbase, namFixedBaseStr);
10036
10037 return ajTrue;
10038 }
10039
10040
10041
10042
10043 /* @obsolete ajNamRsAttrValue
10044 ** @rename ajNamRsAttrValueS
10045 */
ajNamRsAttrValue(const AjPStr name,const AjPStr attribute,AjPStr * value)10046 __deprecated AjBool ajNamRsAttrValue(const AjPStr name, const AjPStr attribute,
10047 AjPStr *value)
10048 {
10049 return ajNamRsAttrValueS(name, attribute, value);
10050 }
10051 #endif
10052